feat: unify zmail workflow targets#3
Conversation
Greptile SummaryThis PR unifies zmail workflow targets by adding durable finance ledger overrides, date-precision tracking, a shared client mutation envelope contract, and new UI primitives (DataInspector, decision decks). It also canonicalizes the
Confidence Score: 5/5Safe to merge; the two findings are non-blocking quality notes with no impact on correctness. The override apply/revert/reapply logic is well-structured, the statement-to-text migration is complete across all affected tables, and the readiness stats remain correctly year-scoped via canonical-key filtering. The unbounded ledger table scan is a future performance concern but does not produce wrong results today. db/migrations/010_finance_ledger_override_indexes.sql (redundant index) and the rawLedgerRows query in server/actions.ts (unbounded selectAll). Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[rebuildFinanceKnowledge] --> B[Build LedgerEntryDraft map]
B --> C[email transactions loop]
B --> D[import rows loop]
C --> E[classifyLedgerDate / dateRecovery]
D --> E
E --> F[addOrMerge into entries map]
F --> G[reapplyActiveFinanceLedgerOverrides]
G --> H{Active overrides in DB?}
H -- yes --> I[dbPatch + mergeMetadata]
I --> J[Object.assign entry]
H -- no --> K[skip]
J --> L[bulk upsert finance_ledger_entries]
K --> L
M[applyFinanceLedgerOverride] --> N[dbPatch + mergeMetadata]
N --> O[supersede old override]
O --> P[insert new override]
P --> Q[update ledger entry]
Q --> R{affectsRollups?}
R -- yes --> S[queue rebuild_finance_rollups]
R -- no --> T[done]
S --> T
U[revertFinanceLedgerOverride] --> V[mark override reverted]
V --> W[queue rebuild_finance_knowledge + rollups]
Prompt To Fix All With AIFix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
db/migrations/010_finance_ledger_override_indexes.sql:1-3
**Duplicate index already created by migration 009**
Migration 009 already contains an identical `CREATE INDEX IF NOT EXISTS finance_ledger_entry_overrides_status_updated_idx` statement on the same table with the same partial filter. Migration 010 is therefore a complete no-op after 009 runs. If 010 was intended to add the index retroactively to databases that ran an earlier version of 009 (before the index was part of it), that scenario can't occur since both migrations ship in the same PR.
### Issue 2 of 2
server/actions.ts:1535
**Unbounded full-table scan loads all columns including large JSON blobs on every finance page view**
`db.selectFrom("finance_ledger_entries").selectAll().execute()` has no `WHERE`, no `LIMIT`, and fetches every column — including `raw_payload_json`, `field_confidence_json`, and `ledger_metadata_json` — for every row in the table. As the ledger grows (multiple years × thousands of transactions), this will load potentially tens of megabytes of JSON on every `loadFinanceData` call. Consider selecting only the columns that `summarizeExportReadiness` and `buildFinanceDrilldown` actually consume, or scoping the query to the rows already in `filteredCanonicalKeys`.
Reviews (4): Last reviewed commit: "feat: migrate operator UI to SvelteKit" | Re-trigger Greptile |
Replace the Hono JSX/browser partial stack with SvelteKit page rendering and Hono-owned API/auth/WebSocket routes. Add the client mutation invalidation contract, WebSocket realtime protocol, SvelteKit route skeleton, and updated docs/tests for the clean-break target.
Summary
Test plan