Files
Edwin van den Houdt e82309786d style: format frontend, docs and skills with prettier; add .prettierignore
One-time prettier --write so the new format:check CI gate starts green.
.prettierignore excludes generated (api-client.ts, documentation.json),
vendored (public/cibg-huisstijl), and backend (dotnet format owns it).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 13:39:31 +02:00

2.2 KiB

name, description
name description
mutation-command Add a write/submit operation — infrastructure adapter method plus an application command factory returning Result, keeping the reducer pure. Use for any POST/PUT/DELETE a form or action triggers.

Mutation command

Reducer = "what the new state is"; command = "go do it, then say what happened". The UI holds an application command, never the network client (lint-enforced).

Skeleton

Adapter method (<context>/infrastructure/<name>.adapter.ts) — takes the machine's Valid type, returns the server's answer, no parse (server is authority):

@Injectable({ providedIn: 'root' })
export class ChangeRequestAdapter {
  private client = inject(ApiClient);
  async changeRequest(data: Valid): Promise<string> {
    /* → server reference */
  }
}

Command factory (<context>/application/submit-<name>.ts) — binds the adapter in an injection context; runSubmit is the one try/catch + ProblemDetails mapping:

export function createSubmitChangeRequest() {
  const adapter = inject(ChangeRequestAdapter);
  return (data: Valid): Promise<Result<string, string>> =>
    runSubmit(() => adapter.changeRequest(data), SUBMIT_FAILED);
}

Caller (organism, field initializer — same shape as createStore): on the machine's Submitting state, run the command, then dispatch SubmitConfirmed / SubmitFailed { error }. Never throw into the template.

Optimistic updates on shared state

When a root store's view must reflect the write before the server confirms: begin* (flip pending) → confirm* (clear + resource.reload()) / rollback* (undo). See src/app/registratie/application/big-profile.store.ts.

Worked examples

  • src/app/registratie/infrastructure/change-request.adapter.ts
  • src/app/registratie/application/submit-change-request.ts
  • src/app/registratie/application/draft-sync.tscreateDraftSync(...) bundles draft persistence + submit for wizard flows; prefer it when the form has a draft.
  • src/app/shared/application/submit.tsrunSubmit, SUBMIT_FAILED.

Verify

npm test && npm run lint && npm run build
# exercise the failure path in the browser: ?scenario=error on the submitting page