"""Endpoints для Milestone-платежей (Upwork-style).""" from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from app.core.database import get_db from app.core.security import get_current_user from app.models.project import Project from app.models.milestone import Milestone from app.models.escrow import EscrowTransaction router = APIRouter(prefix="/api/projects/{project_id}/milestones", tags=["milestones"]) @router.post("", response_model=dict) async def create_milestone( project_id: str, data: dict, db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user) ): """Создать milestone для проекта.""" result = await db.execute(select(Project).where(Project.id == project_id)) project = result.scalar_one_or_none() if not project or project.client_id != user["id"]: raise HTTPException(status_code=403, detail="Только владелец проекта может создавать milestones") milestone = Milestone( project_id=project_id, title=data.get("title", ""), description=data.get("description"), amount=float(data.get("amount")), due_date=None, # ISO format string ) db.add(milestone) await db.commit() await db.refresh(milestone) return {"id": str(milestone.id), "status": milestone.status} @router.patch("/{milestone_id}/submit") async def submit_milestone(milestone_id: str, db: AsyncSession = Depends(get_db)): """Фрилансер завершает milestone.""" result = await db.execute(select(Milestone).where(Milestone.id == milestone_id)) milestone = result.scalar_one_or_none() if not milestone or milestone.status != "funded": raise HTTPException(status_code=400, detail="Milestone не может быть завершён") milestone.status = "submitted" await db.commit() return {"status": "submitted", "milestone_id": str(milestone.id)} @router.patch("/{milestone_id}/approve") async def approve_milestone(milestone_id: str, user: dict = Depends(get_current_user), db: AsyncSession = Depends(get_db)): """Клиент одобряет milestone.""" result = await db.execute(select(Milestone).where(Milestone.id == milestone_id)) milestone = result.scalar_one_or_none() if not milestone or milestone.status != "submitted": raise HTTPException(status_code=400, detail="Milestone не может быть одобрен") milestone.status = "approved" await db.commit() return {"status": "approved", "milestone_id": str(milestone.id)}