"""Escrow endpoints (гарант).""" 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.schemas.escrow import EscrowCreate, EscrowRelease from app.models.escrow import EscrowTransaction from app.models.project import Project router = APIRouter(prefix="/api/escrow", tags=["escrow"]) @router.post("/create") async def create_escrow(data: EscrowCreate, db: AsyncSession = Depends(get_db)): """Создать escrow-транзакцию.""" result = await db.execute(select(Project).where(Project.id == data.project_id)) project = result.scalar_one_or_none() if not project: raise HTTPException(status_code=404, detail="Проект не найден") transaction = EscrowTransaction( project_id=data.project_id, client_id=data.client_id, freelancer_id=data.freelancer_id, amount=data.amount, status="pending", ) db.add(transaction) await db.commit() await db.refresh(transaction) return { "id": str(transaction.id), "status": transaction.status, "amount": float(transaction.amount), "payment_url": f"https://stripe.com/pay/{transaction.id}", # Stripe redirect } @router.post("/release") async def release_escrow(data: EscrowRelease, db: AsyncSession = Depends(get_db)): """Освободить средства фрилансеру.""" result = await db.execute(select(EscrowTransaction).where(EscrowTransaction.id == data.transaction_id)) transaction = result.scalar_one_or_none() if not transaction or transaction.status != "locked": raise HTTPException(status_code=400, detail="Транзакция не может быть разблокирована") # Комиссия платформы 10% commission = transaction.amount * 0.10 freelancer_amount = transaction.amount - commission transaction.status = "released" await db.commit() return { "id": str(transaction.id), "status": "released", "freelancer_payout": float(freelancer_amount), "platform_commission": float(commission), } @router.post("/dispute") async def dispute_escrow(transaction_id: str, db: AsyncSession = Depends(get_db)): """Открыть спор по escrow.""" result = await db.execute(select(EscrowTransaction).where(EscrowTransaction.id == transaction_id)) transaction = result.scalar_one_or_none() if not transaction: raise HTTPException(status_code=404, detail="Транзакция не найдена") transaction.status = "disputed" await db.commit() return {"status": "dispute_opened", "transaction_id": str(transaction.id)}