from __future__ import annotations from app.projects.repositories.approval_repository import ApprovalRepository from app.projects.repositories.editor_repository import ProjectEditorRepository from app.projects.models.collaboration import ApprovalWorkflow, ApprovalRequest, ReviewComment class ApprovalService: def __init__(self, repository: ApprovalRepository, editor_repository: ProjectEditorRepository) -> None: self.repository = repository self.editor_repository = editor_repository async def create_workflow(self, workspace_id: str, project_id: str, name: str) -> ApprovalWorkflow: return await self.repository.create_workflow(workspace_id, project_id, name) async def create_request(self, workspace_id: str, workflow_id: str, project_id: str, user_id: str) -> ApprovalRequest: state = await self.editor_repository.get_state(workspace_id, project_id) return await self.repository.create_request(workspace_id, workflow_id, project_id, user_id, state.revision) async def approve_request(self, request_id: str, actor_user_id: str) -> ApprovalRequest: request = await self.repository.get_request(request_id) if request.created_by == actor_user_id: raise Exception("Separation of duties: Cannot approve your own submission.") # Verify revision hasn't changed state = await self.editor_repository.get_state(request.workspace_id, request.project_id) if state.revision != request.editor_revision: raise Exception("Content has changed since request; approval is stale.") return await self.repository.update_request_status(request_id, "approved") async def reject_request(self, request_id: str, actor_user_id: str) -> ApprovalRequest: return await self.repository.update_request_status(request_id, "rejected") async def add_comment(self, request_id: str, user_id: str, workspace_id: str, content: str) -> ReviewComment: return await self.repository.add_review_comment(request_id, user_id, workspace_id, content) async def list_requests(self, workflow_id: str) -> list[ApprovalRequest]: return await self.repository.list_requests(workflow_id)