from __future__ import annotations from typing import Any from pydantic import BaseModel, Field class RepositoryCreate(BaseModel): url: str name: str | None = None description: str | None = None branch: str = "main" model_config = { "json_schema_extra": { "examples": [ { "url": "https://github.com/example/repository.git", "name": "Example Repository", "description": "Optional human-readable repository summary.", "branch": "main", } ] } } class RepositoryUpdate(BaseModel): name: str | None = None description: str | None = None branch: str | None = None model_config = { "json_schema_extra": { "examples": [ { "name": "Renamed Repository", "description": "Updated curator-facing summary.", "branch": "main", } ] } } class AbilityCreate(BaseModel): name: str description: str = "" confidence: float = Field(default=1.0, ge=0.0, le=1.0) model_config = { "json_schema_extra": { "examples": [ { "name": "Business Email Routing", "description": "Route inbound messages to the right team.", "confidence": 0.92, } ] } } class AbilityUpdate(BaseModel): name: str | None = None description: str | None = None confidence: float | None = Field(default=None, ge=0.0, le=1.0) class CapabilityCreate(BaseModel): ability_id: int name: str description: str = "" inputs: list[str] = Field(default_factory=list) outputs: list[str] = Field(default_factory=list) confidence: float = Field(default=1.0, ge=0.0, le=1.0) model_config = { "json_schema_extra": { "examples": [ { "ability_id": 1, "name": "Classify Incoming Email", "description": "Classify messages by intent.", "inputs": ["subject", "body"], "outputs": ["intent", "confidence"], "confidence": 0.88, } ] } } class CapabilityUpdate(BaseModel): name: str | None = None description: str | None = None inputs: list[str] | None = None outputs: list[str] | None = None confidence: float | None = Field(default=None, ge=0.0, le=1.0) class FeatureCreate(BaseModel): capability_id: int name: str type: str location: str = "" confidence: float = Field(default=1.0, ge=0.0, le=1.0) model_config = { "json_schema_extra": { "examples": [ { "capability_id": 1, "name": "POST /api/classify-email", "type": "REST endpoint", "location": "src/routes/classify_email.py", "confidence": 0.84, } ] } } class FeatureUpdate(BaseModel): name: str | None = None type: str | None = None location: str | None = None confidence: float | None = Field(default=None, ge=0.0, le=1.0) class EvidenceCreate(BaseModel): capability_id: int type: str reference: str strength: str = "medium" model_config = { "json_schema_extra": { "examples": [ { "capability_id": 1, "type": "unit_test", "reference": "tests/test_email_classification.py", "strength": "strong", } ] } } class EvidenceUpdate(BaseModel): type: str | None = None reference: str | None = None strength: str | None = None class AnalysisRunCreate(BaseModel): source_path: str | None = None model_config = { "json_schema_extra": { "examples": [ {}, {"source_path": "/path/to/local/repository"}, ] } } class CandidateGraphApproval(BaseModel): notes: str = "" model_config = { "json_schema_extra": { "examples": [{"notes": "Approved after curator review."}] } } class CandidateRejection(BaseModel): notes: str = "" model_config = { "json_schema_extra": { "examples": [{"notes": "Rejected because the claim is too generic."}] } } class CandidateEdit(BaseModel): name: str description: str = "" confidence: float = Field(default=0.5, ge=0.0, le=1.0) notes: str = "" model_config = { "json_schema_extra": { "examples": [ { "name": "Service Health Monitoring", "description": "Expose health state for operational checks.", "confidence": 0.9, "notes": "Renamed from generated review seed.", } ] } } class CandidateCapabilityRelink(BaseModel): target_ability_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [ {"target_ability_id": 2, "notes": "Move under operational ability."} ] } } class CandidateLeafRelink(BaseModel): target_capability_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [ { "target_capability_id": 3, "notes": "Evidence supports a different capability.", } ] } } class CandidateAbilityMerge(BaseModel): target_ability_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [ {"target_ability_id": 2, "notes": "Duplicate ability wording."} ] } } class CandidateCapabilityMerge(BaseModel): target_capability_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [ {"target_capability_id": 3, "notes": "Duplicate capability."} ] } } class CandidateFeatureMerge(BaseModel): target_feature_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [{"target_feature_id": 4, "notes": "Duplicate route."}] } } class CandidateEvidenceMerge(BaseModel): target_evidence_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [{"target_evidence_id": 5, "notes": "Duplicate evidence."}] } } class RepositoryResponse(BaseModel): id: int name: str url: str description: str | None branch: str status: str class RepositorySnapshotResponse(BaseModel): id: int repository_id: int commit_hash: str branch: str source_path: str file_count: int class AnalysisRunResponse(BaseModel): id: int repository_id: int snapshot_id: int | None status: str started_at: str completed_at: str | None error_message: str | None scanner_version: str class ReviewDecisionResponse(BaseModel): id: int repository_id: int analysis_run_id: int | None action: str notes: str created_at: str class ObservedFactResponse(BaseModel): id: int repository_id: int analysis_run_id: int snapshot_id: int | None kind: str path: str name: str value: str metadata: dict[str, Any] class ContentChunkResponse(BaseModel): id: int repository_id: int analysis_run_id: int snapshot_id: int | None path: str kind: str start_line: int end_line: int text: str class ScanSummaryResponse(BaseModel): analysis_run: AnalysisRunResponse snapshot: RepositorySnapshotResponse | None facts: list[ObservedFactResponse] class SourceReferenceResponse(BaseModel): fact_id: int | None path: str kind: str name: str line: int | None = None class CandidateEvidenceResponse(BaseModel): id: int type: str reference: str strength: str status: str source_refs: list[SourceReferenceResponse] class CandidateFeatureResponse(BaseModel): id: int name: str type: str location: str confidence: float status: str source_refs: list[SourceReferenceResponse] confidence_label: str class CandidateCapabilityResponse(BaseModel): id: int name: str description: str inputs: list[str] outputs: list[str] confidence: float status: str source_refs: list[SourceReferenceResponse] confidence_label: str features: list[CandidateFeatureResponse] evidence: list[CandidateEvidenceResponse] class CandidateAbilityResponse(BaseModel): id: int name: str description: str confidence: float status: str source_refs: list[SourceReferenceResponse] confidence_label: str capabilities: list[CandidateCapabilityResponse] class CandidateGraphResponse(BaseModel): repository: RepositoryResponse analysis_run: AnalysisRunResponse abilities: list[CandidateAbilityResponse] class EvidenceResponse(BaseModel): id: int type: str reference: str strength: str source_refs: list[SourceReferenceResponse] class FeatureResponse(BaseModel): id: int name: str type: str location: str confidence: float confidence_label: str source_refs: list[SourceReferenceResponse] class CapabilityResponse(BaseModel): id: int name: str description: str inputs: list[str] outputs: list[str] confidence: float confidence_label: str features: list[FeatureResponse] evidence: list[EvidenceResponse] class AbilityResponse(BaseModel): id: int name: str description: str confidence: float confidence_label: str capabilities: list[CapabilityResponse] class RepositoryAbilityMapResponse(BaseModel): repository: RepositoryResponse abilities: list[AbilityResponse] class IdResponse(BaseModel): id: int class SearchResultResponse(BaseModel): repository_id: int repository_name: str match_type: str match_name: str confidence: float confidence_label: str match_description: str matched_field: str ability_id: int | None = None ability_name: str | None = None capability_id: int | None = None capability_name: str | None = None evidence_level: str | None = None source_reference: str | None = None class AbilitySummaryResponse(BaseModel): id: int repository_id: int repository_name: str name: str description: str confidence: float confidence_label: str class CapabilitySummaryResponse(BaseModel): id: int repository_id: int repository_name: str ability_id: int ability_name: str name: str description: str confidence: float confidence_label: str