feat(fp): WP-08 — one store idiom + machine naming + TEA MDX

Rename change-request.machine.ts's bare State/Msg to ChangeRequestState/
ChangeRequestMsg (the last machine not context-prefixed), document the
createStore-is-the-idiom + naming convention in CLAUDE.md §3, and add the
Foundations/State Machines (TEA) curriculum page. The wizard pages already
wired createStore (confirmed by reading each and by git log) -- the WP's
"hand-wired signal(model)" premise was stale; recorded as a deviation.
This commit is contained in:
2026-07-03 21:50:53 +02:00
parent e3cd908f4f
commit 0d623f90e8
8 changed files with 310 additions and 185 deletions

View File

@@ -1,9 +1,9 @@
import { describe, it, expect } from 'vitest';
import { State, reduce, initial } from './change-request.machine';
import { ChangeRequestState, reduce, initial } from './change-request.machine';
const editingWith = (
draft: Partial<{ straat: string; postcode: string; woonplaats: string }>,
): State => ({
): ChangeRequestState => ({
tag: 'Editing',
draft: { straat: '', postcode: '', woonplaats: '', ...draft },
errors: {},
@@ -13,13 +13,13 @@ describe('change-request reduce', () => {
it('SetField updates the draft while editing', () => {
const s = reduce(initial, { tag: 'SetField', key: 'straat', value: 'Lange Voorhout 9' });
expect(s.tag).toBe('Editing');
expect((s as Extract<State, { tag: 'Editing' }>).draft.straat).toBe('Lange Voorhout 9');
expect((s as Extract<ChangeRequestState, { tag: 'Editing' }>).draft.straat).toBe('Lange Voorhout 9');
});
it('Submit with an invalid draft stays Editing and reports field errors', () => {
const s = reduce(editingWith({ straat: '', postcode: 'nope' }), { tag: 'Submit' });
expect(s.tag).toBe('Editing');
const errors = (s as Extract<State, { tag: 'Editing' }>).errors;
const errors = (s as Extract<ChangeRequestState, { tag: 'Editing' }>).errors;
expect(errors.straat).toBeTruthy();
expect(errors.postcode).toBeTruthy();
});
@@ -29,7 +29,7 @@ describe('change-request reduce', () => {
tag: 'Submit',
});
expect(s.tag).toBe('Submitting');
expect((s as Extract<State, { tag: 'Submitting' }>).data.postcode).toBe('2514 EA');
expect((s as Extract<ChangeRequestState, { tag: 'Submitting' }>).data.postcode).toBe('2514 EA');
});
it('confirms and fails only from Submitting; Retry re-submits a failure', () => {