Skip to content

fix(cleanup): address PR #10 CodeRabbit review findings#13

Merged
notedwin-dev merged 2 commits into
stagingfrom
bugfix/pr10-coderabbit-cleanup
Jun 5, 2026
Merged

fix(cleanup): address PR #10 CodeRabbit review findings#13
notedwin-dev merged 2 commits into
stagingfrom
bugfix/pr10-coderabbit-cleanup

Conversation

@notedwin-dev
Copy link
Copy Markdown
Owner

@notedwin-dev notedwin-dev commented Jun 5, 2026

Addresses remaining CodeRabbit comments on the staging→main PR (PR #10) before it can merge to main.

Persistence order + field naming

  • src/lib/application/commands/accounts.ts: opening + adjustment transactions built in a single newTxs[] array, persisted via saveTransactions BEFORE saveAccounts, stores updated only after both persists succeed
  • src/lib/application/commands/transactions.ts: sharedFields corrected to note (was notes plural)

Domain correctness

  • src/lib/domain/balance.engine.ts: computeBudgetConsumption and computeSavingsMovement now return empty maps for t.isHistorical, matching the existing computeAccountTransactionAmount pattern
  • src/lib/domain/balance.engine.ts: replaces implicit date coercion with explicit parseDateSafe + normalizeDate from new src/lib/domain/dates.ts

Input sanitization

  • components/AccountForm.tsx: sanitizeNote hardened to match digit/separator runs and redact only when 13–19 digits remain after stripping non-digits; CVV/CVC redaction preserved

Subagent permissions

  • opencode.json: 3 subagent bash settings changed from allow to deny for state-migrator, commands-splitter, page-migrator

Test hygiene

  • src/lib/application/commands/__tests__/sync.test.ts: static import of resetAndSync, vi.unstubAllGlobals() in afterEach
  • src/lib/domain/__tests__/migration.test.ts: fix mismatched returns true description (assertion expects false) for empty biometricCredIds case
  • crypto.test.ts: moved to services/__tests__/ to co-locate with crypto.services.ts; vite.config.ts include extended to pick up services/**/*.test.{ts,tsx}

Docs

  • docs/adrs/001-layered-architecture-refactor.md + docs/adrs/002-drop-vault-data-minimization.md: reordered to Context → Decision → Consequences → Status (Status moved to end)
  • docs/PLAN.md: fence blocks tagged with language hints; vault commands replaced with mask-mode guidance (Phase 4 row + Commit 14)

Misc

  • components/GoogleDrivePicker.tsx: maskFileId extracted to module scope (was duplicated in 2 components)
  • src/lib/application/commands/transactions.ts: removed 8 inline section comments
  • src/lib/application/commands/migration.ts: removed redundant temp-migration note (already in CONTEXT.md line 60)
  • layouts/MainLayout.tsx: desktop Mask Mode toggle now has type="button" (mobile already did)

Skipped findings

  • sync.ts loadData: _forceUnlock already uses underscore prefix (intentionally unused, preserved for AccountPage caller)

Validated: npx tsc --noEmit clean, npm test 14 files / 153 tests pass

Diff: 16 files changed, 73 insertions(+), 71 deletions(-)

Summary by CodeRabbit

  • New Features

    • Enhanced redaction of sensitive numeric sequences in account forms
  • Bug Fixes

    • Fixed Mask Mode toggle buttons to prevent accidental form submissions
    • Improved balance calculations for historical transactions
  • Documentation

    • Updated architecture migration planning and decision documentation
  • Chores

    • Tightened security permissions for automation agents
    • Refactored code organization and expanded test coverage scope

Addresses remaining CodeRabbit comments on the staging→main PR.

Persistence order + field naming:
- accounts.ts: build opening + adjustment txs in a single newTxs[]
  array, persist via saveTransactions BEFORE saveAccounts, update
  stores only after both persists succeed
- transactions.ts: sharedFields corrected to 'note' (was 'notes')

Domain correctness:
- balance.engine.ts: computeBudgetConsumption and computeSavingsMovement
  now return empty maps for t.isHistorical, matching the existing
  computeAccountTransactionAmount pattern
- balance.engine.ts: replaces implicit date coercion with explicit
  parseDateSafe + normalizeDate from new src/lib/domain/dates.ts

Input sanitization:
- AccountForm.tsx: sanitizeNote hardened to match digit/separator
  runs and redact only when 13-19 digits remain after stripping
  non-digits; CVV/CVC redaction preserved

Subagent permissions:
- opencode.json: 3 subagent 'bash' settings changed from 'allow' to
  'deny' for state-migrator, commands-splitter, page-migrator

Test hygiene:
- sync.test.ts: static import of resetAndSync, vi.unstubAllGlobals()
  in afterEach
- migration.test.ts: fix mismatched 'returns true' description
  (assertion expects false) for empty biometricCredIds case
- crypto.test.ts: moved to services/__tests__/ to co-locate with
  crypto.services.ts; vite.config.ts include extended to pick up
  services/**/*.test.{ts,tsx}

Docs:
- adrs/001 + adrs/002: reordered to Context → Decision → Consequences
  → Status (Status moved to end)
- PLAN.md: fence blocks tagged with language hints; vault commands
  replaced with mask-mode guidance (Phase 4 row + Commit 14)

Misc:
- GoogleDrivePicker.tsx: maskFileId extracted to module scope
  (was duplicated in 2 components)
- transactions.ts: removed 8 inline section comments
- migration.ts: removed redundant temp-migration note (already in
  CONTEXT.md line 60)
- MainLayout.tsx: desktop Mask Mode toggle now has type='button'
  (mobile already did)

Skipped findings:
- sync.ts loadData: _forceUnlock already uses underscore prefix
  (intentionally unused, preserved for AccountPage caller)

Validated: npx tsc --noEmit clean, npm test 14 files / 153 tests pass
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
finance-tracker-app Ready Ready Preview, Comment Jun 5, 2026 7:31pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 5, 2026

Need the big picture first? Review this PR in Change Stack to see what changed before going file by file.

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ad34a964-9f08-433c-8e57-0eee51e744b3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR consolidates incremental progress toward the layered architecture migration. It introduces date utilities, batches transaction persistence in account commands, refines transaction field handling, improves component masking and form behavior, updates test infrastructure for broader discovery, and restructures migration documentation with Mask Mode + Sync sequencing and tightened agent permissions.

Changes

Core refactor and feature consolidation

Layer / File(s) Summary
Date utilities and historical transaction filtering
src/lib/domain/dates.ts, src/lib/domain/balance.engine.ts
New dates.ts module exports parseDateSafe and normalizeDate for safe date parsing and en-CA formatting. balance.engine.ts imports from the new module and skips delta computation when t.isHistorical is true in both computeBudgetConsumption and computeSavingsMovement.
Transaction batching in account persistence
src/lib/application/commands/accounts.ts
saveAccount collects newly generated transactions (account-opening or balance-adjustment) into a newTxs array and defers persistence until after determining which transactions to create. Conditionally saves merged transactions and updates both stores only when new transactions exist; otherwise saves/updates accounts only.
Transaction command field fix and cleanup
src/lib/application/commands/transactions.ts, src/lib/application/commands/migration.ts
Removes inline comments from submitTransaction and batchEditTransactions. Changes shared-field list in batchEditTransactions from notes to note to correctly propagate the text field to partner legs. migration.ts removes leading temporary comment.
UI and masking improvements
components/AccountForm.tsx, components/GoogleDrivePicker.tsx, layouts/MainLayout.tsx
AccountForm.tsx refines sanitizeNote to redact 13–19 digit sequences. GoogleDrivePicker.tsx extracts maskFileId into a shared module-level helper and removes render-time environment-variable warnings. MainLayout.tsx adds type="button" to both Mask Mode toggles (desktop and mobile).
Test discovery and cleanup
vite.config.ts, services/__tests__/crypto.test.ts, src/lib/application/commands/__tests__/sync.test.ts, src/lib/domain/__tests__/migration.test.ts
vite.config.ts extends Vitest discovery to services/**. crypto.test.ts uses shorter relative import. sync.test.ts converts dynamic import to static and adds vi.unstubAllGlobals() cleanup. migration.test.ts updates assertion for empty biometric credentials.
Documentation and configuration updates
docs/PLAN.md, docs/adrs/001-layered-architecture-refactor.md, docs/adrs/002-drop-vault-data-minimization.md, opencode.json
PLAN.md restructures migration roadmap with Mask Mode + Sync phases and explicit data-flow architecture. ADRs move Status metadata to the end. opencode.json restricts bash permissions for state-migrator, commands-splitter, and page-migrator agents from "allow" to "deny".

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main purpose of the PR: addressing CodeRabbit review findings from PR #10. The changes span multiple functional areas (persistence, domain correctness, sanitization, permissions, tests, and docs), and the title captures the overarching intent as a cleanup/fix addressing prior feedback.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bugfix/pr10-coderabbit-cleanup

Comment @coderabbitai help to get the list of available commands and usage tips.

@notedwin-dev
Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 5, 2026

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/domain/__tests__/migration.test.ts (1)

301-305: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Test name conflicts with the actual profile version.

Line 301 says “v1 user”, but Line 304 sets schemaVersion: 2. Please rename the test title to avoid misleading future readers.

Suggested rename
-  it("returns false when v1 user has plain empty array for biometricCredIds (treated as absent)", () => {
+  it("returns false when v2 profile has empty biometricCredIds array (treated as absent)", () => {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/domain/__tests__/migration.test.ts` around lines 301 - 305, The test
title incorrectly refers to a "v1 user" while the profile under test is created
with schemaVersion: 2; update the test name in
src/lib/domain/__tests__/migration.test.ts to accurately reflect the profile
version (e.g., "returns false when v2 user has plain empty array for
biometricCredIds (treated as absent)"), keeping the test body using
needsV1Migration and asProfile unchanged so the assertion still verifies
behavior for asProfile({ schemaVersion: 2, biometricCredIds: [] }) calling
needsV1Migration(...).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/AccountForm.tsx`:
- Around line 41-45: The regex that detects long digit runs in AccountForm.tsx
currently uses the pattern \d[ -]?(?:\d[ -]?){12,18}\d which only matches 14–20
digit sequences and thus misses 13-digit numbers; update that quantifier to
{11,17} so the pattern becomes \d[ -]?(?:\d[ -]?){11,17}\d (this will match
13–19 digit runs) and keep the existing replacement callback that strips
non-digits and returns "[redacted]" when digits.length is between 13 and 19.

In `@src/lib/application/commands/accounts.ts`:
- Around line 63-67: The current sequence writes transactions then accounts via
StorageService.saveTransactions and StorageService.saveAccounts which can leave
durable state inconsistent if saveAccounts fails; change to an atomic approach:
either (A) add/use an atomic API (e.g., implement StorageService.saveBatch or
StorageService.saveAtomic that persists both updatedTxs and updated together in
one durable operation and call that from this code), or (B) if atomic storage
can't be added, invert and protect the sequence—persist the account snapshot
first with StorageService.saveAccounts(updated) and then persist transactions
with StorageService.saveTransactions(updatedTxs) inside a try/catch, and on
failure roll back the account write (e.g., restore previous account via
StorageService.saveAccounts(existingAccountSnapshot) or remove the
partially-written transactions via StorageService.deleteTransactions) so durable
state stays consistent; update store.setTransactions only after both durable
writes succeed.

In `@src/lib/domain/dates.ts`:
- Around line 4-7: parseDateSafe currently calls new Date(date) first (which
treats "YYYY-MM-DD" as UTC) and falls back to constructing a Date that can
silently overflow; change parseDateSafe to first detect ISO date-only strings
(/\d{4}[-/]\d{1,2}[-/]\d{1,2}/), parse y/m/d, construct a local Date via new
Date(y, m-1, d), then validate by checking constructedDate.getFullYear() === y
&& constructedDate.getMonth() === m-1 && constructedDate.getDate() === d to
reject overflowed inputs (return null on invalid); only if the input is not an
ISO date, fall back to new Date(date) and verify !isNaN(...). Keep normalizeDate
returning a stable "YYYY-MM-DD" string derived from a validated local Date so
lexical comparisons remain correct.

---

Outside diff comments:
In `@src/lib/domain/__tests__/migration.test.ts`:
- Around line 301-305: The test title incorrectly refers to a "v1 user" while
the profile under test is created with schemaVersion: 2; update the test name in
src/lib/domain/__tests__/migration.test.ts to accurately reflect the profile
version (e.g., "returns false when v2 user has plain empty array for
biometricCredIds (treated as absent)"), keeping the test body using
needsV1Migration and asProfile unchanged so the assertion still verifies
behavior for asProfile({ schemaVersion: 2, biometricCredIds: [] }) calling
needsV1Migration(...).
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5ea3e12e-210a-4202-89c6-5b3a465c04c3

📥 Commits

Reviewing files that changed from the base of the PR and between 3f81a18 and 170c54d.

📒 Files selected for processing (16)
  • components/AccountForm.tsx
  • components/GoogleDrivePicker.tsx
  • docs/PLAN.md
  • docs/adrs/001-layered-architecture-refactor.md
  • docs/adrs/002-drop-vault-data-minimization.md
  • layouts/MainLayout.tsx
  • opencode.json
  • services/__tests__/crypto.test.ts
  • src/lib/application/commands/__tests__/sync.test.ts
  • src/lib/application/commands/accounts.ts
  • src/lib/application/commands/migration.ts
  • src/lib/application/commands/transactions.ts
  • src/lib/domain/__tests__/migration.test.ts
  • src/lib/domain/balance.engine.ts
  • src/lib/domain/dates.ts
  • vite.config.ts
💤 Files with no reviewable changes (1)
  • src/lib/application/commands/migration.ts
📜 Review details
🔇 Additional comments (12)
components/GoogleDrivePicker.tsx (1)

8-10: LGTM!

layouts/MainLayout.tsx (1)

247-247: LGTM!

Also applies to: 306-306

docs/PLAN.md (1)

7-17: LGTM!

Also applies to: 36-50, 53-62, 82-82, 90-99, 102-131, 134-146, 147-159, 162-172

docs/adrs/001-layered-architecture-refactor.md (1)

268-272: LGTM!

docs/adrs/002-drop-vault-data-minimization.md (1)

51-55: LGTM!

opencode.json (1)

47-47: LGTM!

Also applies to: 66-66, 85-85

src/lib/domain/balance.engine.ts (1)

2-2: LGTM!

Also applies to: 12-13, 45-46

src/lib/application/commands/accounts.ts (1)

27-60: LGTM!

src/lib/application/commands/transactions.ts (1)

561-561: LGTM!

services/__tests__/crypto.test.ts (1)

7-7: LGTM!

vite.config.ts (1)

68-68: LGTM!

src/lib/application/commands/__tests__/sync.test.ts (1)

5-5: LGTM!

Also applies to: 97-97

Comment thread components/AccountForm.tsx
Comment thread src/lib/application/commands/accounts.ts Outdated
Comment thread src/lib/domain/dates.ts Outdated
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 5, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 3 file(s) based on 3 unresolved review comments.

Files modified:

  • components/AccountForm.tsx
  • src/lib/application/commands/accounts.ts
  • src/lib/domain/dates.ts

Commit: 5e2edc93c0f6f2a42d7ab6003733468736ac3e5f

The changes have been pushed to the bugfix/pr10-coderabbit-cleanup branch.

Time taken: 3m 0s

Fixed 3 file(s) based on 3 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@notedwin-dev notedwin-dev merged commit b85ea43 into staging Jun 5, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant