Files
freelancer-match/backend/app/api/milestones.py
T

72 lines
2.7 KiB
Python
Raw Normal View History

"""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)}