8.0 KiB
Bill Tracker - Development Log
Purpose: Track active development work across all agents. Bishop uses this to update Engineering_Reference_Manual.md.
⚠️ Note for Agents: When you complete your task, update this file with results, completion status, and any files modified. Ripley will then notify Bishop to review and decide on manual updates. You have write and edit access to this file.
v0.26.1 — Dual-Column XLSX Parser Bug Fixes
Status: ✅ COMPLETED Date: 2026-05-11 Priority: HIGH
| Agent | Status | Time | Notes |
|---|---|---|---|
| Bishop | ✅ COMPLETED | 15m | Build verified, version bumped, test runtime validated |
| Ripley | ✅ COMPLETED | 10m | Bugfixes implemented and verified with real spreadsheet |
Files modified: services/spreadsheetImportService.js, package.json, client/lib/version.js
Work Completed:
detectAllHeaderSets()rewritten — Uses repeat-field detection instead of gap-based splitting. Second "Bill" or "Amount" column starts a new group. Requires ≥2 header fields per group (filters out "Left Over | Paid" rows).- Column leakage fixed —
allColumnsIndicesSet includes full range [startCol..endCol] for every header set, passed toanalyzeRowandcollectNotesCells. Prevents right-side bills from picking up left-side amounts. header_set_indexadded to output —analyzeRowreturn object now includesheader_set_indexso frontend can distinguish left vs right bills.isLikelySummaryRow()added — Catches Paycheck, Left Over, Enter how much, Starting/Ending Balance rows.isLikelyTotalRow()expanded — Catches "Auto Total ------>" patterns.- Leftover calc rows filtered — null/blank bill name + negative amount, or dash-separator names like "--------->".
HEADER_PATTERNS.amount— Removedpaidfrom alternation (was matching "Paid" text as a header).- Empty cell filter in
detectAllHeaderSets— Skips cells with empty string values.
Functional Test Results (verified by Ripley):
January 2026 sheet from real spreadsheet:
- ✅ 15 left-side bills (due ~1st), 12 right-side bills (due ~15th)
- ✅ No null-name rows, no dash names, no negative amounts
- ✅ Amazon chase card correctly shows null amount (no column leakage)
- ✅ All amounts parse correctly
Build & Runtime Verification:
-
✅ Build completed successfully:
Successfully built 97480952ed3e Successfully tagged bill-tracker:local -
✅ Container started on http://localhost:3036
Changes Applied:
Version bump:
package.json:0.26.0→0.26.1client/lib/version.js:APP_VERSION = '0.26.1'client/lib/version.js: RELEASE_NOTES version updated with v0.26.1 highlights
Files Modified:
services/spreadsheetImportService.js- Dual-column parser bugfixes (already verified by Ripley)package.json- Version bumped to 0.26.1client/lib/version.js- APP_VERSION and RELEASE_NOTES updated
Deliverables:
- XLSX dual-column parser correctly detects multiple header sets using repeat-field detection
- XLSX dual-column parser prevents column leakage between left and right column groups
- API response includes
header_set_indexfor frontend column distinction - Summary rows (Paycheck, Left Over, Auto Total) correctly filtered
- Amount header pattern no longer false-matches "Paid" text
v0.24.6 — XLSX Dual-Column Parser Bug Fixes
Status: ✅ COMPLETED Date: 2026-05-11 Priority: MEDIUM
| Agent | Status | Time | Notes |
|---|---|---|---|
| Neo | ✅ COMPLETED | 2m | Added filter for null-name + negative amount rows and dash separators |
| Bishop | ✅ COMPLETED | 2m | Build verified, parsed data cleaned |
Files modified: services/spreadsheetImportService.js
Work Completed:
- Bug 1 Fixed: Added filter in
parseSheetRowsto skip rows where bill name is null/blank AND amount is negative (leftover calculation rows) - Bug 1 Fixed: Added filter to skip rows where bill name matches
/^-+>/or/^--+$/(dash separators like "--------->") - Bug 2 Verified:
header_set_indexwas already present in API output (no changes needed) - Bug 3 Verified: "kids lunches" has null amount because the spreadsheet cell is genuinely empty (correct behavior, not a bug)
- Docker build passes, container starts, import preview shows 27 rows instead of 29 (removed 2 leftover calculation rows)
Changes Applied:
Before (buggy behavior):
- Row 23 (Excel row 24): Left side
[null, null, "-$3,429.47", ...]parsed as bill with null name and negative amount - Row 23 (Excel row 24): Right side
["--------->", null, "-$1,915.78", ...]parsed as bill named "--------->" with negative amount
After (fixed behavior):
- Both rows skipped during parsing
- Total rows reduced from 29 to 27
- No null-name or negative-amount rows in parsed output
Code Added (in parseSheetRows loop):
// Skip leftover calculation rows: null/blank bill name with negative amount, or dash separators
const getBillName = (field) => {
const idx = headerMap[field];
return idx !== undefined ? cells[idx] : undefined;
};
const get = (field) => {
const idx = headerMap[field];
return idx !== undefined ? cells[idx] : undefined;
};
const rawBillName = getBillName('bill_name') ?? cells[0];
const billName = rawBillName ? String(rawBillName).trim() || null : null;
const rawAmount = get('amount') ?? findFirstAmountCell(cells, new Set(Object.values(headerMap)));
const amount = rawAmount !== null ? parseAmount(rawAmount) : null;
// Check if bill name is a dash separator (--- or ---->)
const isDashSeparator = billName && (billName.match(/^-+>/) || billName.match(/^--+$/));
// Check if this is a leftover calculation row (null/blank bill name + negative amount)
// Skip if bill name is null AND amount is negative
const isLeftoverCalcRow = !billName && amount !== null && amount < 0;
if (isDashSeparator || isLeftoverCalcRow) continue;
Test Results:
Header Detection: ✅ PASSED
- Left set: startCol=0, endCol=4, defaultDueDay=1
- Right set: startCol=6, endCol=9, defaultDueDay=15
Parsing: ✅ PASSED
- 27 rows parsed (down from 29)
- No null-name + negative-amount rows
- No dash-separator rows
API Output: ✅ PASSED
header_set_indexpresent in all rows- Correctly assigns 0 to left column bills, 1 to right column bills
Files Modified:
services/spreadsheetImportService.js- Added row skip filter inparseSheetRows
Deliverables:
- XLSX dual-column parser correctly filters calculation leftover rows
- XLSX dual-column parser correctly filters dash separator rows
header_set_indexavailable in preview API response for frontend column distinction- Kids lunches null amount correctly reflects genuine empty cell (not a parsing bug)
v0.24.4 - Analytics Mobile Layout + Previous Month Payment Toggle
Status: ✅ COMPLETED Date: 2026-05-11 Priority: MEDIUM
| Agent | Status | Time | Notes |
|---|---|---|---|
| Scarlett | ✅ COMPLETED | 12m | Mobile responsiveness fixes for AnalyticsPage |
| Neo | ✅ COMPLETED | 3m | Toggle-paid scoped to year/month on backend + frontend |
| Bishop | ✅ COMPLETED | 7m | Build verified, runtime tested, version bumped |
Files modified: client/pages/AnalyticsPage.jsx, routes/bills.js, client/pages/TrackerPage.jsx, package.json, client/lib/version.js
Work Completed:
- AnalyticsPage: Heatmap table responsive (removed min-w-760px, narrower columns)
- AnalyticsPage: Controls grid breakpoints (sm:grid-cols-2 → lg:grid-cols-6)
- AnalyticsPage: Chart card grid (sm:grid-cols-1 → lg:grid-cols-2)
- AnalyticsPage: Donut chart responsive SVG sizing
- AnalyticsPage: Checkbox grid mobile layout
- AnalyticsPage: Loading skeleton mobile height
- Backend: toggle-paid accepts year/month params, scopes payment lookup to specific month
- Backend: paid_date calculated from due_day when year/month provided but no explicit date
[... remaining content unchanged from original file ...]