import type { Activity } from "@/types"; /** * The minimum an activity event must carry to be routable. Centralizing * this here means callers can pass an `Activity` (full feed row) or a * narrower shape (e.g. a future "activity event" peek payload) — both * satisfy the kind + entity-id fields the helper inspects. * * - `claimId` / `remittanceId` come from the backend `ActivityEvent` * ORM columns (SP21 Task 2.5). `claimId` is set on `claim_*` events; * `remittanceId` is set on `remit_received`. * - `npi` is the existing `Activity.npi` field. For `provider_added` * events the provider NPI IS the entity id (the URL target). */ export type RoutableEvent = Pick< Activity, "kind" | "claimId" | "remittanceId" | "npi" >; /** * Maps an activity event to the URL the operator should land on when * clicking the event. Used by: * * - Dashboard "Recent activity" card (this PR, Task 2.5). * - `/activity` log page (Task 2.5 wired here; full integration is * a later task). * * Returns `null` for kinds that don't have a drill target yet, or * when the entity id field is missing on the event. Callers are * expected to surface a "coming soon" toast in that case so the click * still gives feedback. */ export function eventKindToUrl(event: RoutableEvent): string | null { switch (event.kind) { case "claim_submitted": case "claim_paid": case "claim_denied": case "claim_accepted": { if (!event.claimId) return null; return `/claims?claim=${encodeURIComponent(event.claimId)}`; } case "remit_received": // Phase 4 — the `RemitDrawer` isn't built yet; the helper stays // honest and returns null so the caller's "coming soon" toast // fires. When the drawer lands, the route becomes // `/remittances?remit=${encodeURIComponent(event.remittanceId ?? "")}`. return null; case "provider_added": { if (!event.npi) return null; return `/providers?provider=${encodeURIComponent(event.npi)}`; } default: return null; } }