diff --git a/dashboard/amplify/data/resource.ts b/dashboard/amplify/data/resource.ts index 56c9dc3bb..cd34d610b 100644 --- a/dashboard/amplify/data/resource.ts +++ b/dashboard/amplify/data/resource.ts @@ -48,7 +48,6 @@ type DataSourceIndexFields = "accountId" | "scorecardId" | "scoreId" | "name" | type DataSourceVersionIndexFields = "dataSourceId" | "createdAt" | "updatedAt"; type DataSetIndexFields = "accountId" | "scorecardId" | "scoreId" | "scoreVersionId" | "dataSourceVersionId" | "createdAt" | "updatedAt"; type ProcedureIndexFields = "accountId" | "scorecardId" | "scoreId" | "scoreVersionId" | "parentProcedureId" | "updatedAt" | "createdAt" | "category" | "version" | "status" | "createdByUserId"; -type ProcedureScoreVersionIndexFields = "procedureId" | "scoreVersionId" | "updatedAt"; // New index types for Feedback Alignment // type FeedbackAlignmentIndexFields = "accountId" | "scorecardId" | "createdAt"; // REMOVED @@ -225,8 +224,7 @@ const schema = a.schema({ childVersions: a.hasMany('ScoreVersion', 'parentVersionId'), evaluations: a.hasMany('Evaluation', 'scoreVersionId'), dataSets: a.hasMany('DataSet', 'scoreVersionId'), - procedures: a.hasMany('Procedure', 'scoreVersionId'), - procedureLinks: a.hasMany('ProcedureScoreVersion', 'scoreVersionId') + procedures: a.hasMany('Procedure', 'scoreVersionId') }) .authorization((allow) => [ allow.publicApiKey(), @@ -906,7 +904,6 @@ const schema = a.schema({ score: a.belongsTo('Score', 'scoreId'), scoreVersionId: a.string(), scoreVersion: a.belongsTo('ScoreVersion', 'scoreVersionId'), - scoreVersionLinks: a.hasMany('ProcedureScoreVersion', 'procedureId'), chatSessions: a.hasMany('ChatSession', 'procedureId'), chatMessages: a.hasMany('ChatMessage', 'procedureId'), createdByUserId: a.string(), @@ -927,28 +924,6 @@ const schema = a.schema({ idx("createdByUserId") ]), - ProcedureScoreVersion: a - .model({ - procedureId: a.string().required(), - procedure: a.belongsTo('Procedure', 'procedureId'), - scoreVersionId: a.string().required(), - scoreVersion: a.belongsTo('ScoreVersion', 'scoreVersionId'), - accountId: a.string().required(), - scorecardId: a.string(), - scoreId: a.string(), - relationshipTypes: a.string().array(), - createdAt: a.datetime().required(), - updatedAt: a.datetime().required(), - }) - .authorization((allow) => [ - allow.publicApiKey(), - allow.authenticated() - ]) - .secondaryIndexes((idx: (field: ProcedureScoreVersionIndexFields) => any) => [ - idx("procedureId").sortKeys(["updatedAt"]), - idx("scoreVersionId").sortKeys(["updatedAt"]) - ]), - ChatSession: a .model({ accountId: a.string().required(), diff --git a/plexus/cli/shared/optimizer_results.py b/plexus/cli/shared/optimizer_results.py index 7ce469177..373fd131d 100644 --- a/plexus/cli/shared/optimizer_results.py +++ b/plexus/cli/shared/optimizer_results.py @@ -136,39 +136,6 @@ def _sort_by_updated_at_desc(items: Iterable[Dict[str, Any]]) -> List[Dict[str, ) -def _optimizer_manifest_score_version_links(manifest: Dict[str, Any]) -> Dict[str, List[str]]: - links: Dict[str, List[str]] = {} - - def add(version_id: Any, relationship_type: str) -> None: - if not isinstance(version_id, str) or not version_id: - return - relationship_types = links.setdefault(version_id, []) - if relationship_type not in relationship_types: - relationship_types.append(relationship_type) - - baseline = manifest.get("baseline") or {} - if isinstance(baseline, dict): - add(baseline.get("version_id"), "baseline") - - best = manifest.get("best") or {} - if isinstance(best, dict): - add(best.get("winning_version_id"), "winning") - add(best.get("last_accepted_version_id"), "accepted") - - for cycle in manifest.get("cycles") or []: - if not isinstance(cycle, dict): - continue - add(cycle.get("version_id"), "cycle") - for candidate in cycle.get("candidates") or []: - if isinstance(candidate, dict): - add(candidate.get("version_id"), "candidate") - for candidate in cycle.get("no_version_candidates") or []: - if isinstance(candidate, dict): - add(candidate.get("version_id"), "no_version_candidate") - - return links - - def _evaluation_url(evaluation_id: Optional[str]) -> Optional[str]: return f"{LAB_EVALUATION_BASE_URL}/{evaluation_id}" if evaluation_id else None @@ -647,115 +614,6 @@ def _artifact_keys_for_task(self, task_id: str) -> Dict[str, str]: "runtime_log": f"tasks/{task_id}/{OPTIMIZER_RUNTIME_LOG_SUFFIX}", } - def _list_score_version_links_for_procedure(self, procedure_id: str) -> List[Dict[str, Any]]: - query = """ - query ListProcedureScoreVersionByProcedureIdAndUpdatedAtForOptimizer( - $procedureId: String! - $limit: Int - $nextToken: String - ) { - listProcedureScoreVersionByProcedureIdAndUpdatedAt( - procedureId: $procedureId - sortDirection: DESC - limit: $limit - nextToken: $nextToken - ) { - items { - id - procedureId - scoreVersionId - } - nextToken - } - } - """ - links: List[Dict[str, Any]] = [] - next_token: Optional[str] = None - while True: - variables: Dict[str, Any] = {"procedureId": procedure_id, "limit": 100} - if next_token: - variables["nextToken"] = next_token - result = self.client.execute(query, variables) - payload = result.get("listProcedureScoreVersionByProcedureIdAndUpdatedAt", {}) - links.extend(item for item in payload.get("items") or [] if isinstance(item, dict)) - next_token = payload.get("nextToken") - if not next_token: - break - return links - - def _sync_optimizer_score_version_links( - self, - *, - procedure: Dict[str, Any], - manifest: Dict[str, Any], - ) -> None: - procedure_id = str(procedure.get("id") or "") - account_id = str(procedure.get("accountId") or "") - if not procedure_id or not account_id: - return - - now = _utc_now_iso() - desired = _optimizer_manifest_score_version_links(manifest) - existing = self._list_score_version_links_for_procedure(procedure_id) - existing_by_version = { - item.get("scoreVersionId"): item - for item in existing - if isinstance(item.get("scoreVersionId"), str) - } - - create_mutation = """ - mutation CreateProcedureScoreVersionForOptimizer($input: CreateProcedureScoreVersionInput!) { - createProcedureScoreVersion(input: $input) { - id - } - } - """ - update_mutation = """ - mutation UpdateProcedureScoreVersionForOptimizer($input: UpdateProcedureScoreVersionInput!) { - updateProcedureScoreVersion(input: $input) { - id - } - } - """ - delete_mutation = """ - mutation DeleteProcedureScoreVersionForOptimizer($input: DeleteProcedureScoreVersionInput!) { - deleteProcedureScoreVersion(input: $input) { - id - } - } - """ - - for version_id, relationship_types in desired.items(): - existing_item = existing_by_version.get(version_id) - input_data = { - "procedureId": procedure_id, - "scoreVersionId": version_id, - "accountId": account_id, - "scorecardId": procedure.get("scorecardId"), - "scoreId": procedure.get("scoreId"), - "relationshipTypes": relationship_types, - "updatedAt": now, - } - if existing_item: - self.client.execute( - update_mutation, - {"input": {"id": existing_item["id"], **input_data}}, - ) - else: - link_id = f"{procedure_id}:{version_id}" - self.client.execute( - create_mutation, - {"input": {"id": link_id, "createdAt": now, **input_data}}, - ) - - desired_versions = set(desired.keys()) - for existing_item in existing: - version_id = existing_item.get("scoreVersionId") - link_id = existing_item.get("id") - if version_id in desired_versions or not link_id: - continue - self.client.execute(delete_mutation, {"input": {"id": link_id}}) - def index_optimizer_run( self, procedure_id: str, @@ -786,7 +644,6 @@ def index_optimizer_run( raise RuntimeError("aws.storage.task_attachments_bucket is required for optimizer artifacts.") manifest = self.build_manifest(procedure=procedure, task=task, state=state) - self._sync_optimizer_score_version_links(procedure=procedure, manifest=manifest) artifact_keys = self._artifact_keys_for_task(task.id) upload_task_attachment_bytes( bucket_name=bucket_name, diff --git a/plexus/cli/shared/optimizer_results_test.py b/plexus/cli/shared/optimizer_results_test.py index 262c1e2d1..2ac28c375 100644 --- a/plexus/cli/shared/optimizer_results_test.py +++ b/plexus/cli/shared/optimizer_results_test.py @@ -10,22 +10,8 @@ class _FakeClient: def __init__(self): self.update_calls = [] - self.link_creates = [] - self.link_updates = [] - self.link_deletes = [] def execute(self, query, variables): - if "listProcedureScoreVersionByProcedureIdAndUpdatedAt" in query: - return {"listProcedureScoreVersionByProcedureIdAndUpdatedAt": {"items": [], "nextToken": None}} - if "createProcedureScoreVersion" in query: - self.link_creates.append({"query": query, "variables": variables}) - return {"createProcedureScoreVersion": {"id": variables["input"]["id"]}} - if "updateProcedureScoreVersion" in query: - self.link_updates.append({"query": query, "variables": variables}) - return {"updateProcedureScoreVersion": {"id": variables["input"]["id"]}} - if "deleteProcedureScoreVersion" in query: - self.link_deletes.append({"query": query, "variables": variables}) - return {"deleteProcedureScoreVersion": {"id": variables["input"]["id"]}} if "updateProcedure(input:" in query: self.update_calls.append({"query": query, "variables": variables}) return {"updateProcedure": {"id": variables["input"]["id"], "metadata": variables["input"]["metadata"]}} @@ -172,14 +158,6 @@ def test_index_optimizer_run_persists_manifest_and_pointer(monkeypatch): pointer = saved_metadata[OPTIMIZER_ARTIFACTS_METADATA_KEY] assert pointer["task_id"] == "task-123" assert pointer["manifest"] == "tasks/task-123/optimizer/manifest.json" - linked_versions = { - call["variables"]["input"]["scoreVersionId"]: call["variables"]["input"]["relationshipTypes"] - for call in client.link_creates - } - assert linked_versions["version-baseline"] == ["baseline"] - assert linked_versions["version-accepted"] == ["winning", "accepted", "cycle"] - assert linked_versions["version-1"] == ["cycle"] - assert linked_versions["version-candidate"] == ["candidate"] def test_list_optimizer_candidates_for_score_aggregates_best_visible_metrics(monkeypatch):