Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
Koryakinaisen committed Dec 19, 2024
2 parents b900a24 + c1f3f5b commit b0ad8bc
Show file tree
Hide file tree
Showing 20 changed files with 368 additions and 13 deletions.
19 changes: 19 additions & 0 deletions backend/src/core/entities/category/category.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,25 @@ class CategoryInDB(Category):
description="Unique identifier of the category in the db"
)

class Config:
json_encoders = {
ObjectId: str
}

allow_population_by_field_name = True

class CategoryCreateDB(Category):
id: str = Field(
...,
description="Unique identifier of the order in the db",
alias="_id",
)

types: List[str] = Field(
...,
description="Unique identifier of the order in the db"
)

class CategoryCreated(BaseModel):
message: str = Field(
default="Category created successfully"
Expand Down
Empty file.
58 changes: 58 additions & 0 deletions backend/src/core/entities/db_model/db_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from typing import List, Optional

from pydantic import BaseModel, Field

from src.core.entities.category.category import Category, CategoryInDB, CategoryCreateDB
from src.core.entities.order.order import Order, OrderInDB, OrderCreateDB
from src.core.entities.review.review import Review, ReviewInDB, ReviewCreateDB
from src.core.entities.tool.tool import Tool, ToolInDB, ToolCreateDB
from src.core.entities.type.type import Type, TypeInDB, TypeCreateDB
from src.core.entities.users.client.client import Client, ClientInDB, ClientCreateDB
from src.core.entities.users.worker.worker import Worker, WorkerInDB, WorkerCreateDB


class DBModel(BaseModel):
workers: Optional[List[WorkerInDB]] = Field(
...
)
clients: Optional[List[ClientInDB]] = Field(
...,
)
tools: Optional[List[ToolInDB]] = Field(
...,
)
orders: Optional[List[OrderInDB]] = Field(
...,
)
categories: Optional[List[CategoryInDB]] = Field(
...,
)
types: Optional[List[TypeInDB]] = Field(
...,
)
reviews: Optional[List[ReviewInDB]] = Field(
...,
)

class DBModelCreate(BaseModel):
workers: Optional[List[WorkerCreateDB]] = Field(
...
)
clients: Optional[List[ClientCreateDB]] = Field(
...,
)
tools: Optional[List[ToolCreateDB]] = Field(
...,
)
orders: Optional[List[OrderCreateDB]] = Field(
...,
)
categories: Optional[List[CategoryCreateDB]] = Field(
...,
)
types: Optional[List[TypeCreateDB]] = Field(
...,
)
reviews: Optional[List[ReviewCreateDB]] = Field(
...,
)
15 changes: 15 additions & 0 deletions backend/src/core/entities/order/order.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,22 @@ class Config:

allow_population_by_field_name = True

class OrderCreateDB(Order):
id: str = Field(
...,
description="Unique identifier of the order in the db",
alias="_id",
)

client: str = Field(
...,
description="Unique identifier of the client in the db"
)

tools: List[str] = Field(
...,
description="list of tools"
)

class OrderCreated(BaseModel):
message: str = Field(
Expand Down
26 changes: 26 additions & 0 deletions backend/src/core/entities/review/review.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from datetime import datetime, timezone

from bson import ObjectId
from pydantic import BaseModel, Field
from typing import Optional
from src.core.entities.object_id_str import ObjectIdStr
Expand Down Expand Up @@ -38,6 +40,30 @@ class ReviewInDB(Review):
description="Unique identifier of the review in the db"
)

class Config:
json_encoders = {
ObjectId: str
}

allow_population_by_field_name = True

class ReviewCreateDB(Review):
id: str = Field(
...,
description="Unique identifier of the order in the db",
alias="_id",
)

toolId: str = Field(
...,
description="Reviewed tool id"
)

reviewerId: str = Field(
...,
description="Reviewer tool id"
)

class ReviewCreate(Review):
orderId: str = Field(
...,
Expand Down
14 changes: 14 additions & 0 deletions backend/src/core/entities/tool/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,20 @@ class ToolInDB(Tool):
description="Unique identifier of the tool in the db"
)

class Config:
json_encoders = {
ObjectId: str
}

allow_population_by_field_name = True

class ToolCreateDB(Tool):
id: str = Field(
...,
description="Unique identifier of the tool in the db",
alias="_id",
)

class ToolSummary(BaseModel):
id: Optional[ObjectIdStr] = Field(
...,
Expand Down
12 changes: 12 additions & 0 deletions backend/src/core/entities/type/type.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ class Config:

allow_population_by_field_name = True

class TypeCreateDB(Type):
id: str = Field(
...,
description="Unique identifier of the order in the db",
alias="_id",
)

tools: List[str] = Field(
...,
description="List of tools ids associated with this type"
)

class TypeCreated(BaseModel):
message: str = Field(
default="Type created successfully"
Expand Down
14 changes: 14 additions & 0 deletions backend/src/core/entities/users/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ class ClientInDB(Client):
description="Unique identifier of the client in the db"
)

class Config:
json_encoders = {
ObjectId: str
}

allow_population_by_field_name = True

class ClientCreateDB(Client):
id: str = Field(
...,
description="Unique identifier of the client in the db",
alias="_id",
)

class ClientForWorker(BaseModel):
id: Optional[ObjectIdStr] = Field(
...,
Expand Down
18 changes: 16 additions & 2 deletions backend/src/core/entities/users/worker/worker.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@

from bson import ObjectId
from pydantic import Field, BaseModel, EmailStr
from datetime import datetime
from typing import List, Optional

from src.core.entities.object_id_str import ObjectIdStr
from src.core.entities.order.order import Order
from src.core.entities.users.base_user import BaseUser, BaseUserPrivateSummary


Expand Down Expand Up @@ -43,6 +42,21 @@ class WorkerInDB(Worker):
description="Unique identifier of the client in the db"
)

class Config:
json_encoders = {
ObjectId: str
}

allow_population_by_field_name = True

class WorkerCreateDB(Worker):
id: str = Field(
...,
description="Unique identifier of the client in the db",
alias="_id",
)


class WorkerPrivateSummary(BaseUserPrivateSummary):
jobTitle: str = Field(
...,
Expand Down
Empty file.
13 changes: 13 additions & 0 deletions backend/src/core/repositories/im_ex_repo/iim_ex_repo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from abc import ABC, abstractmethod

from src.core.entities.db_model.db_model import DBModel, DBModelCreate


class IImExRepository(ABC):
@abstractmethod
async def export_data(self) -> DBModel:
pass

@abstractmethod
async def import_data(self, data: DBModelCreate) -> None:
pass
Empty file.
15 changes: 15 additions & 0 deletions backend/src/core/services/im_ex_service/im_ex_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from src.core.entities.db_model.db_model import DBModel, DBModelCreate
from src.core.repositories.im_ex_repo.iim_ex_repo import IImExRepository


class ImExService:
def __init__(self,
im_ex_repository: IImExRepository,
):
self.im_ex_repository = im_ex_repository

async def export(self) -> DBModel:
return await self.im_ex_repository.export_data()

async def import_data(self, data: DBModelCreate) -> None:
return await self.im_ex_repository.import_data(data)
31 changes: 31 additions & 0 deletions backend/src/infrastructure/api/import_export_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from fastapi import APIRouter, Depends
from fastapi.security import OAuth2PasswordBearer

from src.core.entities.db_model.db_model import DBModel, DBModelCreate
from src.core.services.im_ex_service.im_ex_service import ImExService
from src.infrastructure.api.client_controller import oauth2_scheme
from src.infrastructure.api.security.role_required import is_worker
from src.infrastructure.services_instances import get_im_ex_service

im_ex_router = APIRouter()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login")


@im_ex_router.get(path="/export", status_code=201, response_model=DBModel)
async def export(
im_ex_service: ImExService = Depends(get_im_ex_service),
token: str = Depends(oauth2_scheme),
):
is_worker(token)
return await im_ex_service.export()


@im_ex_router.post(path="/import", status_code=201, response_model=None)
async def import_data(
data: DBModelCreate,
im_ex_service: ImExService = Depends(get_im_ex_service),
token: str = Depends(oauth2_scheme),
):
is_worker(token)
return await im_ex_service.import_data(data)
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
from motor.motor_asyncio import AsyncIOMotorDatabase
from pymongo.errors import PyMongoError

from src.core.entities.category.category import Category, CategoryInDB
from src.core.entities.db_model.db_model import DBModel, DBModelCreate
from src.core.entities.order.order import Order, OrderInDB
from src.core.entities.review.review import Review, ReviewInDB
from src.core.entities.tool.tool import Tool, ToolInDB
from src.core.entities.type.type import Type, TypeInDB
from src.core.entities.users.client.client import Client, ClientInDB
from src.core.entities.users.worker.worker import Worker, WorkerInDB
from src.core.exceptions.server_error import DatabaseError
from src.core.repositories.im_ex_repo.iim_ex_repo import IImExRepository
from src.infrastructure.repo_implementations.helpers.id_mapper import str_to_objectId


class MongoImExRepository(IImExRepository):
def __init__(
self,
db: AsyncIOMotorDatabase,
order_collection: str,
tool_collection: str,
client_collection: str,
worker_collection: str,
review_collection: str,
category_collection: str,
type_collection: str):
self.order_collection = db[order_collection]
self.tool_collection = db[tool_collection]
self.client_collection = db[client_collection]
self.worker_collection = db[worker_collection]
self.review_collection = db[review_collection]
self.category_collection = db[category_collection]
self.type_collection = db[type_collection]

async def export_data(self) -> DBModel:
try:
workers = [WorkerInDB(**worker) for worker in (await self.worker_collection.find().to_list(None))]
clients = [ClientInDB(**client) for client in (await self.client_collection.find().to_list(None))]
tools = [ToolInDB(**tool) for tool in (await self.tool_collection.find().to_list(None))]
orders = [OrderInDB(**order) for order in (await self.order_collection.find().to_list(None))]
categories = [CategoryInDB(**category) for category in (await self.category_collection.find().to_list(None))]
types = [TypeInDB(**type) for type in (await self.type_collection.find().to_list(None))]
reviews = [ReviewInDB(**review)for review in (await self.review_collection.find().to_list(None))]

return DBModel(
workers=workers,
clients=clients,
tools=tools,
orders=orders,
categories=categories,
types=types,
reviews=reviews
)
except PyMongoError:
raise DatabaseError()

async def import_data(self, data: DBModelCreate) -> None:
try:
if data.workers:
await self.worker_collection.delete_many({})
await self.worker_collection.insert_many([worker.model_dump() for worker in data.workers])

if data.clients:
await self.client_collection.delete_many({})
await self.client_collection.insert_many([client.model_dump() for client in data.clients])

if data.tools:
await self.tool_collection.delete_many({})
await self.tool_collection.insert_many([tool.model_dump() for tool in data.tools])

if data.orders:
await self.order_collection.delete_many({})
await self.order_collection.insert_many([order.model_dump() for order in data.orders])

if data.categories:
await self.category_collection.delete_many({})
await self.category_collection.insert_many([category.model_dump() for category in data.categories])

if data.types:
await self.type_collection.delete_many({})
await self.type_collection.insert_many([typee.model_dump() for typee in data.types])

if data.reviews:
await self.review_collection.delete_many({})
await self.review_collection.insert_many([review.model_dump() for review in data.reviews])

except PyMongoError:
raise DatabaseError()

Loading

0 comments on commit b0ad8bc

Please sign in to comment.