Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .claude/agent-memory/docs-writer/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
- `getting-started/` -- index, docker-setup, first-login, configuration
- `guides/work-items/` -- index, creating-work-items, tags, notes-and-subtasks, dependencies, keyboard-shortcuts
- `guides/users/` -- index, oidc-setup, admin-panel
- `guides/budget/` -- index, categories, financing-sources, work-item-budgets, vendors-and-invoices, subsidies, budget-overview
- `guides/budget/` -- index, categories, financing-sources, work-item-budgets, vendors-and-invoices, subsidies, budget-overview, bank-reports (added PR #2041, see [Bank Report Wizard docs](bank-report-wizard-docs.md))
- `guides/timeline/` -- index, gantt-chart, milestones, calendar-view
- `guides/documents/` -- index, setup, browsing-documents, linking-documents
- `guides/household-items/` -- index, creating-editing-items, budget-and-invoices, work-item-linking, delivery-and-dependencies
Expand Down Expand Up @@ -103,6 +103,12 @@ Three user-facing changes documented (no new pages, no sidebar changes):

Pre-existing lint baseline in worktree: ~8 eslint ERRORS in production/test .ts across client/server/e2e (photoService OrientationSummary unused, usePaperless import() type, etc.) -- NOT introduced by docs changes (docs edits are markdown-only; eslint doesn't lint .md). Likely a local `npm install --ignore-scripts` artifact since beta CI requires lint green. Do NOT touch those files as docs-writer.

## Release: PR #2041 (Bank Report Wizard docs gap, subsidies drift fix, .env.example drift fix)

Full env-var scan (`grep` for `getValue('...')` in `server/src/`) confirmed 3 vars missing/wrong in `.env.example`: `AUTH_RATE_LIMIT_MAX` and `AUTH_RATE_LIMIT_WINDOW` (new, added commented-out under Server section near `TRUST_PROXY`/`EXTERNAL_URL`) and `VAT_RATE` (pre-existing gap, added commented-out under Localization near `CURRENCY`). `CLAUDE.md`'s env-var table was already current for all three (added in an earlier commit within the same 40-commit range) -- always diff `.env.example` against `server/src/plugins/config.ts` directly rather than assuming the two docs surfaces drift together.

New page `guides/budget/bank-reports.md` closes a total docs gap for the Bank Report Wizard feature -- see [Bank Report Wizard docs](bank-report-wizard-docs.md) for what it covers and why the gap existed. Same pass also rewrote stale portions of `subsidies.md` (multi-category + "No Category" + real 5-status enum) -- same memory file has the detail.

## Build Note (still true)

`npm run docs:build` fails in worktrees with webpack `ProgressPlugin` ValidationError (node_modules corruption, NOT content). Build reaches the webpack bundling stage, so MDX/content/link loading succeeded. Validate internal links/anchors statically with grep instead; CI does the real build.
Expand Down
40 changes: 40 additions & 0 deletions .claude/agent-memory/docs-writer/bank-report-wizard-docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: bank-report-wizard-docs
description: Bank Report Wizard had zero docs-site coverage until PR #2041 (2026-08-06); new guide at guides/budget/bank-reports.md, plus the subsidies.md drift that was fixed in the same pass
metadata:
type: project
---

# Bank Report Wizard docs gap (closed 2026-08-06, PR #2041)

**Why this mattered:** EPIC-07 (Reporting and Export) had been checked off in the roadmap for a long
time, and the feature (`client/src/pages/ReportWizardPage`, route `/budget/reports`) had grown into a
large, actively-developed area (see `product-owner`'s `bank-report-wizard.md` memory for the full
mini-epic history), but `docs/src/` and `docs/sidebars.js` had **no page for it at all** -- not even a
stub. A release task that assumed "extend the existing reports docs" surfaced the gap.

**How to apply:** The gap is now closed -- `docs/src/guides/budget/bank-reports.md` (sidebar position 9,
registered in `docs/sidebars.js` under the Budget category, cross-linked from `guides/budget/index.md`).
It documents the wizard as a single comprehensive page (index-style, no sub-pages, matching the
`guides/backup/index.md` pattern) covering: the 3 report types (Budget Overview / Claim / Proof of
Funds) and their invoice-status eligibility, the 5 wizard steps (Report Type, Budget Source, Select
Invoices, Settings, Preview & Export), column visibility toggles, AI-assisted generation
("Enhance with AI", gated on `llmEnabled`), marking invoices claimed, and long-content/multi-page PDF
handling. **Before extending this page**, re-derive current UI/copy from
`client/src/i18n/en/budget.json` (`sourceReports` key) and `ReportWizardPage.tsx` rather than trusting
this page alone to stay current -- the feature has a long history of fast iteration (see
`[[release-notes-drift]]` if that file exists, or the product-owner memory directly).

## Related fix in the same pass: subsidies.md was stale, not just missing "No Category"

`docs/src/guides/budget/subsidies.md` described a **single** "Budget Category" field and a **4-status**
lifecycle (Pending/Approved/Rejected/Disbursed) that no longer matched the shipped `SubsidyProgram`
type (`shared/src/types/subsidyProgram.ts`): categories are actually **multi-select**
(`applicableCategories: BudgetCategory[]`, empty = universal) with an independent `includesNoCategoryItems`
("No Category") checkbox, and the real status enum is
`eligible | applied | approved | received | rejected` (only `approved`/`received` count toward budget
math). This predated the "No Category" release task -- rewrote the whole Creating/Statuses/How-it-affects
sections rather than just appending the new checkbox, since the old text would have stayed actively
wrong. **Lesson: when a task says "add feature X to this doc", verify the doc's existing claims against
the current type/schema before touching it — drift compounds silently on release cycles that only ever
append.**
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ NODE_ENV=production
# Used for CalDAV/CardDAV discovery, .mobileconfig generation, and OIDC callback fallback
# EXTERNAL_URL=https://myhouse.example.com

# Login endpoint (POST /api/auth/login) rate limiting
# A value that fails to parse causes the server to fail at startup.
# AUTH_RATE_LIMIT_MAX=20 # Max login requests per client per window
# AUTH_RATE_LIMIT_WINDOW=15 minutes # Window length (ms library format, e.g. '1h', '30s')

# ─── Database ──────────────────────────────────────────
DATABASE_URL=/app/data/cornerstone.db

Expand All @@ -21,6 +26,7 @@ SECURE_COOKIES=true

# ─── Localization ──────────────────────────────────────
# CURRENCY=EUR # ISO 4217 currency code (EUR, USD, CHF, etc.)
# VAT_RATE=0.19 # VAT/sales-tax rate as a fraction (e.g. 0.19 = 19%)

# ─── Diary ─────────────────────────────────────────────
# DIARY_AUTO_EVENTS=true # Set to false to disable automatic diary event logging
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ A self-hosted home building project management tool for homeowners. Track work i

- **Work Items** -- Manage construction tasks with statuses, dates, area assignments, notes, subtasks, dependencies, and keyboard shortcuts -- every work item shows its full area ancestor path (e.g. `House / Ground Floor / Kitchen`) as a breadcrumb across lists, detail pages, pickers, and every place it is referenced
- **Areas & Trades** -- Organize your project with hierarchical areas (rooms, floors, zones) and trade specialties (Electrical, Plumbing, etc.) for vendors; a dedicated "No Area" filter surfaces items that have not been classified yet
- **Budget Management** -- Budget categories, financing sources with inline expansion and mass-move of attached lines, multi-budget-line invoice linking with itemized amounts, inline editing of invoice-linked budget lines (including moving a line to a different work item or household item), staged-payment deposits for invoices paid in instalments (deposit-aware paid/claimed rollups), subsidies with caps, quotation tracking, and an area-grouped overview dashboard with source attribution badges on every line, a per-source filter (URL-persisted, server-side) that updates totals and subsidy math, a Cost Basis filter (All / Paid / Outstanding) that reframes the breakdown around what you have actually spent versus what is left to pay, clickable summary tiles, and print-friendly export
- **Budget Management** -- Budget categories, financing sources with inline expansion and mass-move of attached lines, multi-budget-line invoice linking with itemized amounts, inline editing of invoice-linked budget lines (including moving a line to a different work item or household item), staged-payment deposits for invoices paid in instalments (deposit-aware paid/claimed rollups), subsidies with caps that can target specific categories, uncategorized items, or your whole project, quotation tracking, and an area-grouped overview dashboard with source attribution badges on every line, a per-source filter (URL-persisted, server-side) that updates totals and subsidy math, a Cost Basis filter (All / Paid / Outstanding) that reframes the breakdown around what you have actually spent versus what is left to pay, clickable summary tiles, and print-friendly export
- **Bank Reports** -- Generate a formatted PDF for a financing source -- a claim submission, a proof-of-funds statement, or a budget overview -- with an editable cover letter, configurable table columns, and optional AI-drafted content
- **Auto-itemize Invoices** -- Read line items off invoice PDFs (via Paperless OCR) using any OpenAI-compatible LLM provider (Gemini, Anthropic, OpenAI, Ollama) on a dedicated review page with side-by-side PDF preview, per-row category/funding/assignment pickers, and the ability to merge several related rows into one consolidated line -- or create a whole invoice straight from a Paperless document, with metadata, vendor, and VAT-grossed-up line items extracted in one step -- opt-in, no vendor lock-in, costs pennies per invoice
- **Timeline & Gantt Chart** -- Interactive Gantt chart with dependency arrows, critical path, zoom controls, milestones, and CPM-based auto-scheduling
- **Calendar View** -- Monthly and weekly calendar grids with work items and milestones
Expand Down
26 changes: 17 additions & 9 deletions RELEASE_SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,26 @@

## What's New

This release sharpens two of the areas you spend the most time in: the budget overview and invoice auto-itemization. You can now see your budget through a "how much have we spent versus how much is left" lens, and consolidate messy multi-row invoices into clean budget lines before saving. No new configuration or migration steps are required.
This release is a reliability and polish pass on the bank report wizard -- the PDFs you hand to a lender now render correctly in every case that was previously fragile, from long German descriptions to multi-page tables. It also adds a configurable login rate limit, a "No Category" option for subsidies, and three security fixes.

### Highlights

- **Cost Basis filter on the Budget Overview** -- The Cost Breakdown table gains a **Cost Basis** dropdown with three views: **All** (the full blended projection, as before), **Paid** (only money that has actually left your account), and **Outstanding** (everything still to pay -- unpaid invoice balances plus not-yet-invoiced projections). It is deposit-aware, so invoices paid in instalments split correctly between Paid and Outstanding, and your choice is saved in the URL for bookmarking and sharing.
- **Merge line items when auto-itemizing** -- On both the auto-itemize review page and the "create invoice from a Paperless document" flow, you can now select two or more extracted rows and merge them into one consolidated line. Amounts are summed on your own server for exact arithmetic; only the descriptions are sent to the language model to propose a combined name and category. A failed merge can be retried or fully undone -- nothing is destructive until you save.
- **Diary opens on your own entries** -- The construction diary now defaults to the **Manual** filter, so you land on the entries you actually wrote instead of a feed dominated by auto-generated system events. Switch to **All** or **Automatic** anytime; the choice is reflected in the URL.

### Behind the Scenes

- Auto-itemization now shares a single, harmonized code path between the existing-invoice and new-invoice flows -- no change in behavior, but a more consistent and reliable review experience.
- Dependency and toolchain updates for security and maintenance, with no user-facing changes.
- **Report table columns now flow through to the exported PDF.** The Show/Hide columns you toggle in the wizard preview are respected in the downloaded document, not just the on-screen preview.
- **Long rows are handled cleanly.** Descriptions that need to continue onto the next page are now clearly marked as continuations instead of reading like truncated or broken rows.
- **Split invoices are footnoted correctly.** The report now distinguishes an invoice split across budget lines from one split via a deposit tagged to a different source, so the footnote on each row explains the right reason.
- **Editable fields in the report editor have sensible length limits**, so cover letters and usage descriptions stay within what the PDF layout can safely render.
- **Fixed German header word-breaks, a missing timestamp on later report pages, and the page footer's locale**, so multi-page German-language reports read correctly throughout.
- **AI-assisted report generation is now guarded** against switching report type or source while a generation is still in progress, preventing content written for the wrong report from landing in your draft.
- **Configurable login rate limiting.** New `AUTH_RATE_LIMIT_MAX` and `AUTH_RATE_LIMIT_WINDOW` settings let you tune the login endpoint's rate limit for your household's network setup -- see the [Configuration guide](https://cornerstone.steiler.dev/getting-started/configuration#authentication-rate-limiting).
- **Subsidies can now include uncategorized items.** A subsidy program's applicable-categories picker gained a "No Category" option, so a subsidy can cover budget lines that have no category assigned.
- **Budget source drill-down is deposit-aware.** Instalment-paid invoices now show the correct paid and outstanding split when viewed from a financing source.
- **Failed column-preference saves now surface an error toast** in list views instead of failing silently.

### Security

- Fixed an IPv6 address-normalization bypass in the login rate limiter (CVE-2026-15144).
- Remediated a credential-leak/SSRF vulnerability in the `undici` HTTP client (GHSA-g4rg-993r-mgx8).
- Remediated a vulnerability in the `brace-expansion` dependency (GHSA-rhx6-c78j-4q9w).

## Upgrade

Expand Down
1 change: 1 addition & 0 deletions docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const sidebars = {
'guides/budget/auto-itemize',
'guides/budget/subsidies',
'guides/budget/budget-overview',
'guides/budget/bank-reports',
],
},
{
Expand Down
Loading