from typing import Dict, List, Optional from backend.services.project.models import ProjectDoc from backend.services.product.product_store import ProductStore from backend.infra.exception.exceptions import DoesNotExistError from beanie.operators import In class ProjectStore: def __init__(self) -> None: self.product_store = ProductStore() async def fetch_project(self, project_id: str) -> Optional[Dict[str, any]]: project = await self.__fetch_project(project_id) return project.model_dump() async def __fetch_project(self, project_id: str) -> Optional[ProjectDoc]: project = await ProjectDoc.get(project_id) if not project: raise DoesNotExistError(f"Project <{project_id}> not exist.") return project async def fetch_projects_by_requester( self, requester_id: str ) -> List[Dict[str, any]]: projects = await ProjectDoc.find( ProjectDoc.requester_id == requester_id ).to_list() return [project.model_dump() for project in projects] async def fetch_projects_by_proposer( self, proposer_id: str ) -> List[Dict[str, any]]: projects = await ProjectDoc.find( ProjectDoc.proposer_id == proposer_id ).to_list() return [project.model_dump() for project in projects] async def fetch_projects_by_requests( self, request_ids: List[str] ) -> List[Dict[str, any]]: projects = await ProjectDoc.find( In(ProjectDoc.request_id, request_ids) ).to_list() return [project.model_dump() for project in projects] async def fetch_product_by_project( self, project_id: str ) -> Optional[Dict[str, any]]: project = await self.__fetch_project(project_id) product = await self.product_store.fetch_product(project.product_id) return product async def add_user_as_provider(self, project_id: str, user_id: str) -> bool: project = await self.__fetch_project(project_id) project.providers.append(user_id) await project.save() return True async def add_user_as_issuer(self, project_id: str, user_id: str) -> bool: project = await self.__fetch_project(project_id) project.issuers.append(user_id) await project.save() return True