perf(db): logs-list index, drop redundant indexes, replica routing, hot-path write cleanups#5105
Conversation
…ot-path write cleanups
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Mark chat read now updates Unit tests cover the unread guard on mothership chat read and the atomic webhook config merge. Reviewed by Cursor Bugbot for commit d763062. Configure here. |
Greptile SummaryThis PR delivers a focused set of database performance improvements: a new DESC composite index for the logs-list cursor query, removal of three redundant prefix indexes, and replica routing for the two admin read-only list endpoints. Two hot-path write operations are also tightened —
Confidence Score: 5/5Safe to merge. All changes are additive or eliminate races; the migration is online-safe and idempotent; no auth boundary is weakened. The admin replica routing is sound — No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Incoming Request] --> B{Route}
B --> C["POST /api/v1/admin/organizations"]
B --> D["GET /api/v1/admin/organizations\nGET /api/v1/admin/audit-logs"]
B --> E["POST /api/mothership/chats/read"]
B --> F["Webhook polling\nupdateWebhookProviderConfig"]
C --> G["withAdminAuth\nsafeCompare header vs env\nno DB query"]
D --> G
G -->|authenticated| H["Primary db — POST writes"]
G -->|authenticated| I["dbReplica — GET list queries\nno permission join"]
E --> J{isAuthenticated?}
J -->|no| K["401 Unauthorized"]
J -->|yes| L{"lastSeenAt IS NULL\nOR lastSeenAt < updatedAt?"}
L -->|no — already read| M["200 no-op — no DB write"]
L -->|yes — unread| N["UPDATE lastSeenAt\nPrimary db"]
F --> O{"any undefined keys\nin configUpdates?"}
O -->|no| P["COALESCE merge only\nSingle atomic UPDATE"]
O -->|yes| Q["COALESCE merge\nminus removedKeys\nSingle atomic UPDATE"]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[Incoming Request] --> B{Route}
B --> C["POST /api/v1/admin/organizations"]
B --> D["GET /api/v1/admin/organizations\nGET /api/v1/admin/audit-logs"]
B --> E["POST /api/mothership/chats/read"]
B --> F["Webhook polling\nupdateWebhookProviderConfig"]
C --> G["withAdminAuth\nsafeCompare header vs env\nno DB query"]
D --> G
G -->|authenticated| H["Primary db — POST writes"]
G -->|authenticated| I["dbReplica — GET list queries\nno permission join"]
E --> J{isAuthenticated?}
J -->|no| K["401 Unauthorized"]
J -->|yes| L{"lastSeenAt IS NULL\nOR lastSeenAt < updatedAt?"}
L -->|no — already read| M["200 no-op — no DB write"]
L -->|yes — unread| N["UPDATE lastSeenAt\nPrimary db"]
F --> O{"any undefined keys\nin configUpdates?"}
O -->|no| P["COALESCE merge only\nSingle atomic UPDATE"]
O -->|yes| Q["COALESCE merge\nminus removedKeys\nSingle atomic UPDATE"]
Reviews (3): Last reviewed commit: "fix(logs): keep /api/v1/logs on primary ..." | Re-trigger Greptile |
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 2b541ce. Configure here.
…the auth gate, not replica-safe
|
Thanks — addressed the auth-on-replica concern at the source rather than waving it off.
The two routes still on @greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit d763062. Configure here.
Summary
workflow_execution_logs (workspace_id, started_at DESC NULLS LAST, id DESC)index so the logs-list cursor query (WHERE workspace_id = ? ORDER BY started_at DESC, id DESC LIMIT n) runs as an index-only scan with LIMIT early-exit instead of a sort. The existing(workspace_id, started_at)index is kept — it still serves the ascending/range log queries the new DESC index does not cover.permission_group_workspace_group_id_idx,user_table_rows_table_id_idx,workspace_byok_workspace_idx./api/v1/logs, admin audit-logs, admin organizations (GET only — POST stays on the primary).updateWebhookProviderConfiga single atomicjsonbmerge instead of SELECT-then-UPDATE (preserves the shallow-merge plus null/undefined semantics exactly).copilot_chats.last_seen_atwhen the chat is actually unread, avoiding per-read rewrites of the same row.getFileMetadataByContext.Type of Change
Testing
last_seen_atunread guard and the webhook atomic merge.bun run check:api-validationpasses; biome clean.CREATE/DROP INDEX CONCURRENTLY(replay-safe). Recommend applying on a non-prod branch first and watching the dropped indexes' query latency during rollout.Checklist