refactor: rename Application → Aanvraag across the wire (Step 1/8)
The wire said Application, the domain said Aanvraag — one aggregate with two names at every hop. Rename the backend DTOs and the /applications route to /aanvragen, regenerate the typed client, and rename the frontend adapter/store to match. Renamed: ApplicationSummaryDto/DetailDto, CreateApplicationRequest, SubmitApplicationRequest/Response → Aanvraag* equivalents; ApplicationsAdapter/Store → AanvragenAdapter/Store; applications.adapter.ts/applications.store.ts → aanvragen.*. Left untouched: the admin Case/Zaak vocabulary (/admin/cases, AdminCasesStore) — a separate read model, not part of this rename; the internal BigRegister.Domain.Applications namespace and the Applications EF table (renaming those needs a new EF migration, out of scope here). Part of the dashboard-readability refactor (see the approved plan). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+14
-14
@@ -1,10 +1,10 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
parseAanvraagStatus,
|
||||
parseApplicationSummary,
|
||||
parseApplications,
|
||||
parseApplicationDetail,
|
||||
} from './applications.adapter';
|
||||
parseAanvraagSummary,
|
||||
parseAanvragen,
|
||||
parseAanvraagDetail,
|
||||
} from './aanvragen.adapter';
|
||||
|
||||
const concept = {
|
||||
id: 'a1',
|
||||
@@ -42,29 +42,29 @@ describe('parseAanvraagStatus', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseApplicationSummary', () => {
|
||||
describe('parseAanvraagSummary', () => {
|
||||
it('maps a valid DTO to domain', () => {
|
||||
const r = parseApplicationSummary(concept);
|
||||
const r = parseAanvraagSummary(concept);
|
||||
expect(r.ok && r.value.type).toBe('registratie');
|
||||
expect(r.ok && r.value.status.tag).toBe('Concept');
|
||||
});
|
||||
|
||||
it('rejects a bad type and non-objects', () => {
|
||||
expect(parseApplicationSummary({ ...concept, type: 'onbekend' }).ok).toBe(false);
|
||||
expect(parseApplicationSummary(null).ok).toBe(false);
|
||||
expect(parseApplicationSummary({ ...concept, id: 42 }).ok).toBe(false);
|
||||
expect(parseAanvraagSummary({ ...concept, type: 'onbekend' }).ok).toBe(false);
|
||||
expect(parseAanvraagSummary(null).ok).toBe(false);
|
||||
expect(parseAanvraagSummary({ ...concept, id: 42 }).ok).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseApplications / parseApplicationDetail', () => {
|
||||
describe('parseAanvragen / parseAanvraagDetail', () => {
|
||||
it('parses a list and fails fast on a bad element', () => {
|
||||
expect(parseApplications([concept, concept]).ok).toBe(true);
|
||||
expect(parseApplications([concept, { ...concept, status: { tag: 'x' } }]).ok).toBe(false);
|
||||
expect(parseApplications({}).ok).toBe(false);
|
||||
expect(parseAanvragen([concept, concept]).ok).toBe(true);
|
||||
expect(parseAanvragen([concept, { ...concept, status: { tag: 'x' } }]).ok).toBe(false);
|
||||
expect(parseAanvragen({}).ok).toBe(false);
|
||||
});
|
||||
|
||||
it('carries the opaque draft through detail', () => {
|
||||
const r = parseApplicationDetail({ ...concept, draft: { beroep: 'arts' } });
|
||||
const r = parseAanvraagDetail({ ...concept, draft: { beroep: 'arts' } });
|
||||
expect(r.ok && (r.value.draft as { beroep: string }).beroep).toBe('arts');
|
||||
});
|
||||
});
|
||||
+24
-24
@@ -3,11 +3,11 @@ import { Result, ok, err } from '@shared/kernel/fp';
|
||||
import {
|
||||
ApiClient,
|
||||
AanvraagStatusDto,
|
||||
ApplicationSummaryDto,
|
||||
ApplicationDetailDto,
|
||||
AanvraagSummaryDto,
|
||||
AanvraagDetailDto,
|
||||
DraftSyncRequest,
|
||||
SubmitApplicationRequest,
|
||||
SubmitApplicationResponse,
|
||||
AanvraagIndienenRequest,
|
||||
AanvraagIndienenResponse,
|
||||
} from '@shared/infrastructure/api-client';
|
||||
import {
|
||||
Aanvraag,
|
||||
@@ -19,21 +19,21 @@ import {
|
||||
/**
|
||||
* Infrastructure adapter for the backend-owned Aanvraag aggregate — the only place
|
||||
* its HTTP lives (ADR-0001 anti-corruption boundary). The list is a resource; the
|
||||
* mutations (create/sync/cancel/submit) are thin commands the ApplicationsStore
|
||||
* mutations (create/sync/cancel/submit) are thin commands the AanvragenStore
|
||||
* orchestrates optimistically. The untrusted response is validated + mapped to
|
||||
* domain by the hand-written parse* boundary below.
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ApplicationsAdapter {
|
||||
export class AanvragenAdapter {
|
||||
private client = inject(ApiClient);
|
||||
|
||||
/** The dashboard's application list (raw DTOs; the store parses at the boundary). */
|
||||
list(): Promise<ApplicationSummaryDto[]> {
|
||||
return this.client.applicationsAll();
|
||||
/** The dashboard's aanvraag list (raw DTOs; the store parses at the boundary). */
|
||||
list(): Promise<AanvraagSummaryDto[]> {
|
||||
return this.client.aanvragenAll();
|
||||
}
|
||||
|
||||
/** Admin: every case across all owners (WP-36; `cases:manage`). Parsed at the boundary. */
|
||||
listAll(): Promise<ApplicationSummaryDto[]> {
|
||||
listAll(): Promise<AanvraagSummaryDto[]> {
|
||||
return this.client.casesAll();
|
||||
}
|
||||
|
||||
@@ -42,26 +42,26 @@ export class ApplicationsAdapter {
|
||||
return this.client.cases(id);
|
||||
}
|
||||
|
||||
detail(id: string): Promise<ApplicationDetailDto> {
|
||||
return this.client.applicationsGET(id);
|
||||
detail(id: string): Promise<AanvraagDetailDto> {
|
||||
return this.client.aanvragenGET(id);
|
||||
}
|
||||
|
||||
/** Create a Concept for a wizard type; resolves to the new aanvraag id. */
|
||||
create(type: AanvraagType): Promise<string> {
|
||||
return this.client.applicationsPOST({ type }).then((d) => d.id ?? '');
|
||||
return this.client.aanvragenPOST({ type }).then((d) => d.id ?? '');
|
||||
}
|
||||
|
||||
/** Draft sync per step (idempotent). Keep it debounced at the call site — it is chatty. */
|
||||
syncDraft(id: string, body: DraftSyncRequest): Promise<void> {
|
||||
return this.client.applicationsPUT(id, body);
|
||||
return this.client.aanvragenPUT(id, body);
|
||||
}
|
||||
|
||||
/** Cancel a Concept (cascades to its unlinked documents server-side). */
|
||||
cancel(id: string): Promise<void> {
|
||||
return this.client.applicationsDELETE(id);
|
||||
return this.client.aanvragenDELETE(id);
|
||||
}
|
||||
|
||||
submit(id: string, body: SubmitApplicationRequest): Promise<SubmitApplicationResponse> {
|
||||
submit(id: string, body: AanvraagIndienenRequest): Promise<AanvraagIndienenResponse> {
|
||||
return this.client.submit(id, body);
|
||||
}
|
||||
}
|
||||
@@ -101,7 +101,7 @@ export function parseAanvraagStatus(
|
||||
}
|
||||
}
|
||||
|
||||
function parseCommon(dto: ApplicationSummaryDto): Result<string, Aanvraag> {
|
||||
function parseCommon(dto: AanvraagSummaryDto): Result<string, Aanvraag> {
|
||||
if (typeof dto.id !== 'string') return err('aanvraag: missing id');
|
||||
if (typeof dto.type !== 'string' || !AANVRAAG_TYPES.includes(dto.type))
|
||||
return err(`aanvraag: bad type ${dto.type}`);
|
||||
@@ -121,25 +121,25 @@ function parseCommon(dto: ApplicationSummaryDto): Result<string, Aanvraag> {
|
||||
});
|
||||
}
|
||||
|
||||
export function parseApplicationSummary(json: unknown): Result<string, Aanvraag> {
|
||||
export function parseAanvraagSummary(json: unknown): Result<string, Aanvraag> {
|
||||
if (typeof json !== 'object' || json === null) return err('aanvraag: not an object');
|
||||
return parseCommon(json as ApplicationSummaryDto);
|
||||
return parseCommon(json as AanvraagSummaryDto);
|
||||
}
|
||||
|
||||
export function parseApplications(json: unknown): Result<string, Aanvraag[]> {
|
||||
export function parseAanvragen(json: unknown): Result<string, Aanvraag[]> {
|
||||
if (!Array.isArray(json)) return err('aanvragen: not an array');
|
||||
const out: Aanvraag[] = [];
|
||||
for (const item of json) {
|
||||
const parsed = parseApplicationSummary(item);
|
||||
const parsed = parseAanvraagSummary(item);
|
||||
if (!parsed.ok) return parsed;
|
||||
out.push(parsed.value);
|
||||
}
|
||||
return ok(out);
|
||||
}
|
||||
|
||||
export function parseApplicationDetail(json: unknown): Result<string, AanvraagDetail> {
|
||||
export function parseAanvraagDetail(json: unknown): Result<string, AanvraagDetail> {
|
||||
if (typeof json !== 'object' || json === null) return err('aanvraag: not an object');
|
||||
const base = parseCommon(json as ApplicationDetailDto);
|
||||
const base = parseCommon(json as AanvraagDetailDto);
|
||||
if (!base.ok) return base;
|
||||
return ok({ ...base.value, draft: (json as ApplicationDetailDto).draft ?? null });
|
||||
return ok({ ...base.value, draft: (json as AanvraagDetailDto).draft ?? null });
|
||||
}
|
||||
Reference in New Issue
Block a user