From db93b4afafb007f7c8d76d91a75905f66dbb32bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B0=D1=81=D1=82=D0=B0=D1=81=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=A8=D0=B8=D0=BD=D1=8F=D0=B5=D0=B2=D0=B0?= Date: Wed, 18 Dec 2024 23:21:45 +0300 Subject: [PATCH 1/4] repo added --- .../src/core/entities/db_model/__init__.py | 0 .../src/core/entities/db_model/db_model.py | 35 ++++++++ .../core/repositories/im_ex_repo/__init__.py | 0 .../repositories/im_ex_repo/iim_ex_repo.py | 13 +++ .../core/services/im_ex_service/__init__.py | 0 .../services/im_ex_service/im_ex_service.py | 15 ++++ .../api/import_export_controller.py | 28 +++++++ .../im_ex_repo/__init__.py | 0 .../im_ex_repo/im_ex_repo.py | 82 +++++++++++++++++++ .../repo_implementations/repo_instances.py | 18 +++- .../src/infrastructure/services_instances.py | 35 ++++++-- 11 files changed, 216 insertions(+), 10 deletions(-) create mode 100644 backend/src/core/entities/db_model/__init__.py create mode 100644 backend/src/core/entities/db_model/db_model.py create mode 100644 backend/src/core/repositories/im_ex_repo/__init__.py create mode 100644 backend/src/core/repositories/im_ex_repo/iim_ex_repo.py create mode 100644 backend/src/core/services/im_ex_service/__init__.py create mode 100644 backend/src/core/services/im_ex_service/im_ex_service.py create mode 100644 backend/src/infrastructure/api/import_export_controller.py create mode 100644 backend/src/infrastructure/repo_implementations/im_ex_repo/__init__.py create mode 100644 backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py diff --git a/backend/src/core/entities/db_model/__init__.py b/backend/src/core/entities/db_model/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/src/core/entities/db_model/db_model.py b/backend/src/core/entities/db_model/db_model.py new file mode 100644 index 0000000..e3181f6 --- /dev/null +++ b/backend/src/core/entities/db_model/db_model.py @@ -0,0 +1,35 @@ +from typing import List, Optional + +from pydantic import BaseModel, Field + +from src.core.entities.category.category import Category +from src.core.entities.order.order import Order +from src.core.entities.review.review import Review +from src.core.entities.tool.tool import Tool +from src.core.entities.type.type import Type +from src.core.entities.users.client.client import Client +from src.core.entities.users.worker.worker import Worker + + +class DBModel(BaseModel): + workers: Optional[List[Worker]] = Field( + ... + ) + clients: Optional[List[Client]] = Field( + ..., + ) + tools: Optional[List[Tool]] = Field( + ..., + ) + orders: Optional[List[Order]] = Field( + ..., + ) + categories: Optional[List[Category]] = Field( + ..., + ) + types: Optional[List[Type]] = Field( + ..., + ) + reviews: Optional[List[Review]] = Field( + ..., + ) \ No newline at end of file diff --git a/backend/src/core/repositories/im_ex_repo/__init__.py b/backend/src/core/repositories/im_ex_repo/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/src/core/repositories/im_ex_repo/iim_ex_repo.py b/backend/src/core/repositories/im_ex_repo/iim_ex_repo.py new file mode 100644 index 0000000..b87cdf5 --- /dev/null +++ b/backend/src/core/repositories/im_ex_repo/iim_ex_repo.py @@ -0,0 +1,13 @@ +from abc import ABC, abstractmethod + +from src.core.entities.db_model.db_model import DBModel + + +class IImExRepository(ABC): + @abstractmethod + async def export_data(self) -> DBModel: + pass + + @abstractmethod + async def import_data(self, data: DBModel) -> None: + pass \ No newline at end of file diff --git a/backend/src/core/services/im_ex_service/__init__.py b/backend/src/core/services/im_ex_service/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/src/core/services/im_ex_service/im_ex_service.py b/backend/src/core/services/im_ex_service/im_ex_service.py new file mode 100644 index 0000000..163fd8f --- /dev/null +++ b/backend/src/core/services/im_ex_service/im_ex_service.py @@ -0,0 +1,15 @@ +from src.core.entities.db_model.db_model import DBModel +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: DBModel) -> None: + return await self.im_ex_repository.import_data(data) \ No newline at end of file diff --git a/backend/src/infrastructure/api/import_export_controller.py b/backend/src/infrastructure/api/import_export_controller.py new file mode 100644 index 0000000..86b8467 --- /dev/null +++ b/backend/src/infrastructure/api/import_export_controller.py @@ -0,0 +1,28 @@ +from fastapi import APIRouter, Depends +from fastapi.security import OAuth2PasswordBearer + +from src.core.entities.db_model.db_model import DBModel +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), + +): + return await im_ex_service.export() + +@im_ex_router.post(path="/import", status_code=201, response_model=DBModel) +async def import_data( + data: DBModel, + im_ex_service: ImExService = Depends(get_im_ex_service), +): + + return await im_ex_service.import_data(data) \ No newline at end of file diff --git a/backend/src/infrastructure/repo_implementations/im_ex_repo/__init__.py b/backend/src/infrastructure/repo_implementations/im_ex_repo/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py b/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py new file mode 100644 index 0000000..deb715e --- /dev/null +++ b/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py @@ -0,0 +1,82 @@ +from motor.motor_asyncio import AsyncIOMotorDatabase +from pymongo.errors import PyMongoError + +from src.core.entities.db_model.db_model import DBModel +from src.core.exceptions.server_error import DatabaseError +from src.core.repositories.im_ex_repo.iim_ex_repo import IImExRepository + + +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 = await self.worker_collection.find().to_list(None) + clients = await self.client_collection.find().to_list(None) + tools = await self.tool_collection.find().to_list(None) + orders = await self.order_collection.find().to_list(None) + categories = await self.category_collection.find().to_list(None) + types = await self.type_collection.find().to_list(None) + reviews = 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: DBModel) -> None: + try: + if data.workers: + await self.worker_collection.delete_many({}) + await self.worker_collection.insert_many(data.workers) + + if data.clients: + await self.client_collection.delete_many({}) + await self.client_collection.insert_many(data.clients) + + if data.tools: + await self.tool_collection.delete_many({}) + await self.tool_collection.insert_many(data.tools) + + if data.orders: + await self.order_collection.delete_many({}) + await self.order_collection.insert_many(data.orders) + + if data.categories: + await self.category_collection.delete_many({}) + await self.category_collection.insert_many(data.categories) + + if data.types: + await self.type_collection.delete_many({}) + await self.type_collection.insert_many(data.types) + + if data.reviews: + await self.review_collection.delete_many({}) + await self.review_collection.insert_many(data.reviews) + + except PyMongoError: + raise DatabaseError() + diff --git a/backend/src/infrastructure/repo_implementations/repo_instances.py b/backend/src/infrastructure/repo_implementations/repo_instances.py index 7da37b6..ed672cf 100644 --- a/backend/src/infrastructure/repo_implementations/repo_instances.py +++ b/backend/src/infrastructure/repo_implementations/repo_instances.py @@ -1,4 +1,6 @@ from fastapi.params import Depends + +from src.infrastructure.repo_implementations.im_ex_repo.im_ex_repo import MongoImExRepository from src.infrastructure.repo_implementations.order_repos.mongo_order_repository import MongoOrderRepository from src.configs.config import config from src.infrastructure.db.mongo import MongoDB, get_db @@ -39,5 +41,19 @@ def get_mongo_order_repo(db: AsyncIOMotorDatabase = Depends(get_db)): return MongoOrderRepository(db, collections_config.order_collection, collections_config.tool_collection, collections_config.client_collection) + def get_mongo_review_repo(db: AsyncIOMotorDatabase = Depends(get_db)): - return MongoReviewRepository(db, collections_config.review_collection) \ No newline at end of file + return MongoReviewRepository(db, collections_config.review_collection) + + +def get_mongo_im_ex_repo(db: AsyncIOMotorDatabase = Depends(get_db)): + return MongoImExRepository( + db, + collections_config.order_collection, + collections_config.tool_collection, + collections_config.client_collection, + collections_config.worker_collection, + collections_config.review_collection, + collections_config.category_collection, + collections_config.type_collection, + ) diff --git a/backend/src/infrastructure/services_instances.py b/backend/src/infrastructure/services_instances.py index 3b5ddd5..ea36dce 100644 --- a/backend/src/infrastructure/services_instances.py +++ b/backend/src/infrastructure/services_instances.py @@ -1,6 +1,9 @@ from fastapi import Depends + +from src.core.services.im_ex_service.im_ex_service import ImExService from src.core.services.order_service.order_service import OrderService from src.core.services.review_service.review_service import ReviewService +from src.infrastructure.repo_implementations.im_ex_repo.im_ex_repo import MongoImExRepository from src.infrastructure.repo_implementations.order_repos.mongo_order_repository import MongoOrderRepository from src.configs.config import config from src.core.services.authentication.jwt.jwt_auth import JWTAuthentication @@ -10,7 +13,7 @@ from src.core.services.worker_service.worker_service import WorkerService from src.infrastructure.repo_implementations.repo_instances import get_mongo_client_repo, get_mongo_order_repo, \ get_mongo_worker_repo, \ - get_mongo_tool_repo, get_mongo_category_repo, get_mongo_type_repo, get_mongo_review_repo + get_mongo_tool_repo, get_mongo_category_repo, get_mongo_type_repo, get_mongo_review_repo, get_mongo_im_ex_repo from src.infrastructure.repo_implementations.review_repos.mongo_review_repository import MongoReviewRepository from src.infrastructure.repo_implementations.tool_repos.mongo_category_repository import MongoCategoryRepository from src.infrastructure.repo_implementations.tool_repos.mongo_tool_repository import MongoToolRepository @@ -31,6 +34,7 @@ def get_jwt_authenticator( config.jwt ) + def get_registration_service( mongo_client_repo: MongoClientRepository = Depends(get_mongo_client_repo), mongo_worker_repo: MongoWorkerRepository = Depends(get_mongo_worker_repo) @@ -40,6 +44,7 @@ def get_registration_service( mongo_worker_repo, ) + def get_tool_service( mongo_tool_repo: MongoToolRepository = Depends(get_mongo_tool_repo), mongo_category_repo: MongoCategoryRepository = Depends(get_mongo_category_repo), @@ -53,6 +58,7 @@ def get_tool_service( config.urls ) + def get_client_service( mongo_client_repo: MongoClientRepository = Depends(get_mongo_client_repo) ) -> ClientService: @@ -62,6 +68,7 @@ def get_client_service( config.urls ) + def get_worker_service( mongo_worker_repo: MongoWorkerRepository = Depends(get_mongo_worker_repo) ) -> WorkerService: @@ -71,11 +78,12 @@ def get_worker_service( config.urls ) + def get_order_service( - mongo_order_repo: MongoOrderRepository = Depends(get_mongo_order_repo), - mongo_tool_repo: MongoToolRepository = Depends(get_mongo_tool_repo), - mongo_worker_repo: MongoWorkerRepository = Depends(get_mongo_worker_repo), - mongo_client_repo: MongoClientRepository = Depends(get_mongo_client_repo) + mongo_order_repo: MongoOrderRepository = Depends(get_mongo_order_repo), + mongo_tool_repo: MongoToolRepository = Depends(get_mongo_tool_repo), + mongo_worker_repo: MongoWorkerRepository = Depends(get_mongo_worker_repo), + mongo_client_repo: MongoClientRepository = Depends(get_mongo_client_repo) ) -> OrderService: return OrderService( @@ -85,11 +93,12 @@ def get_order_service( mongo_client_repo ) + def get_review_service( - mongo_review_repo: MongoReviewRepository = Depends(get_mongo_review_repo), - mongo_tool_repo: MongoToolRepository = Depends(get_mongo_tool_repo), - mongo_client_repo: MongoClientRepository = Depends(get_mongo_client_repo), - mongo_order_repo: MongoOrderRepository = Depends(get_mongo_order_repo) + mongo_review_repo: MongoReviewRepository = Depends(get_mongo_review_repo), + mongo_tool_repo: MongoToolRepository = Depends(get_mongo_tool_repo), + mongo_client_repo: MongoClientRepository = Depends(get_mongo_client_repo), + mongo_order_repo: MongoOrderRepository = Depends(get_mongo_order_repo) ) -> ReviewService: return ReviewService( mongo_review_repo, @@ -97,3 +106,11 @@ def get_review_service( mongo_client_repo, mongo_order_repo ) + + +def get_im_ex_service( + mongo_im_ex_repo: MongoImExRepository = Depends(get_mongo_im_ex_repo) +) -> ImExService: + return ImExService( + mongo_im_ex_repo, + ) From d224ed793f998a9d6e58d163ade4b765365208ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B0=D1=81=D1=82=D0=B0=D1=81=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=A8=D0=B8=D0=BD=D1=8F=D0=B5=D0=B2=D0=B0?= Date: Thu, 19 Dec 2024 00:38:19 +0300 Subject: [PATCH 2/4] add route --- .../api/import_export_controller.py | 6 +-- .../im_ex_repo/im_ex_repo.py | 40 +++++++++++-------- backend/src/main.py | 1 + 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/backend/src/infrastructure/api/import_export_controller.py b/backend/src/infrastructure/api/import_export_controller.py index 86b8467..0fb273f 100644 --- a/backend/src/infrastructure/api/import_export_controller.py +++ b/backend/src/infrastructure/api/import_export_controller.py @@ -19,10 +19,10 @@ async def export( ): return await im_ex_service.export() -@im_ex_router.post(path="/import", status_code=201, response_model=DBModel) + +@im_ex_router.post(path="/import", status_code=201, response_model=None) async def import_data( data: DBModel, im_ex_service: ImExService = Depends(get_im_ex_service), ): - - return await im_ex_service.import_data(data) \ No newline at end of file + return await im_ex_service.import_data(data) diff --git a/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py b/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py index deb715e..eb4cd1e 100644 --- a/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py +++ b/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py @@ -1,7 +1,14 @@ from motor.motor_asyncio import AsyncIOMotorDatabase from pymongo.errors import PyMongoError +from src.core.entities.category.category import Category from src.core.entities.db_model.db_model import DBModel +from src.core.entities.order.order import Order +from src.core.entities.review.review import Review +from src.core.entities.tool.tool import Tool +from src.core.entities.type.type import Type +from src.core.entities.users.client.client import Client +from src.core.entities.users.worker.worker import Worker from src.core.exceptions.server_error import DatabaseError from src.core.repositories.im_ex_repo.iim_ex_repo import IImExRepository @@ -27,23 +34,25 @@ def __init__( async def export_data(self) -> DBModel: try: - workers = await self.worker_collection.find().to_list(None) - clients = await self.client_collection.find().to_list(None) - tools = await self.tool_collection.find().to_list(None) - orders = await self.order_collection.find().to_list(None) - categories = await self.category_collection.find().to_list(None) - types = await self.type_collection.find().to_list(None) - reviews = await self.review_collection.find().to_list(None) + # workers = [Worker(**worker) for worker in (await self.worker_collection.find().to_list(None))] + # clients = [Client(**client) for client in (await self.client_collection.find().to_list(None))] + # tools = [Tool(**tool) for tool in (await self.tool_collection.find().to_list(None))] + # orders = [Order(**order) for order in (await self.order_collection.find().to_list(None))] + # categories = [Category(**category) for category in (await self.category_collection.find().to_list(None))] + # types = [Type(**type) for type in (await self.type_collection.find().to_list(None))] + # reviews = [Review(**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 + result = DBModel( + # workers=workers, + # clients=clients, + # tools=tools, + # orders=orders, + # categories=categories, + # types=types, + # reviews=reviews ) + print(result) + return result except PyMongoError: raise DatabaseError() @@ -79,4 +88,3 @@ async def import_data(self, data: DBModel) -> None: except PyMongoError: raise DatabaseError() - diff --git a/backend/src/main.py b/backend/src/main.py index 0b45513..6e5f77d 100644 --- a/backend/src/main.py +++ b/backend/src/main.py @@ -39,6 +39,7 @@ async def lifespan(app: FastAPI): app.include_router(client_router, prefix="/api/clients", tags=["client"]) app.include_router(order_router, prefix="/api/orders", tags=["order"]) app.include_router(review_router, prefix="/api/reviews", tags=["reviews"]) +app.include_router(review_router, prefix="/api/data", tags=["reviews"]) app.add_middleware( From 2df80ef2d8487544eecf049ff85e07b6fec46753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B0=D1=81=D1=82=D0=B0=D1=81=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=A8=D0=B8=D0=BD=D1=8F=D0=B5=D0=B2=D0=B0?= Date: Thu, 19 Dec 2024 01:14:37 +0300 Subject: [PATCH 3/4] fix main --- .../api/import_export_controller.py | 3 +- .../im_ex_repo/im_ex_repo.py | 29 +++++++++---------- backend/src/main.py | 3 +- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/backend/src/infrastructure/api/import_export_controller.py b/backend/src/infrastructure/api/import_export_controller.py index 0fb273f..a4767dd 100644 --- a/backend/src/infrastructure/api/import_export_controller.py +++ b/backend/src/infrastructure/api/import_export_controller.py @@ -15,8 +15,9 @@ @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() diff --git a/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py b/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py index eb4cd1e..91352b2 100644 --- a/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py +++ b/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py @@ -34,24 +34,23 @@ def __init__( async def export_data(self) -> DBModel: try: - # workers = [Worker(**worker) for worker in (await self.worker_collection.find().to_list(None))] - # clients = [Client(**client) for client in (await self.client_collection.find().to_list(None))] - # tools = [Tool(**tool) for tool in (await self.tool_collection.find().to_list(None))] - # orders = [Order(**order) for order in (await self.order_collection.find().to_list(None))] - # categories = [Category(**category) for category in (await self.category_collection.find().to_list(None))] - # types = [Type(**type) for type in (await self.type_collection.find().to_list(None))] - # reviews = [Review(**review)for review in (await self.review_collection.find().to_list(None))] + workers = [Worker(**worker) for worker in (await self.worker_collection.find().to_list(None))] + clients = [Client(**client) for client in (await self.client_collection.find().to_list(None))] + tools = [Tool(**tool) for tool in (await self.tool_collection.find().to_list(None))] + orders = [Order(**order) for order in (await self.order_collection.find().to_list(None))] + categories = [Category(**category) for category in (await self.category_collection.find().to_list(None))] + types = [Type(**type) for type in (await self.type_collection.find().to_list(None))] + reviews = [Review(**review)for review in (await self.review_collection.find().to_list(None))] result = DBModel( - # workers=workers, - # clients=clients, - # tools=tools, - # orders=orders, - # categories=categories, - # types=types, - # reviews=reviews + workers=workers, + clients=clients, + tools=tools, + orders=orders, + categories=categories, + types=types, + reviews=reviews ) - print(result) return result except PyMongoError: raise DatabaseError() diff --git a/backend/src/main.py b/backend/src/main.py index 6e5f77d..946e3c0 100644 --- a/backend/src/main.py +++ b/backend/src/main.py @@ -7,6 +7,7 @@ from src.core.exceptions.custom_error import CustomError from src.infrastructure.api.auth_controller import auth_router from src.infrastructure.api.client_controller import client_router +from src.infrastructure.api.import_export_controller import im_ex_router from src.infrastructure.api.order_controller import order_router from src.infrastructure.api.review_controller import review_router from src.infrastructure.api.tool_controller import tool_router, category_router, type_router @@ -39,7 +40,7 @@ async def lifespan(app: FastAPI): app.include_router(client_router, prefix="/api/clients", tags=["client"]) app.include_router(order_router, prefix="/api/orders", tags=["order"]) app.include_router(review_router, prefix="/api/reviews", tags=["reviews"]) -app.include_router(review_router, prefix="/api/data", tags=["reviews"]) +app.include_router(im_ex_router, prefix="/api/data", tags=["im_ex"]) app.add_middleware( From 7f2bafece699a01c32d2e0537f28f6d793f73489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B0=D1=81=D1=82=D0=B0=D1=81=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=A8=D0=B8=D0=BD=D1=8F=D0=B5=D0=B2=D0=B0?= Date: Thu, 19 Dec 2024 02:26:53 +0300 Subject: [PATCH 4/4] done --- .../src/core/entities/category/category.py | 19 +++++++ .../src/core/entities/db_model/db_model.py | 51 ++++++++++++++----- backend/src/core/entities/order/order.py | 15 ++++++ backend/src/core/entities/review/review.py | 26 ++++++++++ backend/src/core/entities/tool/tool.py | 14 +++++ backend/src/core/entities/type/type.py | 12 +++++ .../src/core/entities/users/client/client.py | 14 +++++ .../src/core/entities/users/worker/worker.py | 18 ++++++- .../repositories/im_ex_repo/iim_ex_repo.py | 4 +- .../services/im_ex_service/im_ex_service.py | 4 +- .../api/import_export_controller.py | 6 ++- .../im_ex_repo/im_ex_repo.py | 51 ++++++++++--------- .../order_repos/mongo_order_repository.py | 1 - 13 files changed, 187 insertions(+), 48 deletions(-) diff --git a/backend/src/core/entities/category/category.py b/backend/src/core/entities/category/category.py index b902710..882991a 100644 --- a/backend/src/core/entities/category/category.py +++ b/backend/src/core/entities/category/category.py @@ -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" diff --git a/backend/src/core/entities/db_model/db_model.py b/backend/src/core/entities/db_model/db_model.py index e3181f6..c0a4ce3 100644 --- a/backend/src/core/entities/db_model/db_model.py +++ b/backend/src/core/entities/db_model/db_model.py @@ -2,34 +2,57 @@ from pydantic import BaseModel, Field -from src.core.entities.category.category import Category -from src.core.entities.order.order import Order -from src.core.entities.review.review import Review -from src.core.entities.tool.tool import Tool -from src.core.entities.type.type import Type -from src.core.entities.users.client.client import Client -from src.core.entities.users.worker.worker import Worker +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[Worker]] = Field( + workers: Optional[List[WorkerInDB]] = Field( ... ) - clients: Optional[List[Client]] = Field( + clients: Optional[List[ClientInDB]] = Field( ..., ) - tools: Optional[List[Tool]] = Field( + tools: Optional[List[ToolInDB]] = Field( ..., ) - orders: Optional[List[Order]] = Field( + orders: Optional[List[OrderInDB]] = Field( ..., ) - categories: Optional[List[Category]] = Field( + categories: Optional[List[CategoryInDB]] = Field( ..., ) - types: Optional[List[Type]] = Field( + types: Optional[List[TypeInDB]] = Field( ..., ) - reviews: Optional[List[Review]] = 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( ..., ) \ No newline at end of file diff --git a/backend/src/core/entities/order/order.py b/backend/src/core/entities/order/order.py index c318a0c..0149665 100644 --- a/backend/src/core/entities/order/order.py +++ b/backend/src/core/entities/order/order.py @@ -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( diff --git a/backend/src/core/entities/review/review.py b/backend/src/core/entities/review/review.py index ba5681e..3b6d1b7 100644 --- a/backend/src/core/entities/review/review.py +++ b/backend/src/core/entities/review/review.py @@ -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 @@ -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( ..., diff --git a/backend/src/core/entities/tool/tool.py b/backend/src/core/entities/tool/tool.py index a185115..f8426af 100644 --- a/backend/src/core/entities/tool/tool.py +++ b/backend/src/core/entities/tool/tool.py @@ -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( ..., diff --git a/backend/src/core/entities/type/type.py b/backend/src/core/entities/type/type.py index 64fb9de..9f09070 100644 --- a/backend/src/core/entities/type/type.py +++ b/backend/src/core/entities/type/type.py @@ -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" diff --git a/backend/src/core/entities/users/client/client.py b/backend/src/core/entities/users/client/client.py index c5fa129..f67d6ea 100644 --- a/backend/src/core/entities/users/client/client.py +++ b/backend/src/core/entities/users/client/client.py @@ -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( ..., diff --git a/backend/src/core/entities/users/worker/worker.py b/backend/src/core/entities/users/worker/worker.py index 653dce2..9090188 100644 --- a/backend/src/core/entities/users/worker/worker.py +++ b/backend/src/core/entities/users/worker/worker.py @@ -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 @@ -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( ..., diff --git a/backend/src/core/repositories/im_ex_repo/iim_ex_repo.py b/backend/src/core/repositories/im_ex_repo/iim_ex_repo.py index b87cdf5..0cf3944 100644 --- a/backend/src/core/repositories/im_ex_repo/iim_ex_repo.py +++ b/backend/src/core/repositories/im_ex_repo/iim_ex_repo.py @@ -1,6 +1,6 @@ from abc import ABC, abstractmethod -from src.core.entities.db_model.db_model import DBModel +from src.core.entities.db_model.db_model import DBModel, DBModelCreate class IImExRepository(ABC): @@ -9,5 +9,5 @@ async def export_data(self) -> DBModel: pass @abstractmethod - async def import_data(self, data: DBModel) -> None: + async def import_data(self, data: DBModelCreate) -> None: pass \ No newline at end of file diff --git a/backend/src/core/services/im_ex_service/im_ex_service.py b/backend/src/core/services/im_ex_service/im_ex_service.py index 163fd8f..33a51d5 100644 --- a/backend/src/core/services/im_ex_service/im_ex_service.py +++ b/backend/src/core/services/im_ex_service/im_ex_service.py @@ -1,4 +1,4 @@ -from src.core.entities.db_model.db_model import DBModel +from src.core.entities.db_model.db_model import DBModel, DBModelCreate from src.core.repositories.im_ex_repo.iim_ex_repo import IImExRepository @@ -11,5 +11,5 @@ def __init__(self, async def export(self) -> DBModel: return await self.im_ex_repository.export_data() - async def import_data(self, data: DBModel) -> None: + async def import_data(self, data: DBModelCreate) -> None: return await self.im_ex_repository.import_data(data) \ No newline at end of file diff --git a/backend/src/infrastructure/api/import_export_controller.py b/backend/src/infrastructure/api/import_export_controller.py index a4767dd..8af63c5 100644 --- a/backend/src/infrastructure/api/import_export_controller.py +++ b/backend/src/infrastructure/api/import_export_controller.py @@ -1,7 +1,7 @@ from fastapi import APIRouter, Depends from fastapi.security import OAuth2PasswordBearer -from src.core.entities.db_model.db_model import DBModel +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 @@ -23,7 +23,9 @@ async def export( @im_ex_router.post(path="/import", status_code=201, response_model=None) async def import_data( - data: DBModel, + 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) diff --git a/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py b/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py index 91352b2..c6c086e 100644 --- a/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py +++ b/backend/src/infrastructure/repo_implementations/im_ex_repo/im_ex_repo.py @@ -1,16 +1,17 @@ from motor.motor_asyncio import AsyncIOMotorDatabase from pymongo.errors import PyMongoError -from src.core.entities.category.category import Category -from src.core.entities.db_model.db_model import DBModel -from src.core.entities.order.order import Order -from src.core.entities.review.review import Review -from src.core.entities.tool.tool import Tool -from src.core.entities.type.type import Type -from src.core.entities.users.client.client import Client -from src.core.entities.users.worker.worker import Worker +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): @@ -34,15 +35,15 @@ def __init__( async def export_data(self) -> DBModel: try: - workers = [Worker(**worker) for worker in (await self.worker_collection.find().to_list(None))] - clients = [Client(**client) for client in (await self.client_collection.find().to_list(None))] - tools = [Tool(**tool) for tool in (await self.tool_collection.find().to_list(None))] - orders = [Order(**order) for order in (await self.order_collection.find().to_list(None))] - categories = [Category(**category) for category in (await self.category_collection.find().to_list(None))] - types = [Type(**type) for type in (await self.type_collection.find().to_list(None))] - reviews = [Review(**review)for review in (await self.review_collection.find().to_list(None))] + 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))] - result = DBModel( + return DBModel( workers=workers, clients=clients, tools=tools, @@ -51,39 +52,39 @@ async def export_data(self) -> DBModel: types=types, reviews=reviews ) - return result except PyMongoError: raise DatabaseError() - async def import_data(self, data: DBModel) -> None: + async def import_data(self, data: DBModelCreate) -> None: try: if data.workers: await self.worker_collection.delete_many({}) - await self.worker_collection.insert_many(data.workers) + 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(data.clients) + 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(data.tools) + 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(data.orders) + 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(data.categories) + 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(data.types) + 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(data.reviews) + await self.review_collection.insert_many([review.model_dump() for review in data.reviews]) except PyMongoError: raise DatabaseError() + diff --git a/backend/src/infrastructure/repo_implementations/order_repos/mongo_order_repository.py b/backend/src/infrastructure/repo_implementations/order_repos/mongo_order_repository.py index 61185ab..053a4be 100644 --- a/backend/src/infrastructure/repo_implementations/order_repos/mongo_order_repository.py +++ b/backend/src/infrastructure/repo_implementations/order_repos/mongo_order_repository.py @@ -65,7 +65,6 @@ async def get_order_by_id(self, order_id: str) -> Optional[OrderSummary]: ).to_list(length=None) tools_model = [ToolSummary(**tool) for tool in tools] order["tools"] = tools_model - print(order) return OrderSummary(**order) except PyMongoError: raise DatabaseError()