feat(pilot): pydantic schemas for fix outcome patch
Adds FixStatus literal (5 values matching the DB check constraint), extends SessionSuggestedFixResponse with outcome fields, and introduces SessionSuggestedFixOutcomeRequest for the PATCH /outcome endpoint coming in Task 3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,17 @@ from pydantic import BaseModel, Field
|
|||||||
|
|
||||||
UserDecision = Literal["one_off", "draft_template", "build_template", "dismissed"]
|
UserDecision = Literal["one_off", "draft_template", "build_template", "dismissed"]
|
||||||
|
|
||||||
|
# "dismissed" here is the outcome dimension — orthogonal to UserDecision's
|
||||||
|
# "dismissed" (script-path choice), though the migration backfill aligns
|
||||||
|
# them for pre-existing rows.
|
||||||
|
FixStatus = Literal[
|
||||||
|
"proposed",
|
||||||
|
"applied_success",
|
||||||
|
"applied_failed",
|
||||||
|
"applied_partial",
|
||||||
|
"dismissed",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class SessionSuggestedFixResponse(BaseModel):
|
class SessionSuggestedFixResponse(BaseModel):
|
||||||
id: UUID
|
id: UUID
|
||||||
@@ -25,6 +36,12 @@ class SessionSuggestedFixResponse(BaseModel):
|
|||||||
user_decision: UserDecision | None
|
user_decision: UserDecision | None
|
||||||
superseded_at: datetime | None
|
superseded_at: datetime | None
|
||||||
created_at: datetime
|
created_at: datetime
|
||||||
|
status: FixStatus
|
||||||
|
applied_at: datetime | None
|
||||||
|
verified_at: datetime | None
|
||||||
|
partial_notes: str | None
|
||||||
|
failure_reason: str | None
|
||||||
|
ai_outcome_proposal: dict[str, Any] | None
|
||||||
|
|
||||||
model_config = {"from_attributes": True}
|
model_config = {"from_attributes": True}
|
||||||
|
|
||||||
@@ -71,6 +88,30 @@ class SessionSuggestedFixDecisionResponse(BaseModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Subset of FixStatus that the engineer can set via the outcome endpoint —
|
||||||
|
# `proposed` is excluded because you can't un-decide a fix back to "proposed".
|
||||||
|
FixOutcome = Literal[
|
||||||
|
"applied_success", "applied_failed", "applied_partial", "dismissed"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class SessionSuggestedFixOutcomeRequest(BaseModel):
|
||||||
|
"""Engineer-reported outcome of applying a suggested fix.
|
||||||
|
|
||||||
|
Writes to session_suggested_fixes.status and companion columns. This is
|
||||||
|
orthogonal to `user_decision` (which records which script-path the
|
||||||
|
engineer took); outcome captures whether the fix actually worked.
|
||||||
|
|
||||||
|
Allowed transitions:
|
||||||
|
- from `proposed`: any of applied_success | applied_failed | applied_partial | dismissed
|
||||||
|
- from `applied_partial`: applied_success | applied_failed (partial is not terminal)
|
||||||
|
- from any terminal outcome: no change (server returns 409)
|
||||||
|
"""
|
||||||
|
outcome: FixOutcome
|
||||||
|
# Required for applied_partial, optional for applied_failed, ignored otherwise.
|
||||||
|
notes: str | None = Field(None, max_length=500)
|
||||||
|
|
||||||
|
|
||||||
# ── Resolution note preview ────────────────────────────────────────────────
|
# ── Resolution note preview ────────────────────────────────────────────────
|
||||||
|
|
||||||
class ResolutionNotePreviewResponse(BaseModel):
|
class ResolutionNotePreviewResponse(BaseModel):
|
||||||
|
|||||||
Reference in New Issue
Block a user