from __future__ import annotations import json from collections import defaultdict from datetime import datetime, timedelta, timezone from typing import Any from .i18n import DEFAULT_LOCALE, translate SIGNAL_EPISODE_GAP = timedelta(hours=72) TIMELINE_CHILD_LIMIT = 12 TREATMENT_JOURNEY_EVENT_TYPES = { "record_created", "record_updated", "treatment_record_created", "recommendation_shared", "treatment_created", "treatment_milestone", "observation_started", "treatment_completed", "treatment_cancelled", "treatment_reopened", } def _list(value: Any) -> list[Any]: if value is None: return [] return value if isinstance(value, list) else [value] def _dict(value: Any) -> dict[str, Any]: return value if isinstance(value, dict) else {} def _datetime(value: str | None) -> datetime: try: parsed = datetime.fromisoformat((value or "").replace("Z", "+00:00")) except (TypeError, ValueError): return datetime.min.replace(tzinfo=timezone.utc) if parsed.tzinfo is None: parsed = parsed.replace(tzinfo=timezone.utc) return parsed.astimezone(timezone.utc) def _t(locale: str, key: str, **params: Any) -> str: return translate(f"timeline:{key}", locale, params=params or None) def _name(value: Any, locale: str = DEFAULT_LOCALE) -> str: if value is None or value == "": return translate("common:state.unknown", locale) code = str(value) marker = f"__missing__:{code}" for path in ( "severity", "catalog.posture", "catalog.status", "catalog.registration_reason", "catalog.initial_action", "finding.source", "finding.source_type", "treatment.stage", "treatment.state", "treatment.outcome", "record.type", "record.state", "record.visibility", "record.option", "priority", ): label = translate(f"domain:{path}.{code}", locale, default=marker) if label != marker: return label return code.replace("_", " ").strip().title() def _field(label: str, value: Any, value_format: str = "text") -> dict[str, Any] | None: if value is None or value == "" or value == []: return None if isinstance(value, (list, tuple, set)): value = ", ".join(str(item) for item in value) elif isinstance(value, bool): value = "Yes" if value else "No" elif not isinstance(value, (str, int, float)): value = json.dumps(value, ensure_ascii=False, separators=(",", ":")) return {"label": label, "value": value, "format": value_format} def _fields(*values: dict[str, Any] | None) -> list[dict[str, Any]]: return [value for value in values if value is not None] def _link( label: str, *, target_type: str | None = None, target_id: str | None = None, href: str | None = None, external: bool = False, ) -> dict[str, Any] | None: if not label or (not href and (not target_type or not target_id)): return None result: dict[str, Any] = {"label": label} if target_type and target_id: result.update({"target_type": target_type, "target_id": target_id}) if href: result.update({"href": href, "external": external}) return result def _links(*values: dict[str, Any] | None) -> list[dict[str, Any]]: return [value for value in values if value is not None] def _severity_tone(severity: str | None) -> str: if severity == "critical": return "danger" if severity == "high": return "processing" if severity == "medium": return "signal" return "neutral" def _finding_signature(finding: dict[str, Any]) -> tuple[Any, ...]: symptoms = tuple( sorted( (str(symptom.get("code") or ""), str(symptom.get("severity") or "")) for symptom in _list(finding.get("symptoms")) if isinstance(symptom, dict) ) ) return ( finding.get("source"), finding.get("source_type"), finding.get("detector_code"), finding.get("severity"), symptoms, ) def _signal_entries( findings: list[dict[str, Any]], locale: str = DEFAULT_LOCALE ) -> list[dict[str, Any]]: ordered = sorted( findings, key=lambda finding: ( _datetime(finding.get("observed_at") or finding.get("created_at")), finding.get("id") or "", ), ) episodes: list[list[dict[str, Any]]] = [] for finding in ordered: observed_at = _datetime(finding.get("observed_at") or finding.get("created_at")) previous_episode = episodes[-1] if episodes else [] previous = previous_episode[-1] if previous_episode else None previous_at = ( _datetime(previous.get("observed_at") or previous.get("created_at")) if previous else None ) continues_episode = bool( previous and finding.get("source_type") != "manual" and _finding_signature(previous) == _finding_signature(finding) and previous_at is not None and observed_at - previous_at <= SIGNAL_EPISODE_GAP ) if continues_episode: previous_episode.append(finding) else: episodes.append([finding]) entries: list[dict[str, Any]] = [] for episode in episodes: first = episode[0] latest = episode[-1] source = str(first.get("source") or "external_source") source_label = _name(source, locale) severity = str(first.get("severity") or "info") symptom_codes = sorted( { str(symptom.get("code")) for finding in episode for symptom in _list(finding.get("symptoms")) if isinstance(symptom, dict) and symptom.get("code") } ) count = len(episode) recurring = count > 1 symptom_summary = ", ".join(symptom_codes) or _t(locale, "events.sql_anomaly") children = [] for finding in reversed(episode[-TIMELINE_CHILD_LIMIT:]): finding_symptoms = [ str(symptom.get("code")) for symptom in _list(finding.get("symptoms")) if isinstance(symptom, dict) and symptom.get("code") ] children.append( { "id": finding["id"], "category": "signal", "event_type": "finding_observed", "tone": _severity_tone(str(finding.get("severity") or "info")), "title": _t( locale, "events.source_observation", source=_name(finding.get("source"), locale), ), "summary": finding.get("source_event_id") or finding["id"], "occurred_at": finding.get("observed_at") or finding.get("created_at"), "severity": finding.get("severity"), "details": _fields( _field(_t(locale, "fields.symptoms"), finding_symptoms, "code"), _field(_t(locale, "fields.detector"), finding.get("detector_code"), "code"), _field(_t(locale, "fields.source_event"), finding.get("source_event_id"), "code"), _field(_t(locale, "fields.received"), finding.get("ingested_at"), "date"), ), "links": _links( _link(_t(locale, "links.open_finding"), target_type="finding", target_id=finding["id"]), _link(_t(locale, "links.open_source_report"), href=finding.get("source_url"), external=True), ), } ) entries.append( { "id": f"signal_episode:{first['id']}:{latest['id']}", "category": "signal", "event_type": "finding_signal_episode", "importance": "activity", "tone": _severity_tone(severity), "title": _t( locale, "events.recurring_finding_title" if recurring else "events.finding_title", source=source_label, ), "summary": _t( locale, "events.recurring_finding_summary" if recurring else "events.finding_summary", count=count, symptoms=symptom_summary, severity=_name(severity, locale), ), "occurred_at": latest.get("observed_at") or latest.get("created_at"), "started_at": ( first.get("observed_at") or first.get("created_at") if recurring else None ), "actor": None, "severity": severity, "count": count, "details": _fields( _field(_t(locale, "fields.source"), source_label), _field(_t(locale, "fields.detector"), first.get("detector_code"), "code"), _field(_t(locale, "fields.symptoms"), symptom_codes, "code"), _field(_t(locale, "fields.first_observed"), first.get("observed_at"), "date"), _field(_t(locale, "fields.latest_observed"), latest.get("observed_at"), "date"), _field(_t(locale, "fields.finding_count"), count, "number"), ), "links": _links( _link(_t(locale, "links.latest_source_report"), href=latest.get("source_url"), external=True) ), "children": children, "children_total": count, "_sequence": 0, } ) return entries def _treatment_label( treatment: dict[str, Any] | None, treatment_id: str | None, locale: str = DEFAULT_LOCALE, ) -> str: if not treatment: return treatment_id or translate("domain:entity.treatment", locale) return " ".join( value for value in [treatment.get("treatment_no"), treatment.get("title")] if value ) def _event_entry( event: dict[str, Any], *, findings: dict[str, dict[str, Any]], records: dict[str, dict[str, Any]], treatments: dict[str, dict[str, Any]], first_finding: dict[str, Any] | None, locale: str = DEFAULT_LOCALE, ) -> dict[str, Any]: event_type = str(event.get("event_type") or "system_event") payload = _dict(event.get("payload")) category = "system" importance = "background" tone = "neutral" title = _name(event_type, locale) summary = event.get("summary") or title details = _fields(_field(_t(locale, "fields.event"), event_type, "code")) links: list[dict[str, Any]] = [] treatment_id = payload.get("treatment_id") treatment = treatments.get(str(treatment_id)) if treatment_id else None treatment_label = _treatment_label( treatment, str(treatment_id) if treatment_id else None, locale ) record_id = payload.get("record_id") record = records.get(str(record_id)) if record_id else None finding_id = payload.get("finding_id") finding = findings.get(str(finding_id)) if finding_id else None if event_type == "catalog_item_created": category, importance, tone = "decision", "milestone", "accent" title = _t(locale, "events.catalog_registered") registration_origin = payload.get("registration_origin") or "finding" if registration_origin == "manual": reason = payload.get("registration_reason") or "other" title = _t(locale, "events.catalog_manually_registered") reason_key = str(reason) if str(reason) in { "customer_ticket", "high_frequency", "proactive_watch", "other" } else "default" summary = _t(locale, f"events.manual_registration.{reason_key}") details.extend( _fields( _field(_t(locale, "fields.registration_reason"), _name(reason, locale)), _field(_t(locale, "fields.initial_handling"), _name(payload.get("initial_action"), locale)), _field(_t(locale, "fields.owner"), payload.get("owner")), _field(_t(locale, "fields.source_reference"), payload.get("source_reference"), "code"), _field(_t(locale, "fields.registration_note"), payload.get("note")), ) ) links.extend( _links( _link(_t(locale, "links.open_source"), href=payload.get("source_url"), external=True) ) ) else: source = payload.get("source") or (first_finding or {}).get("source") summary = _t(locale, "events.first_finding_registered", source=_name(source, locale)) details.extend( _fields( _field(_t(locale, "fields.source"), _name(source, locale)), _field(_t(locale, "fields.source_event"), payload.get("source_event_id"), "code"), ) ) if first_finding: links.extend( _links( _link( _t(locale, "links.open_first_finding"), target_type="finding", target_id=first_finding["id"], ) ) ) elif event_type == "catalog_review_started": category, importance, tone = "decision", "activity", "processing" title = _t(locale, "events.catalog_review_started") summary = _t(locale, "events.catalog_review_started_summary") details.extend( _fields(_field(_t(locale, "fields.owner"), payload.get("owner"))) ) elif event_type == "catalog_decision_recorded": category, importance = "decision", "milestone" action = payload.get("action") tone = "signal" if action == "watch" else "neutral" action_key = str(action) if action in {"watch", "no_action"} else "default" title = _t(locale, f"events.catalog_decision.{action_key}") summary = _t(locale, f"events.catalog_decision_summary.{action_key}") details.extend( _fields( _field(_t(locale, "fields.action"), _name(action, locale)), _field(_t(locale, "fields.owner"), payload.get("owner")), _field( _t(locale, "fields.reviewed_through"), payload.get("reviewed_through_finding_at"), "datetime", ), ) ) if record_id: links.extend( _links( _link( record.get("title") if record else _t(locale, "links.open_decision_record"), target_type="record", target_id=str(record_id), ) ) ) elif event_type == "catalog_item_archived": category, importance, tone = "decision", "milestone", "neutral" title = _t(locale, "events.catalog_archived") summary = _t(locale, "events.catalog_archived_summary") if record_id: links.extend( _links( _link( record.get("title") if record else _t(locale, "links.open_decision_record"), target_type="record", target_id=str(record_id), ) ) ) elif event_type == "catalog_item_reactivated": category, importance, tone = "signal", "warning", "danger" title = _t(locale, "events.catalog_reactivated") summary = _t(locale, "events.catalog_reactivated_summary") elif event_type == "catalog_item_status_changed": previous_status = payload.get("from") next_status = payload.get("to") action = payload.get("action") details.extend( _fields( _field(_t(locale, "fields.previous_status"), previous_status, "status"), _field(_t(locale, "fields.new_status"), next_status, "status"), _field(_t(locale, "fields.action"), action, "code"), _field(_t(locale, "fields.owner"), payload.get("owner")), ) ) if action: category, importance = "decision", "milestone" tone = ( "processing" if next_status in {"reviewing", "in_treatment"} else "signal" if next_status == "watching" else "neutral" ) action_key = str(action) if str(action) in { "start_review", "watch", "no_action", "archive" } else "default" title = _t(locale, f"events.catalog_action.{action_key}") summary = _t( locale, "events.catalog_status_changed", previous=_name(previous_status, locale), current=_name(next_status, locale), ) else: title = _t(locale, "events.catalog_status_synchronized") summary = _t( locale, "events.catalog_status_automated", previous=_name(previous_status, locale), current=_name(next_status, locale), ) if record_id: links.extend( _links( _link( record.get("title") if record else _t(locale, "links.open_decision_record"), target_type="record", target_id=str(record_id), ) ) ) elif event_type == "catalog_item_updated": category, importance, tone = "decision", "activity", "accent" title = _t(locale, "events.catalog_metadata_updated") before = _dict(payload.get("before")) after = _dict(payload.get("after")) changed = [] for field in ("owner", "priority", "severity", "labels"): if before.get(field) == after.get(field): continue changed.append(field) value_format = "severity" if field == "severity" else "text" field_label = _t(locale, f"fields.{field}") details.extend( _fields( _field(_t(locale, "fields.previous_value", field=field_label), before.get(field) or translate("common:state.none", locale), value_format), _field(_t(locale, "fields.new_value", field=field_label), after.get(field) or translate("common:state.none", locale), value_format), ) ) summary = ( _t(locale, "events.catalog_metadata_fields_changed", fields=", ".join(_t(locale, f"fields.{field}") for field in changed)) if changed else _t(locale, "events.catalog_metadata_changed") ) elif event_type == "catalog_item_reappeared": category, importance, tone = "signal", "warning", "danger" title = _t(locale, "events.symptoms_reappeared") summary = _t(locale, "events.symptoms_reappeared_summary") details.extend( _fields( _field(_t(locale, "fields.finding_severity"), (finding or {}).get("severity"), "severity"), ) ) if finding_id: links.extend( _links( _link( _t(locale, "links.open_reappearing_finding"), target_type="finding", target_id=str(finding_id), ) ) ) elif event_type == "finding_relation_review_needed": category, importance, tone = "governance", "warning", "danger" title = _t(locale, "events.finding_relation_review") summary = _t(locale, "events.finding_relation_review_summary") details.extend( _fields(_field(_t(locale, "fields.candidate_treatments"), payload.get("treatment_ids"), "code")) ) if finding_id: links.extend( _links( _link(_t(locale, "links.review_finding"), target_type="finding", target_id=str(finding_id)) ) ) for candidate_id in _list(payload.get("treatment_ids")): candidate = treatments.get(str(candidate_id)) links.extend( _links( _link( _treatment_label(candidate, str(candidate_id), locale), target_type="treatment", target_id=str(candidate_id), ) ) ) elif event_type in {"record_created", "record_updated", "treatment_record_created"}: category, importance, tone = "record", "activity", "neutral" action = "updated" if event_type == "record_updated" else "added" record_title = (record or {}).get("title") or payload.get("record_title") or translate("domain:entity.record", locale) title = _t(locale, f"events.record_{action}", title=record_title) summary = _t( locale, "events.record_summary", type=_name((record or {}).get("record_type") or payload.get("record_type"), locale), status=_name((record or {}).get("review_status"), locale), ) details.extend( _fields( _field( _t(locale, "fields.record_type"), (record or {}).get("record_type") or payload.get("record_type"), "status", ), _field(_t(locale, "fields.review_status"), (record or {}).get("review_status"), "status"), _field(_t(locale, "fields.visibility"), (record or {}).get("visibility"), "status"), ) ) links.extend( _links( _link(_t(locale, "links.open_record"), target_type="record", target_id=str(record_id) if record_id else None), _link(treatment_label, target_type="treatment", target_id=str(treatment_id) if treatment_id else None), ) ) elif event_type == "recommendation_shared": category, importance, tone = "governance", "milestone", "processing" title = _t(locale, "events.recommendation_shared") record_title = (record or {}).get("title") or payload.get("record_title") or _t(locale, "events.recommendation") summary = _t(locale, "events.recommendation_shared_summary", record=record_title, treatment=treatment_label) details.extend( _fields( _field(_t(locale, "fields.treatment"), treatment_label), _field(_t(locale, "fields.record"), record_title), _field(_t(locale, "fields.visibility"), (record or {}).get("visibility"), "status"), _field(_t(locale, "fields.review_status"), (record or {}).get("review_status"), "status"), ) ) links.extend( _links( _link(_t(locale, "links.open_treatment"), target_type="treatment", target_id=str(treatment_id) if treatment_id else None), _link(_t(locale, "links.open_recommendation"), target_type="record", target_id=str(record_id) if record_id else None), ) ) elif event_type == "treatment_created": category, importance, tone = "governance", "milestone", "processing" title = _t(locale, "events.treatment_started") summary = _t(locale, "events.treatment_started_summary", treatment=treatment_label, count=payload.get("linked_finding_count") or 0) details.extend( _fields( _field(_t(locale, "fields.treatment"), treatment_label), _field(_t(locale, "fields.objective"), (treatment or {}).get("objective")), _field(_t(locale, "fields.success_criteria"), (treatment or {}).get("success_criteria")), _field(_t(locale, "fields.owner"), (treatment or {}).get("owner") or translate("common:state.unassigned", locale)), _field(_t(locale, "fields.linked_findings"), payload.get("linked_finding_count") or 0, "number"), ) ) links.extend( _links( _link(_t(locale, "links.open_treatment"), target_type="treatment", target_id=str(treatment_id) if treatment_id else None) ) ) elif event_type == "treatment_milestone": category, importance, tone = "governance", "milestone", "processing" stage = str(payload.get("stage") or "assessment") stage_key = stage if stage in {"assessment", "planning", "alignment", "execution", "observation"} else "default" title = _t(locale, f"events.treatment_stage.{stage_key}", stage=_name(stage, locale)) summary = _t(locale, "events.treatment_stage_summary", treatment=treatment_label, stage=_name(stage, locale)) details.extend( _fields( _field(_t(locale, "fields.treatment"), treatment_label), _field(_t(locale, "fields.stage"), stage, "status"), _field(_t(locale, "fields.assignee"), (treatment or {}).get("assignee") or translate("common:state.unassigned", locale)), ) ) links.extend( _links( _link(_t(locale, "links.open_treatment"), target_type="treatment", target_id=str(treatment_id) if treatment_id else None) ) ) elif event_type == "observation_started": category, importance, tone = "governance", "milestone", "signal" title = _t(locale, "events.observation_started") summary = _t(locale, "events.observation_started_summary", treatment=treatment_label) details.extend( _fields( _field(_t(locale, "fields.treatment"), treatment_label), _field(_t(locale, "fields.observation_due"), payload.get("due_at"), "date"), _field(_t(locale, "fields.evidence_record"), (record or {}).get("title")), ) ) links.extend( _links( _link(_t(locale, "links.open_treatment"), target_type="treatment", target_id=str(treatment_id) if treatment_id else None), _link(_t(locale, "links.open_observation_record"), target_type="record", target_id=str(record_id) if record_id else None), ) ) elif event_type in {"treatment_completed", "treatment_cancelled"}: category, importance = "governance", "milestone" outcome = str(payload.get("outcome") or (treatment or {}).get("outcome") or "completed") tone = ( "success" if outcome in {"fixed", "improved"} else "danger" if outcome == "failed" else "neutral" ) title = ( _t(locale, "events.treatment_completed", outcome=_name(outcome, locale)) if event_type == "treatment_completed" else _t(locale, "events.treatment_cancelled") ) summary = _t(locale, "events.treatment_terminal_summary", treatment=treatment_label) outcome_record_id = (treatment or {}).get("outcome_record_id") outcome_record = records.get(str(outcome_record_id)) if outcome_record_id else None details.extend( _fields( _field(_t(locale, "fields.treatment"), treatment_label), _field(_t(locale, "fields.outcome"), outcome, "status"), _field(_t(locale, "fields.outcome_record"), (outcome_record or {}).get("title")), ) ) links.extend( _links( _link(_t(locale, "links.open_treatment"), target_type="treatment", target_id=str(treatment_id) if treatment_id else None), _link(_t(locale, "links.open_outcome_record"), target_type="record", target_id=str(outcome_record_id) if outcome_record_id else None), ) ) elif event_type == "treatment_reopened": category, importance, tone = "governance", "warning", "processing" title = _t(locale, "events.treatment_reopened") summary = _t(locale, "events.treatment_reopened_summary", treatment=treatment_label, stage=_name(payload.get("stage"), locale)) details.extend( _fields( _field(_t(locale, "fields.previous_outcome"), payload.get("from_outcome"), "status"), _field(_t(locale, "fields.restart_stage"), payload.get("stage"), "status"), ) ) links.extend( _links( _link(_t(locale, "links.open_treatment"), target_type="treatment", target_id=str(treatment_id) if treatment_id else None) ) ) elif event_type in {"findings_deleted", "findings_restored"}: title = _t(locale, "events.finding_data_corrected") action = "deleted" if event_type == "findings_deleted" else "restored" summary = _t(locale, f"events.findings_{action}") details.extend( _fields( _field(_t(locale, "fields.action"), action, "status"), _field(_t(locale, "fields.reason"), payload.get("reason")), _field(_t(locale, "fields.deletion"), payload.get("deletion_id"), "code"), ) ) else: scalar_fields = [] for key, value in payload.items(): if key in {"before", "after"} or isinstance(value, (dict, list)): continue scalar_fields.append( _field(_name(key, locale), value, "code" if key.endswith("_id") else "text") ) details.extend(_fields(*scalar_fields[:6])) return { "id": event["id"], "category": category, "event_type": event_type, "importance": importance, "tone": tone, "title": title, "summary": summary, "occurred_at": event.get("created_at"), "started_at": None, "actor": event.get("actor"), "severity": None, "count": None, "details": details, "links": links, "children": [], "children_total": 0, "_treatment_id": str(treatment_id) if treatment_id else None, "_sequence": event.get("sequence") or 0, } def _duration_label( started_at: str | None, ended_at: str | None, locale: str = DEFAULT_LOCALE, ) -> str | None: if not started_at or not ended_at: return None seconds = max(0, (_datetime(ended_at) - _datetime(started_at)).total_seconds()) if seconds < 3600: return _t(locale, "duration.minutes", count=max(1, round(seconds / 60))) if seconds < 86400: return _t(locale, "duration.hours", count=max(1, round(seconds / 3600))) days = seconds / 86400 return _t(locale, "duration.days", count=f"{days:.1f}" if days < 10 else round(days)) def _treatment_journey_entry( treatment_id: str, entries: list[dict[str, Any]], treatment: dict[str, Any] | None, locale: str = DEFAULT_LOCALE, ) -> dict[str, Any]: ordered = sorted( entries, key=lambda entry: ( _datetime(entry.get("occurred_at")), int(entry.get("_sequence") or 0), ), ) started_at = ordered[0].get("occurred_at") occurred_at = ordered[-1].get("occurred_at") state = str((treatment or {}).get("state") or "active") stage = str((treatment or {}).get("stage") or "assessment") outcome = (treatment or {}).get("outcome") record_count = sum(1 for entry in ordered if entry.get("category") == "record") event_count = len(ordered) duration = _duration_label(started_at, occurred_at, locale) or _t(locale, "duration.governance_cycle") if state == "completed": tone = "success" if outcome in {"fixed", "improved"} else "neutral" summary = _t(locale, "journey.completed", outcome=_name(outcome, locale), duration=duration) elif state == "cancelled": tone = "danger" if outcome == "failed" else "neutral" summary = _t(locale, "journey.cancelled", stage=_name(stage, locale), duration=duration) else: tone = "processing" summary = _t(locale, "journey.active", stage=_name(stage, locale), count=event_count) children = [] for entry in ordered: details = [ field for field in entry.get("details", []) if field.get("label") not in { _t(locale, "fields.event"), _t(locale, "fields.treatment"), } ] links = [ link for link in entry.get("links", []) if link.get("target_type") != "treatment" ] children.append( { "id": entry["id"], "category": entry.get("category"), "event_type": entry.get("event_type"), "tone": entry.get("tone"), "title": entry.get("title"), "summary": entry.get("summary"), "occurred_at": entry.get("occurred_at"), "actor": entry.get("actor"), "severity": entry.get("severity"), "details": details, "links": links, } ) treatment_label = _treatment_label(treatment, treatment_id, locale) return { "id": f"treatment_journey:{treatment_id}", "category": "governance", "event_type": "treatment_journey", "importance": "milestone", "tone": tone, "title": treatment_label, "summary": summary, "occurred_at": occurred_at, "started_at": started_at, "actor": (treatment or {}).get("owner"), "severity": None, "count": event_count, "details": _fields( _field(_t(locale, "fields.state"), state, "status"), _field(_t(locale, "fields.current_stage"), stage, "status"), _field(_t(locale, "fields.outcome"), outcome, "status"), _field(_t(locale, "fields.objective"), (treatment or {}).get("objective")), _field(_t(locale, "fields.success_criteria"), (treatment or {}).get("success_criteria")), _field(_t(locale, "fields.owner"), (treatment or {}).get("owner") or translate("common:state.unassigned", locale)), _field(_t(locale, "fields.assignee"), (treatment or {}).get("assignee") or translate("common:state.unassigned", locale)), _field(_t(locale, "fields.duration"), _duration_label(started_at, occurred_at, locale)), _field(_t(locale, "fields.lifecycle_events"), event_count, "number"), _field(_t(locale, "fields.records"), record_count, "number"), ), "links": _links( _link(_t(locale, "links.open_treatment"), target_type="treatment", target_id=treatment_id) ), "children": children, "children_total": len(children), "_sequence": max(int(entry.get("_sequence") or 0) for entry in ordered), } def _group_treatment_journeys( entries: list[dict[str, Any]], treatments: dict[str, dict[str, Any]], locale: str = DEFAULT_LOCALE, ) -> list[dict[str, Any]]: standalone: list[dict[str, Any]] = [] grouped: dict[str, list[dict[str, Any]]] = defaultdict(list) for entry in entries: treatment_id = entry.get("_treatment_id") if treatment_id and entry.get("event_type") in TREATMENT_JOURNEY_EVENT_TYPES: grouped[str(treatment_id)].append(entry) else: entry.pop("_treatment_id", None) standalone.append(entry) for treatment_id, journey_entries in grouped.items(): standalone.append( _treatment_journey_entry( treatment_id, journey_entries, treatments.get(treatment_id), locale, ) ) return standalone def project_catalog_timeline( events: list[dict[str, Any]], findings: list[dict[str, Any]], records: list[dict[str, Any]], treatments: list[dict[str, Any]], catalog_item: dict[str, Any] | None = None, locale: str = DEFAULT_LOCALE, ) -> tuple[list[dict[str, Any]], dict[str, Any]]: """Project raw audit events into the Catalog's user-facing longitudinal history.""" finding_map = {finding["id"]: finding for finding in findings} record_map = {record["id"]: record for record in records} treatment_map = {treatment["id"]: treatment for treatment in treatments} first_finding = min( findings, key=lambda finding: _datetime(finding.get("observed_at") or finding.get("created_at")), default=None, ) shared_record_events = { (_dict(event.get("payload")).get("record_id"), event.get("created_at")) for event in events if event.get("event_type") == "recommendation_shared" } projected = _signal_entries(findings, locale) event_entries: list[dict[str, Any]] = [] for event in events: event_type = event.get("event_type") if event_type == "finding_ingested": continue payload = _dict(event.get("payload")) if ( event_type in {"record_created", "record_updated", "treatment_record_created"} and (payload.get("record_id"), event.get("created_at")) in shared_record_events ): continue entry = _event_entry( event, findings=finding_map, records=record_map, treatments=treatment_map, first_finding=first_finding, locale=locale, ) if event_type == "catalog_item_created" and catalog_item: entry["occurred_at"] = catalog_item.get("created_at") or entry["occurred_at"] event_entries.append(entry) projected.extend(_group_treatment_journeys(event_entries, treatment_map, locale)) projected.sort( key=lambda entry: ( _datetime(entry.get("occurred_at")), int(entry.get("_sequence") or 0), ), reverse=True, ) for entry in projected: entry.pop("_treatment_id", None) entry.pop("_sequence", None) category_counts: dict[str, int] = defaultdict(int) for entry in projected: category_counts[entry["category"]] += 1 return projected, { "entry_count": len(projected), "highlight_count": sum(1 for entry in projected if entry["category"] != "system"), "raw_event_count": len(events), "finding_count": len(findings), "signal_episode_count": sum( 1 for entry in projected if entry["event_type"] == "finding_signal_episode" ), "treatment_journey_count": sum( 1 for entry in projected if entry["event_type"] == "treatment_journey" ), "category_counts": dict(category_counts), }