generated from coulomb/repo-seed
first review workflow slice
This commit is contained in:
@@ -103,6 +103,67 @@ class RegistryService:
|
||||
def candidate_graph(self, repository_id: int, analysis_run_id: int) -> CandidateGraph:
|
||||
return self.store.get_candidate_graph(repository_id, analysis_run_id)
|
||||
|
||||
def approve_candidate_graph(
|
||||
self,
|
||||
repository_id: int,
|
||||
analysis_run_id: int,
|
||||
*,
|
||||
notes: str = "",
|
||||
) -> RepositoryAbilityMap:
|
||||
graph = self.store.get_candidate_graph(repository_id, analysis_run_id)
|
||||
pending_abilities = [
|
||||
ability for ability in graph.abilities if ability.status == "candidate"
|
||||
]
|
||||
for ability in pending_abilities:
|
||||
approved_ability_id = self.store.create_ability(
|
||||
repository_id,
|
||||
name=ability.name,
|
||||
description=ability.description,
|
||||
confidence=ability.confidence,
|
||||
)
|
||||
for capability in ability.capabilities:
|
||||
approved_capability_id = self.store.create_capability(
|
||||
repository_id,
|
||||
approved_ability_id,
|
||||
name=capability.name,
|
||||
description=capability.description,
|
||||
inputs=capability.inputs,
|
||||
outputs=capability.outputs,
|
||||
confidence=capability.confidence,
|
||||
)
|
||||
for feature in capability.features:
|
||||
self.store.create_feature(
|
||||
repository_id,
|
||||
approved_capability_id,
|
||||
name=feature.name,
|
||||
type=feature.type,
|
||||
location=feature.location,
|
||||
confidence=feature.confidence,
|
||||
)
|
||||
for evidence in capability.evidence:
|
||||
self.store.create_evidence(
|
||||
repository_id,
|
||||
approved_capability_id,
|
||||
type=evidence.type,
|
||||
reference=evidence.reference,
|
||||
strength=evidence.strength,
|
||||
)
|
||||
|
||||
if pending_abilities:
|
||||
self.store.mark_candidate_graph_status(
|
||||
repository_id,
|
||||
analysis_run_id,
|
||||
"approved",
|
||||
)
|
||||
self.store.create_review_decision(
|
||||
repository_id,
|
||||
analysis_run_id,
|
||||
action="approve_candidate_graph",
|
||||
notes=notes,
|
||||
)
|
||||
self.store.update_repository_status(repository_id, "indexed")
|
||||
return self.store.get_ability_map(repository_id)
|
||||
|
||||
def add_ability(
|
||||
self,
|
||||
repository_id: int,
|
||||
|
||||
@@ -361,6 +361,47 @@ class RegistryStore:
|
||||
abilities=abilities,
|
||||
)
|
||||
|
||||
def mark_candidate_graph_status(
|
||||
self,
|
||||
repository_id: int,
|
||||
analysis_run_id: int,
|
||||
status: str,
|
||||
) -> None:
|
||||
with self.connect() as connection:
|
||||
for table in (
|
||||
"candidate_abilities",
|
||||
"candidate_capabilities",
|
||||
"candidate_features",
|
||||
"candidate_evidence",
|
||||
):
|
||||
connection.execute(
|
||||
f"""
|
||||
UPDATE {table}
|
||||
SET status = ?
|
||||
WHERE repository_id = ? AND analysis_run_id = ?
|
||||
""",
|
||||
(status, repository_id, analysis_run_id),
|
||||
)
|
||||
|
||||
def create_review_decision(
|
||||
self,
|
||||
repository_id: int,
|
||||
analysis_run_id: int,
|
||||
*,
|
||||
action: str,
|
||||
notes: str = "",
|
||||
) -> int:
|
||||
with self.connect() as connection:
|
||||
cursor = connection.execute(
|
||||
"""
|
||||
INSERT INTO review_decisions
|
||||
(repository_id, analysis_run_id, action, notes)
|
||||
VALUES (?, ?, ?, ?)
|
||||
""",
|
||||
(repository_id, analysis_run_id, action, notes),
|
||||
)
|
||||
return int(cursor.lastrowid)
|
||||
|
||||
def fail_analysis_run(
|
||||
self,
|
||||
repository_id: int,
|
||||
|
||||
@@ -69,6 +69,10 @@ class AnalysisRunCreate(BaseModel):
|
||||
source_path: str | None = None
|
||||
|
||||
|
||||
class CandidateGraphApproval(BaseModel):
|
||||
notes: str = ""
|
||||
|
||||
|
||||
app = FastAPI(title="Repository Ability Registry", version="0.1.0")
|
||||
|
||||
|
||||
@@ -161,6 +165,25 @@ def get_candidate_graph(
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@app.post("/repos/{repository_id}/analysis-runs/{analysis_run_id}/candidate-graph/approve")
|
||||
def approve_candidate_graph(
|
||||
repository_id: int,
|
||||
analysis_run_id: int,
|
||||
payload: CandidateGraphApproval,
|
||||
service: RegistryService = Depends(get_service),
|
||||
) -> dict[str, object]:
|
||||
try:
|
||||
return asdict(
|
||||
service.approve_candidate_graph(
|
||||
repository_id,
|
||||
analysis_run_id,
|
||||
notes=payload.notes,
|
||||
)
|
||||
)
|
||||
except NotFoundError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@app.post("/repos/{repository_id}/abilities", status_code=201)
|
||||
def create_ability(
|
||||
repository_id: int,
|
||||
|
||||
Reference in New Issue
Block a user