feat: Review page — batch confirm/reject categorizations by confidence#16
Conversation
Agent-Logs-Url: https://github.com/plures/pares-modulus/sessions/c38f42c4-dd8e-49ab-b3a3-fd6c2a362129 Co-authored-by: kayodebristol <3579196+kayodebristol@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds the missing Review.svelte page for the financial-advisor plugin, enabling users to review and batch-confirm or correct low-confidence category inferences already produced/stored in fa-transaction-inferences.
Changes:
- Introduces an unconfirmed-only review queue sorted by confidence (lowest first), with rule-strategy filtering.
- Adds batch confirm flow (multi-select + select-all) that writes
userConfirmed: trueback to the inferences collection. - Adds per-row reject/correct dialog that overwrites the inference with a user-sourced, confidence-1.0 correction and supports decision-chain expansion.
| if (!infCollection || !ctx || selectedIds.size === 0) return; | ||
| batchConfirming = true; | ||
| const now = new Date().toISOString(); | ||
| const toConfirm = allInferences.filter(inf => selectedIds.has(inf.id)); |
There was a problem hiding this comment.
batchConfirm() builds toConfirm from allInferences.filter(inf => selectedIds.has(inf.id)). Because selectedIds can include items not currently visible under the active filterStrategy, clicking “Confirm N Selected” can end up confirming hidden rows (and the “N” shown is selectedIds.size, not the visible selection count). Consider either clearing selectedIds when filterStrategy changes, or deriving a selectedVisibleIds set from unconfirmedRows and using that both for the button count and for toConfirm.
| const toConfirm = allInferences.filter(inf => selectedIds.has(inf.id)); | |
| const toConfirm = unconfirmedRows | |
| .filter(row => selectedIds.has(row.inf.id)) | |
| .map(row => row.inf); |
| FA_TRANSACTIONS_COLLECTION, | ||
| FA_INFERENCES_COLLECTION, | ||
| confidenceLevel, | ||
| generateInferenceId, |
There was a problem hiding this comment.
generateInferenceId is imported but never used in this component. Removing unused imports keeps the file easier to maintain and avoids confusion about intended behavior.
| generateInferenceId, |
| // ── Derived: inference map keyed by transactionId ──────────────────────── | ||
| const inferenceMap = $derived( | ||
| new Map<string, TransactionInference>( | ||
| allInferences | ||
| .filter(inf => inf.field === 'category') | ||
| .map(inf => [inf.transactionId, inf]), | ||
| ), | ||
| ); | ||
|
|
There was a problem hiding this comment.
inferenceMap is defined but not referenced anywhere in this page. If it’s leftover from copying Transactions.svelte, it should be removed; if it’s intended to be used, wire it into the row building logic to avoid dead derived state.
| // ── Derived: inference map keyed by transactionId ──────────────────────── | |
| const inferenceMap = $derived( | |
| new Map<string, TransactionInference>( | |
| allInferences | |
| .filter(inf => inf.field === 'category') | |
| .map(inf => [inf.transactionId, inf]), | |
| ), | |
| ); |
kayodebristol
left a comment
There was a problem hiding this comment.
Auto-approved: CI green + code review complete.
Implements the missing
Review.sveltecomponent for the financial-advisor plugin. The route was already registered inindex.tsbut the component file did not exist.What's in the page
userConfirmed === falsecategory inferences, sorted by confidence ascending (lowest certainty first)fa-recurring-amount,fa-vendor-clustering,fa-refund-detection,fa-tax-variance)userConfirmed: trueto each inference viainfCollection.put()with optimistic local state updatesourceId: 'user',confidence: 1.0,userConfirmed: truectx.inference.getDecisionChain(inf.id)and renders the numbered step list alongside reasoning/rule/confidence metadataKey shape of the reject write
Styling follows the same CSS custom-property tokens and component patterns as
Transactions.svelte.