feat(dashboard): measure observed case lifecycles - #653
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Reviewed exact head The conflict resolution also restored evidence visibility predicates for classification/fact/milestone queries, the lifecycle metrics projection, and frontend lifecycle fields/rendering; these are required for the PR contract rather than compatibility shims. Exact-head local evidence:
|
| _OPERATIONS_CASE_MILESTONE_MIGRATION = ( | ||
| Path(__file__).resolve().parents[1] | ||
| / "migrations" | ||
| / "0215_operations_case_milestone.sql" | ||
| ) |
There was a problem hiding this comment.
🟡 New milestone migration left out of the schema test
The _OPERATIONS_CASE_MILESTONE_MIGRATION constant for 0215_operations_case_milestone.sql is defined but the schema_db fixture never executes it, unlike every other operations-case migration. The new milestone tables and their constraints are never created in the throwaway database, so the migration goes unvalidated by the real-DB schema test.
Prompt for agents
In tests/test_schema.py the schema_db fixture applies each operations-case migration explicitly via cur.execute(...). The newly added _OPERATIONS_CASE_MILESTONE_MIGRATION (migrations/0215_operations_case_milestone.sql) is defined but never executed inside the fixture's `with conn.cursor() as cur:` block, so the operations_case_milestone and operations_case_missing_milestone tables are never created and the migration is not exercised by the real-database schema replay test. Add a cur.execute(_OPERATIONS_CASE_MILESTONE_MIGRATION.read_text()) call in the fixture in the correct order (after the operations_case classification/missing-fact migrations it depends on, since the milestone tables reference operations_case_classification). Optionally assert the new tables appear in test_migration_applies_cleanly.
Was this helpful? React with 👍 or 👎 to provide feedback.
| elif start and end_code in missing_milestones: | ||
| elapsed_seconds = None | ||
| status_code = "open" | ||
| next_action = f"{MILESTONE_TYPE_LABELS[end_code]} Event 근거를 연결하세요." | ||
| else: | ||
| elapsed_seconds = None | ||
| status_code = "evidence_missing" | ||
| next_action = f"{MILESTONE_TYPE_LABELS[start_code]} Event 근거를 연결하세요." |
There was a problem hiding this comment.
📝 Info: Hidden evidence posts silently downgrade lifecycle status
The observed-milestone query joins evidence_post under visible_evidence (operations_dashboard.py:290-294) while the missing branch does not. When a milestone's evidence post is no longer visible, it vanishes from the observed set and is absent from missing_milestones, so _project_lifecycles reports evidence_missing even when the start endpoint exists, and next_action can name the wrong milestone. This is the intended ABAC recheck, but the status/next-action copy can mislead for partially hidden cases.
Was this helpful? React with 👍 or 👎 to provide feedback.
| union all | ||
| select missing.post_id, missing.case_kind_code, | ||
| missing.milestone_type_code, null, null, null, null, true | ||
| from operations_case_missing_milestone missing | ||
| join source_post post on post.post_id = missing.post_id | ||
| where {visible} | ||
| and ($5::boolean is false or missing.case_kind_code = 'external_information') | ||
| order by post_id, case_kind_code, milestone_type_code |
There was a problem hiding this comment.
📝 Info: Milestone array order in test differs from real DB
The union query orders by milestone_type_code (operations_dashboard.py:303), so a claim case returns cause_confirmed before claim_received, but the test mock returns them claim_received-first, so the asserted array order will not match production. No functional impact: the frontend derives endpoints via by-type lookup in _project_lifecycles, not from the raw milestones array order.
Was this helpful? React with 👍 or 👎 to provide feedback.
| if source.evidence_facts | ||
| else "" | ||
| ), | ||
| source_times[source.post_id][0], | ||
| source_times[source.post_id][1], |
There was a problem hiding this comment.
📝 Info: Milestone instants correctly bound to source clocks
Each source's observed instant is fetched from source_post and attached in _operations_evidence_sources (post_content_worker.py:75-100), and the parser binds observed_at from the cited source, rejecting sources missing an instant. source_times[source.post_id] cannot KeyError because gather_chat_sources only returns posts that exist in source_post, and ChatSourceDocument.post_id is already a canonical string matching the fetched keys.
(Refers to this code)
Was this helpful? React with 👍 or 👎 to provide feedback.
Outcome
Adds a normalized, evidence-bound observed-milestone contract for claim-cause investigation, rebid response, and handover gaps.
event_occurred_atorcreated_atinstants; the model cannot generate dates.Stack
Depends on #640 and targets
feat/dashboard-case-metrics.Verification
Research and standards
ADR 0206 records the adopted IEEE 1849-2023 XES event-log, Process Mining Manifesto, and W3C Time Ontology basis in APA 7 format.