From 241fe1b57bbdb4fc42f36bc788b4eec38a4818e1 Mon Sep 17 00:00:00 2001 From: Edwin van den Houdt Date: Tue, 8 Sep 2026 23:12:56 +0200 Subject: [PATCH] docs: cite symbols, not lines, in ARCHITECTURE 2g RD-31 applied the symbols-not-lines rule to section 6a only. Section 2g has the same rot. Four of its five citation groups point at the wrong code: herregistratie.machine.ts L138-142 lands on `resolve`, not `setField`; draft-sync.ts L34 is a blank line; the wizard's L78 is an input attribute; brief.store.ts L157 is a comment. One link was also dead. text-input.component.ts moved to libs/shared/src/ui/atoms/ in RD-27. Every link in the document now resolves. Co-Authored-By: Claude Opus 5 --- docs/reference/architecture/ARCHITECTURE.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/reference/architecture/ARCHITECTURE.md b/docs/reference/architecture/ARCHITECTURE.md index 69f51cb..d1ea3ce 100644 --- a/docs/reference/architecture/ARCHITECTURE.md +++ b/docs/reference/architecture/ARCHITECTURE.md @@ -379,8 +379,8 @@ A common assumption is "the form saves on blur." It doesn't. **Blur only marks a _touched_** so validation can show; it never writes the value or hits the network. In the shared atoms, `(blur)="onTouched()"` is the `ControlValueAccessor` touched callback and nothing more; the value is pushed on `(input)`, every keystroke -([`text-input.component.ts`](../../../libs/shared/src/ui/text-input/text-input.component.ts): -`(input)` L29 → `onChange` L62, vs `(blur)="onTouched()"` L30). +([`text-input.component.ts`](../../../libs/shared/src/ui/atoms/text-input/text-input.component.ts): +`(input)="onInput($event)"` → `onInput` calls `onChange`, vs `(blur)="onTouched()"`). The real flow has two stages, neither keyed on focus: @@ -388,19 +388,20 @@ The real flow has two stages, neither keyed on focus: `{ tag: 'SetField', key, value }`. The pure reducer stores it immediately — so the Model is always current, on every keystroke, while editing. ([`herregistratie-wizard.component.ts`](../../../apps/ssp/src/app/herregistratie/ui/herregistratie-wizard/herregistratie-wizard.component.ts) - L78 → [`herregistratie.machine.ts`](../../../apps/ssp/src/app/herregistratie/domain/herregistratie.machine.ts) - L138-142, `setField`.) + (`(ngModelChange)="dispatch({ tag: 'SetField', … })"`) → + [`herregistratie.machine.ts`](../../../apps/ssp/src/app/herregistratie/domain/herregistratie.machine.ts), + `setField`.) 2. **Model → backend (600 ms debounce).** A signal `effect` tracks the machine `snapshot()`; each change resets a 600 ms timer whose callback does I/O **only** (it never dispatches, so it can't livelock the store). On the first save it lazily creates the application and stamps `?aanvraag=` into the URL, so a reload resumes the draft. ([`draft-sync.ts`](../../../apps/ssp/src/app/registratie/application/draft-sync.ts): - `DEBOUNCE_MS` L34, `effect` L102-108, `flush` L88-98 → `ApplicationsAdapter.syncDraft`.) + `DEBOUNCE_MS`, the `effect`, `flush` → `ApplicationsAdapter.syncDraft`.) The **brief** context uses the same 600 ms idiom in its own store: `edit()` applies the edit optimistically in the reducer and records an undo step, then `scheduleSave()` → `flushSave()` flips a `saveState` (Saving/Saved/Error) and calls `adapter.save` -([`brief.store.ts`](../../../apps/ssp/src/app/brief/application/brief.store.ts) L157-166, L192-209). +([`brief.store.ts`](../../../apps/ssp/src/app/brief/application/brief.store.ts): `scheduleSave`, `flushSave`). So it _feels_ like save-on-blur only because you usually stop typing when you leave a field, and the debounce fires ~600 ms later. The trigger is **"stopped changing," not