refactor: fold machine-remote-data into remote-data.ts, PascalCase load lifecycle (RD-11)
`machine-remote-data.ts` defined a third encoding of an in-flight fetch: `LoadLifecycle`. It had three call sites, all one identical line, and the type was never imported by name. Move the mapping into `remote-data.ts` as `fromLoadLifecycle`, beside its neighbour `fromResource` — a `RemoteData` constructor, not a sixth encoding. The lowercase `loading`/`failed`/`loaded` tags on `BriefState`, `OrgTemplateState` and `StamdataEditorState` existed only because `LoadLifecycle` required them. Now that the constraint is inline and PascalCase, the three machines' load-lifecycle tags become `Loading`, `Failed` and `Loaded` — matching their own PascalCase message tags in the same file. `stamdata-editor.machine.spec.ts` no longer asserts a PascalCase message producing a lowercase state. `BriefStatus` (the letter's draft/submitted/approved/rejected/sent status, parsed off the wire from `BriefViewDto`) is a separate tag family and is untouched — its tag count stays 54 before and after this change. Delete `machine-remote-data.ts` and merge its spec into `remote-data.spec.ts`. Regenerate `behaviour-spec.mdx` (the `machineRemoteData` section heading becomes `fromLoadLifecycle`) and confirm `gen:snippets` reports no drift, since `remote-data.ts` carries a showcase region. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,7 @@ import { createStore } from '@shared/application/store';
|
||||
import { ActionState, SaveState } from '@shared/application/action-state';
|
||||
import { createHistory } from '@shared/application/history';
|
||||
import { createDebouncedSave } from '@shared/application/debounced-save';
|
||||
import { machineRemoteData } from '@shared/application/machine-remote-data';
|
||||
import { fromLoadLifecycle } from '@shared/application/remote-data';
|
||||
import {
|
||||
Brief,
|
||||
CaseContext,
|
||||
@@ -29,7 +29,7 @@ import { BLOB_PRESENTER } from '@shared/application/blob-presenter';
|
||||
* outcome. Mirrors `BigProfileStore`. All of `canEdit`/`canApprove`/`canReject`/
|
||||
* `canSend`, `diagnostics`, `unresolved`, `canSubmit` are DERIVED here — never
|
||||
* stored. The permission flags come from the server's decision DTO (PRD-0002 phase
|
||||
* P1) via `BriefState.loaded.decisions` — this store never computes them itself.
|
||||
* P1) via `BriefState.Loaded.decisions` — this store never computes them itself.
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class BriefStore implements PendingSave {
|
||||
@@ -95,11 +95,11 @@ export class BriefStore implements PendingSave {
|
||||
/** The load lifecycle as `RemoteData`, for `<app-async>` — the machine keeps
|
||||
owning the letter's own domain lifecycle (draft/submitted/approved/…); this is
|
||||
purely a projection of its loading/failed tags onto the shared async seam. */
|
||||
readonly remoteData = computed(() => machineRemoteData(this.model()));
|
||||
readonly remoteData = computed(() => fromLoadLifecycle(this.model()));
|
||||
|
||||
private brief = computed<Brief | null>(() => {
|
||||
const s = this.model();
|
||||
return s.tag === 'loaded' ? s.brief : null;
|
||||
return s.tag === 'Loaded' ? s.brief : null;
|
||||
});
|
||||
|
||||
readonly canEdit = computed(() => this.decisions()?.canEdit ?? false);
|
||||
@@ -111,7 +111,7 @@ export class BriefStore implements PendingSave {
|
||||
|
||||
private decisions = computed(() => {
|
||||
const s = this.model();
|
||||
return s.tag === 'loaded' ? s.decisions : null;
|
||||
return s.tag === 'Loaded' ? s.decisions : null;
|
||||
});
|
||||
readonly diagnostics = computed(() => (this.brief() ? allDiagnostics(this.brief()!) : []));
|
||||
readonly unresolved = computed(() => (this.brief() ? unresolvedPlaceholders(this.brief()!) : []));
|
||||
@@ -182,7 +182,7 @@ export class BriefStore implements PendingSave {
|
||||
}
|
||||
private restore(step: (current: Brief) => Brief | undefined) {
|
||||
const s = this.model();
|
||||
if (s.tag !== 'loaded') return;
|
||||
if (s.tag !== 'Loaded') return;
|
||||
const target = step(s.brief);
|
||||
if (target === undefined) return;
|
||||
this.store.dispatch({ tag: 'Seed', state: { ...s, brief: target } });
|
||||
|
||||
Reference in New Issue
Block a user