feat(review): add multi-owner contracts and receipts
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
This commit is contained in:
parent
52aefe39e4
commit
598f6418e7
13 changed files with 1401 additions and 9 deletions
|
|
@ -6,7 +6,6 @@ from pathlib import Path
|
|||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request, Response, status
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
|
|
@ -14,9 +13,12 @@ from api.database import get_session
|
|||
from api.events import EventEnvelope, publish_event
|
||||
from api.models.decision import Decision, DecisionStatus, DecisionType
|
||||
from api.models.progress_event import ProgressEvent
|
||||
from api.models.review_contract import ReviewContract
|
||||
from api.schemas.decision import DecisionCreate, DecisionRead, DecisionResolve, DecisionUpdate
|
||||
from api.services.legacy_compat import meter_legacy_body_from_model, meter_legacy_query_param
|
||||
from api.services.review_contracts import aggregate
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
router = APIRouter(prefix="/decisions", tags=["decisions"])
|
||||
|
||||
_FINANCIAL_LEGAL_KEYWORDS = (
|
||||
|
|
@ -154,6 +156,25 @@ async def resolve_decision_action(
|
|||
if decision.status == DecisionStatus.resolved:
|
||||
raise HTTPException(status_code=409, detail="Decision already resolved")
|
||||
|
||||
review_rows = await session.execute(
|
||||
select(ReviewContract).where(
|
||||
ReviewContract.decision_id == decision.id,
|
||||
ReviewContract.active.is_(True),
|
||||
ReviewContract.required_for_decision.is_(True),
|
||||
)
|
||||
)
|
||||
for contract in review_rows.scalars():
|
||||
review_state = await aggregate(session, contract)
|
||||
if not review_state.satisfied:
|
||||
raise HTTPException(
|
||||
status_code=409,
|
||||
detail={
|
||||
"message": "required multi-owner review is not satisfied",
|
||||
"contract_key": contract.contract_key,
|
||||
"contract_digest": contract.contract_digest,
|
||||
},
|
||||
)
|
||||
|
||||
decision.status = DecisionStatus.resolved
|
||||
decision.decision_type = DecisionType.made
|
||||
decision.rationale = body.rationale
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue