collectionGroup alert_events (acknowledged, org_id, triggered_at desc) — the index the /watch Triggered Alerts tab and the site-wide useUnacknowledgedAlerts hook require. Still needs a manual deploy; no automation exists (#51). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Tbknwttzou4s46PAykmtix
92 lines
5.5 KiB
JSON
92 lines
5.5 KiB
JSON
{
|
|
"//": "Composite indexes for the c2-server database. Firestore auto-indexes single-field lookups and equality-only compound queries; an equality filter combined with an inequality, an orderBy on a different field, or array-contains needs an explicit composite index or the query fails at runtime with FAILED_PRECONDITION. Deploy with: firebase deploy --only firestore:indexes --project <project-id> (firebase.json pins database c2-server — without that key the CLI targets (default) and changes nothing the app can see).",
|
|
"//direction": "Every index here is declared ASCENDING. Firestore scans an index in either direction, so org_id+started_at ASC serves orderBy(started_at, 'desc') as well — which is what every frontend hook actually asks for. Declaring only the ASC form keeps one index per query shape instead of a matched pair.",
|
|
"//drift-2026-08-23": "Reconciled against `gcloud firestore indexes composite list --database=c2-server` (server-26#33). The file had drifted four indexes behind the live database, and a deploy against the stale file then added ASC copies of indexes that already existed as DESC. The next deploy will offer to delete three live indexes that are deliberately not declared here — answer YES to all three: calls(org_id ASC, started_at DESC) and incidents(org_id ASC, started_at DESC) are duplicates of the ASC entries below, and alert_events(acknowledged ASC, triggered_at DESC) predates tenancy and is superseded by the org-scoped entry below. Nothing else may be deleted.",
|
|
"indexes": [
|
|
{
|
|
"//": "drb-frontend lib/useCalls.ts — org-scoped call list, orderBy started_at desc.",
|
|
"collectionGroup": "calls",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "org_id", "order": "ASCENDING" },
|
|
{ "fieldPath": "started_at", "order": "ASCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"//": "drb-frontend lib/useCalls.ts — the calls attached to one incident.",
|
|
"collectionGroup": "calls",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "org_id", "order": "ASCENDING" },
|
|
{ "fieldPath": "incident_ids", "arrayConfig": "CONTAINS" }
|
|
]
|
|
},
|
|
{
|
|
"//": "c2-core internal/recorrelation_sweep.py:45 — status == 'ended' AND ended_at >= cutoff. Backend only; was live but undeclared until 2026-08-23.",
|
|
"collectionGroup": "calls",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "status", "order": "ASCENDING" },
|
|
{ "fieldPath": "ended_at", "order": "ASCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"//": "c2-core internal/dedup.py:84 — system_id == X AND started_at within a +/- window. Was live-failing on essentially every inbound call (server-26#84): dedup caught the FAILED_PRECONDITION and degraded to \"not a duplicate\", so double-heard transmissions were stored twice and would have been transcribed and correlated twice the moment an AI window opened. Created directly on c2-server 2026-08-28.",
|
|
"collectionGroup": "calls",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "system_id", "order": "ASCENDING" },
|
|
{ "fieldPath": "started_at", "order": "ASCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"//": "c2-core internal/vocabulary_learner.py:290 — system_id == X AND ended_at >= cutoff. Backend only; was live but undeclared until 2026-08-23.",
|
|
"collectionGroup": "calls",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "system_id", "order": "ASCENDING" },
|
|
{ "fieldPath": "ended_at", "order": "ASCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"//": "drb-frontend lib/useIncidents.ts — org-scoped incident browse, orderBy started_at desc.",
|
|
"collectionGroup": "incidents",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "org_id", "order": "ASCENDING" },
|
|
{ "fieldPath": "started_at", "order": "ASCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"//": "drb-frontend lib/useAlerts.ts — org-scoped alert feed, orderBy triggered_at desc.",
|
|
"collectionGroup": "alert_events",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "org_id", "order": "ASCENDING" },
|
|
{ "fieldPath": "triggered_at", "order": "ASCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"//": "drb-frontend lib/useAlerts.ts useUnacknowledgedAlerts — the nav badge.",
|
|
"collectionGroup": "alert_events",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "org_id", "order": "ASCENDING" },
|
|
{ "fieldPath": "acknowledged", "order": "ASCENDING" },
|
|
{ "fieldPath": "triggered_at", "order": "ASCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"//": "drb-frontend lib/useAlerts.ts useUnacknowledgedAlerts (nav badge) and the /watch \"Triggered Alerts\" tab — where(org_id ==) where(acknowledged == false) orderBy(triggered_at desc). Threw \"the query requires an index\" on every page until this was declared (server-26#51). Field tuple and triggered_at DESCENDING copy the console create_composite link in that issue verbatim, so a gcloud/console create and a firebase deploy converge on one index rather than the ASC-vs-DESC pair that caused server-26#33. Distinct from the (org_id, triggered_at) alert-feed index above (no acknowledged filter) and supersedes the pre-tenancy live alert_events(acknowledged, triggered_at) index #33 says to delete.",
|
|
"collectionGroup": "alert_events",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "acknowledged", "order": "ASCENDING" },
|
|
{ "fieldPath": "org_id", "order": "ASCENDING" },
|
|
{ "fieldPath": "triggered_at", "order": "DESCENDING" }
|
|
]
|
|
}
|
|
],
|
|
"fieldOverrides": []
|
|
}
|