API contract hardening

This commit is contained in:
2026-04-26 17:32:01 +02:00
parent 57bc289fdc
commit 2c2bd4347a
6 changed files with 415 additions and 1 deletions

View File

@@ -40,6 +40,7 @@ from repo_registry.web_api.schemas import (
ContentChunkResponse,
EvidenceCreate,
EvidenceUpdate,
ErrorResponse,
FeatureCreate,
FeatureUpdate,
IdResponse,
@@ -116,6 +117,10 @@ app = FastAPI(
version="0.1.0",
description=API_DESCRIPTION,
openapi_tags=OPENAPI_TAGS,
responses={
400: {"model": ErrorResponse, "description": "Bad request."},
404: {"model": ErrorResponse, "description": "Resource not found."},
},
)

View File

@@ -34,6 +34,19 @@ SOURCE_REFERENCE_EXAMPLE = {
}
class ErrorResponse(BaseModel):
detail: str
model_config = {
"json_schema_extra": {
"examples": [
{"detail": "repository 999 was not found"},
{"detail": "target candidate must be different from source"},
]
}
}
class RepositoryCreate(BaseModel):
url: str
name: str | None = None
@@ -540,6 +553,61 @@ class AnalysisRunDiffResponse(BaseModel):
candidates: AnalysisRunDiffSectionResponse
approved_entries: AnalysisRunDiffSectionResponse
model_config = {
"json_schema_extra": {
"examples": [
{
"repository": REPOSITORY_EXAMPLE,
"base_run": {**ANALYSIS_RUN_EXAMPLE, "id": 1},
"target_run": {**ANALYSIS_RUN_EXAMPLE, "id": 2},
"facts": {
"added": [
{
"change_type": "added",
"item_type": "fact",
"key": "api_route:src/routes/status.py:GET /status",
"target": {
"kind": "api_route",
"path": "src/routes/status.py",
"name": "GET /status",
},
}
],
"removed": [],
"changed": [],
"weakened": [],
},
"chunks": {
"added": [],
"removed": [],
"changed": [],
"weakened": [],
},
"candidates": {
"added": [],
"removed": [],
"changed": [],
"weakened": [
{
"change_type": "weakened",
"item_type": "capability",
"key": "classify incoming email",
"base": {"confidence": 0.9},
"target": {"confidence": 0.62},
}
],
},
"approved_entries": {
"added": [],
"removed": [],
"changed": [],
"weakened": [],
},
}
]
}
}
class EvidenceResponse(BaseModel):
id: int
@@ -760,6 +828,48 @@ class RepositoryComparisonResponse(BaseModel):
abilities: list[ComparedAbilityResponse]
unique_capabilities: list[UniqueCapabilityResponse]
model_config = {
"json_schema_extra": {
"examples": [
{
"repositories": [
REPOSITORY_EXAMPLE,
{**REPOSITORY_EXAMPLE, "id": 2, "name": "InboxWorker"},
],
"abilities": [
{
"name": "Business Email Routing",
"repositories": [
{
"repository_id": 1,
"repository_name": "MailRouter",
"confidence": 0.92,
"confidence_label": "high",
"capabilities": [
{
"name": "Classify Incoming Email",
"confidence": 0.88,
"confidence_label": "high",
"evidence_count": 2,
}
],
}
],
}
],
"unique_capabilities": [
{
"repository_id": 1,
"repository_name": "MailRouter",
"ability_name": "Business Email Routing",
"capability_name": "Classify Incoming Email",
}
],
}
]
}
}
class CapabilityGapMatchResponse(BaseModel):
capability: str
@@ -787,3 +897,37 @@ class CapabilityGapResponse(BaseModel):
missing_capabilities: list[str]
weakly_evidenced_capabilities: list[WeakCapabilityEvidenceResponse]
duplicate_capabilities: list[DuplicateCapabilityResponse]
model_config = {
"json_schema_extra": {
"examples": [
{
"desired_ability": "Business Email Routing",
"matched_capabilities": [
{
"capability": "Classify Incoming Email",
"repositories": ["MailRouter"],
}
],
"missing_capabilities": ["Route Email to Team"],
"weakly_evidenced_capabilities": [
{
"capability": "Classify Incoming Email",
"repository_id": 1,
"repository_name": "MailRouter",
"evidence_count": 0,
"strongest_evidence": None,
"confidence": 0.62,
"confidence_label": "medium",
}
],
"duplicate_capabilities": [
{
"capability": "Classify Incoming Email",
"repositories": ["MailRouter", "InboxWorker"],
}
],
}
]
}
}