Lets a back-office user correct/define which invoice line belongs to which "set" and how deep it is nested, instead of relying only on the implicit "everything after a Set header until the next Set" grouping fds__prepInvoice derives. Sets may contain sets; every change applies immediately to the cached draft session and is reflected in the editor and PDF (ADR 0006/0008). Backend: - InvoiceSetStructure: pure parent-link forest (assign, change level, create, place/move-sibling, depth-first linearise + level recompute). - InvoiceDraftSetStructureDeltas: new inv/dpatch targets set.assign, set.level, set.create, set.move. - InvoiceSetPricing.Build is now order-preserving and nesting-aware (governed by the nearest converted ancestor); the set-item switch sums a header's transitive descendants so nested conversions never double-count. - FuchsPdf indents nested set members per level, mirroring the editor. Frontend: - New fis.inv_sets.js: "Set-Struktur bearbeiten" dialog — per-block table of all lines with drag & drop reorder (before/after/into), ▲▼ order and ◀▶ level buttons, fold/unfold per set (view-only), and a create bar for new Set/Text lines. Posts one delta per action; the dialog is a pure view of the server state (ADR 0006). - _Layout.cshtml / fis_main.js: cache-bust the dynamically imported per-module bundles (web/fis.<mdl>.<locale>.js/.css) with an asset version derived from the newest bundle write time, so a gulp rebuild is picked up without a stale cached module. Docs: ADR 0016, live-draft-editing concept, INVOICE_SET_PRICING.md, USER_GUIDE.md, ARCHITECTURE.md updated. Tests: InvoiceSetStructureTests (new) + additions to InvoiceDraftServiceTests/InvoiceSetPricingTests. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Decisions
This folder holds Architecture Decision Records (ADRs) — short, immutable records of a specific technical choice, why it was made, and what it implies going forward.
What belongs here
A decision, not a how-to. If it answers "why do we do X this way, and what
else did we consider," it's a decision. If it explains "how subsystem X
currently works," that belongs in ../Concepts
instead (and a decision often triggers a concept doc to be created/updated).
File naming
NNNN-kebab-case-title.md, four-digit zero-padded, sequential across the
whole folder (0001-..., 0002-...). Never reuse or renumber.
Required YAML frontmatter
Every decision file starts with:
---
status: Accepted # Proposed | Accepted | Superseded
date: 2026-07-03 # date the decision was accepted
applyTo: # glob(s) — files/areas this decision governs
- "Fuchs/Notifications/**"
supersededBy: "" # filename of the decision that replaced this one, if any
---
Agents (Claude, Copilot, Codex) must scan the YAML frontmatter of every file
in this folder first (cheap — no need to read the body) and only read the
full body of decisions whose applyTo glob matches the files they're about
to touch, or whose subject is otherwise clearly relevant to the task. This
keeps decision-following cheap even as the folder grows.
Body template
# NNNN — Title
## Context
What problem/situation forced a choice.
## Decision
What was decided, stated plainly.
## Consequences
What this implies for future code — constraints, follow-ups, trade-offs
accepted knowingly.
## Alternatives considered
Options that were rejected and why (optional but preferred).
Rules
- Decisions are immutable once
Accepted. Do not edit the Decision/ Consequences of an existing file to reverse it. Instead, write a new decision, set itsapplyTo/subject accordingly, and set the old file'sstatus: Superseded+supersededBy: NNNN-new-file.md. - Follow existing decisions. Before implementing anything in an area
covered by an
Accepteddecision, read it and conform to it. If you believe a decision is wrong, raise it with the user rather than silently deviating. - Capture new decisions as they happen. Whenever the user (or the code
you're writing) settles a non-obvious architectural or cross-cutting
choice — not a routine implementation detail — add a decision here in the
same change, and create/update the matching concept doc in
../Concepts.