docs(qa): add improvement lens + B17/B18 batches + seeded backlog

Expand the QA plan beyond correctness to also hunt for improvements, per
three lenses woven into the execution model:
  - Code health & consolidation (B17): duplication, dead code, overlapping
    modules, oversized files, one canonical path per concern.
  - UX (B18): core-flow friction, empty/loading/error states, feedback.
  - Information architecture / menus (B18): discoverability, surfacing
    actions into sensible menus, nav grouping.

Adds an Improvement Backlog (§2.1) for IMP proposals (separate from the bug
log; non-gating), detailed B17/B18 playbooks, and batch-table rows. Seeded
the backlog with 6 concrete, code-verified candidates (client money-format
consolidation, db/database.js split, match-service overlap, Data/menu IA,
recently-deleted restore view, empty/loading/error-state audit).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
null 2026-07-03 12:23:37 -05:00
parent b3168fca70
commit cc6332731f
1 changed files with 116 additions and 0 deletions

View File

@ -76,6 +76,26 @@ no matter how tempting or trivial.
- **The exit is empirical:** you're done only when an entire find pass (B0→B15) turns up zero new findings — not when you *think* it's clean. Log the cycle result in the [Cycle Log](#11-qa-cycle-log) each time.
- Improve THIS plan whenever a pass reveals a missed surface, a better repro, or a batch that should be reordered/split.
**Improvement lens (not just bug-hunting).** QA here is also about making the product
*better*, not only *correct*. On every batch, in addition to logging bugs, actively
look through three improvement lenses and log what you find as **IMP** items in the
[Improvement Backlog (§2.1)](#21-improvement-backlog):
- **Code health & consolidation** — duplication to DRY up, dead code to delete,
overlapping modules to merge, oversized files to split, one canonical path per
concern. *Consolidate only where it genuinely reduces surface area and is
behavior-preserving.* (Dedicated pass: **B17**.)
- **User experience** — friction in core flows, unclear states (empty/loading/error),
weak feedback/affordances, inconsistent patterns, mobile parity. (Dedicated pass: **B18**.)
- **Information architecture / menus** — features that are buried or only reachable by
URL, actions that belong in a menu (nav, overflow, context, settings groupings), and
groupings that would make the app more discoverable. *Put things where a user would
look for them.* (Dedicated pass: **B18**.)
IMP items are **proposals**, not silent changes: log the candidate with a concrete
recommendation, agree the direction, then implement behind a test. They **don't block
sign-off** — but a strong QA cycle leaves the code cleaner and the UX clearer, not just
green.
---
## 1. Batch plan & progress tracker
@ -105,9 +125,14 @@ before cross-cutting; regression last). Update **Status** and **Findings** every
| B14 | Non-functional | a11y, performance, PWA/offline, XSS/secrets, timezone/DST | large + adversarial | ✅ | 0 / 4 |
| B15 | Regression & sign-off | full smoke on **production build**, exit criteria | seeded | ✅ | 0 / 0 |
| B16 | Migrations, secrets & deploy | migration idempotency/rollback/fresh==migrated, encryption-key lifecycle, `docker-entrypoint` (perms/first-run/migrate), update-check phone-home | scratch + docker | ✅ | 0 / 1 |
| B17 | **Code health & consolidation** (IMP) | duplication/DRY, dead code, overlapping modules to merge, oversized files to split, one canonical path per concern | whole repo | ⬜ | 0 / 0 |
| B18 | **UX & information architecture** (IMP) | core-flow friction, empty/loading/error states, feedback/affordances, nav/menu discoverability, surfacing actions into sensible menus | any | ⬜ | 0 / 0 |
> After B15, if any batch is 🔁 or has open S1/S2, loop back. Then start a new
> cycle from B0 against the next build/version.
>
> **B17/B18 are improvement (IMP) batches** — they run alongside the correctness
> batches but their findings are enhancements, not defects, and don't gate sign-off.
**✅ means "run complete for this cycle's automatable scope, green, findings archived."**
Cycle 1 built a durable, automated guard for every batch (`npm run ci` · `test:e2e` ·
@ -173,6 +198,29 @@ Log console errors, failed network requests, and unhandled rejections as finding
_All Cycle 1 write-ups have been archived to `HISTORY.md` v0.41.0 (see §3)._
### 2.1 Improvement backlog
**IMP-stream, separate from the bug log above.** Enhancement candidates found through
the three improvement lenses (code/consolidation, UX, IA/menus — see §0 and batches
B17/B18). These are **proposals**: log the candidate + a concrete recommendation, then
discuss before implementing. They don't gate sign-off. When one is implemented, archive
it to `HISTORY.md` (`### 🧹 QA` / `### ✨` as fits) and remove the row; deferred ideas
graduate to `roadmap.md`/`FUTURE.md`.
**ID:** `IMP-{stream}-{nn}` where stream = `CODE` (health/consolidation), `UX`, or `IA` (menus/nav).
**Effort:** S (local, <1h) · M (a file or two) · L (cross-cutting / needs design).
**Status:** 🔵 Noted (proposal) → 🟡 Doing → then archive to `HISTORY.md` on implement.
| ID | Lens | Area (`file`/page) | Proposal (what & why) | Effort | Status |
|----|------|--------------------|-----------------------|--------|--------|
| IMP-CODE-01 | Code | `client/` (~10 files, ~30 sites) | **No shared client money formatter.** Server has `utils/money.js`; the client formats currency inline with `toLocaleString`/`Intl.NumberFormat` scattered across ~10 components. Add `client/utils/money.js` `formatUSD(cents)` and migrate call sites → one consistent format (esp. negatives), single source of truth for the cents model. | M | 🔵 Noted |
| IMP-CODE-02 | Code | `db/database.js` (4,174 ln) | **Oversized module.** One file mixes the migration engine, query helpers, settings, and connection lifecycle. Split into cohesive modules (behavior-preserving, test-guarded) for navigability and lower merge-conflict risk. | L | 🔵 Noted |
| IMP-CODE-03 | Code | `services/*match*`, `bankSync*` | **Overlapping match logic.** `transactionMatchService` / `matchSuggestionService` / `merchantStoreMatchService` each write `match_status` + bill/payment links; QA-B5-04 showed how easily these drift out of sync. Extract one canonical "set/clear match" helper so state transitions live in one place. | M | 🔵 Noted |
| IMP-IA-01 | IA | Sidebar · `/data` | **Central features under an overflow menu.** Data (import/export/backups) and account pages are reachable only via the account overflow dropdown + `Ctrl+K`, not the primary nav. For how central import/export/backup is, consider a primary-nav or labeled "Manage" entry so it's easier to find. | S | 🔵 Noted |
| IMP-UX-01 | UX | Bills / Categories delete | **Retention isn't surfaced.** Soft-delete keeps records 30 days, but the only restore affordance is a transient "Undo" toast — dismiss it and a bill deleted an hour ago is unrecoverable via UI. Add a lightweight "Recently deleted / restore" view to actually leverage the retention window. | M | 🔵 Noted |
| IMP-UX-02 | UX | all list pages | **State audit.** Systematically verify every list/page has an empty-state with a CTA, a skeleton/loading state, and a recoverable error state (pair with B14 fault-injection) — no dead ends, no silent failures. | M | 🔵 Noted |
---
## 3. Archiving fixed findings to HISTORY.md
@ -501,6 +549,74 @@ secrets silently.
**Rate-limiter completeness** (`middleware/rateLimiter.js`) — beyond B13's list
- [ ] `backupOperationLimiter` throttles admin backup/restore/cleanup; `skipRateLimitIfNoUsers` only relaxes limits on a genuinely empty instance (first-run), never afterward.
### B17 — Code health & consolidation (IMP)
An **improvement** batch: hunt for ways to make the codebase smaller, clearer, and more
consistent — *without changing behavior*. Every candidate is logged as an `IMP-CODE-*`
row in §2.1 with a concrete proposal; nothing is refactored silently. Consolidation
lands only when it's behavior-preserving **and** covered by existing or added tests.
- [ ] **Duplication / DRY:** find logic copy-pasted across services/routes/components and
propose a shared helper. Known hot spots: money formatting/rounding (`utils/money.js`
vs inline), the `resolveDueDate` occurrence gate (must stay one implementation),
error-response shaping (`utils/apiError.js` vs ad-hoc), React data-fetch patterns
(repeated `useQuery` + toast + error handling → shared hooks).
- [ ] **Dead / unused code:** unused exports, unreachable branches, orphaned files,
commented-out blocks, unused deps (`depcheck`), unused UI components/CSS, leftover
scaffolding. Propose deletion (verify no dynamic/`require`-by-string use first).
- [ ] **Overlapping modules:** services that do similar work and could merge or share a
core — e.g. the matching family (`matchSuggestionService`, `transactionMatchService`,
`merchantStoreMatchService`), the bank-sync family (`bankSyncService`,
`bankSyncWorker`, `bankSyncConfigService`, `simplefinService`). Map responsibilities;
propose a consolidation only where it removes real duplication, not just moves it.
- [ ] **Oversized / low-cohesion files:** split by concern where it aids navigation
(e.g. `db/database.js` is very large — migrations vs query helpers vs settings could
be separate modules). Propose the seams; don't split for its own sake.
- [ ] **One canonical path per concern:** cents handling, date/tz, CSRF, error shape,
pagination — confirm there's a single blessed way and flag divergences.
- [ ] **Consistency:** naming, file layout, async patterns, import ordering; a lint rule
that would prevent a class of the bugs found in earlier batches is itself an IMP.
- [ ] **Test/infra dedupe:** repeated test setup → shared fixtures/helpers; flag coverage
gaps a consolidation would risk.
### B18 — UX & information architecture / menus (IMP)
An **improvement** batch focused on the person using the app: is every feature
*discoverable*, is every core flow *smooth*, and does every action live *where a user
would look for it*? Candidates are logged as `IMP-UX-*` or `IMP-IA-*` in §2.1 with a
concrete before/after proposal. Walk the app as a real user (both `user` and `admin`,
desktop and mobile, light and dark), not just as a tester.
**Information architecture & menus**
- [ ] **Discoverability:** is any feature buried, orphaned, or reachable only by typing a
URL? Everything should be reachable from the nav, a menu, or a clear in-page entry.
- [ ] **Navigation structure:** sidebar/nav grouping is logical; related pages sit
together; admin vs user separation is clear; active state + page titles are correct.
- [ ] **Menus where they belong:** actions that today are loose buttons or hidden should
be grouped into sensible menus — overflow (`⋯`) menus on rows/cards, context menus,
a consolidated **Settings** grouping, an account menu. Put related actions in one menu
rather than scattering them. Flag anything that would be easier to find as a menu item.
- [ ] **Command palette (`Ctrl+K`) coverage:** every page/primary action is reachable;
no dead entries.
- [ ] **Redundancy:** the same action offered in three places with different labels, or
two pages that do nearly the same thing — propose consolidating.
**Experience quality**
- [ ] **Core-flow friction:** count the clicks for the top tasks (pay a bill, add a bill,
connect SimpleFIN, run a sync, import data). Propose shortcuts where a step is wasted.
- [ ] **States:** every list/page has a clear **empty state with a next-step CTA**, a
**loading** state (skeleton/spinner, no layout jump), and a **recoverable error**
state — no dead ends, no silent failures.
- [ ] **Feedback & safety:** state changes confirm (toast); destructive actions confirm
and, where feasible, offer undo (bills already soft-delete — surface a restore path);
long actions show progress.
- [ ] **Consistency:** primary-action placement, button hierarchy, iconography,
terminology, and confirmation patterns are consistent across pages.
- [ ] **Mobile parity:** every action available on desktop is reachable on mobile; touch
targets adequate; menus/overflow work on touch.
- [ ] **Onboarding:** first-run and empty-account guidance explains the next step; advanced
features (SimpleFIN, debt planning, backups) have a short in-context explanation.
---
## 8. Appendices