# Summary This PR introduces a **Case Lifecycle Domain Boundary** to centralize lifecycle decision logic and reduce coupling within the appeals application. The work is **behaviour-preserving** and introduces no intentional changes to business rules, CRM integrations, translations, dashboards, API routes, or user-facing functionality. ## What was added New lifecycle boundary: ```text lib/domain/case-lifecycle/ ``` Key responsibilities extracted: - Specialist process normalization - Appeal type mapping - Specialist process stage override mapping - Stage case-type resolution - Stage catalogue lookup - Closed-case status recognition - Lifecycle stage index resolution - Lifecycle stage status assignment ## Behaviour preserved Characterization tests were added before each extraction to preserve: - Appeal type mapping and aliases - Specialist process handling - Lifecycle stage progression - Closed-case handling - Status assignment (`complete`, `in-progress`, `not-started`) - Existing ROW behaviour - Existing `statuscode` lifecycle semantics Closed-case recognition remains unchanged for: ```text 1000 5 6 846040013 846040059 846040060 ``` ## Documentation Added: ```text lib/domain/case-lifecycle/README.md ``` Documenting: - Boundary ownership - Non-goals - Lifecycle invariants - Known architectural constraints - Future extraction roadmap ## Testing Added lifecycle characterization coverage for: - Stage wrapper behaviour - Specialist process normalization - Appeal type mapping - Specialist process stage mapping - Stage case-type resolution - Stage catalogue lookup - Progress behaviour - Closed-case status handling - Stage index resolution - Stage status assignment ## Validation - Lifecycle characterization tests passed - `npm run lint` passed with no errors ## Out of Scope No changes to: - Stage catalogue ownership - Representation eligibility - Dashboard calculations - CRM/OData queries - API routes - Redux state - EN/CY translations - Event visibility logic ## Risk **Low risk** The refactor was delivered through small, characterization-first slices with no functional changes intended. Related work items: #23527
151 lines
4.8 KiB
Markdown
151 lines
4.8 KiB
Markdown
# Case Lifecycle Domain Boundary
|
|
|
|
## Purpose
|
|
|
|
This directory contains a narrow **case lifecycle decision boundary**, not a full domain model.
|
|
|
|
Its current purpose is to centralise **behaviour-preserving interpretation logic** that was previously embedded in UI-adjacent helpers, while keeping live behaviour unchanged during refactor.
|
|
|
|
This boundary should be treated as an incremental extraction seam for read-only lifecycle interpretation, not as a place to redesign lifecycle behaviour.
|
|
|
|
## Current ownership
|
|
|
|
### `getLifecycleStagesForCase(...)`
|
|
|
|
- thin wrapper around the existing stage/progress helper
|
|
- preserves existing output shape for current consumers
|
|
- does not define new lifecycle semantics
|
|
|
|
### `normalizeSpecialistProcess(...)`
|
|
|
|
- raw CRM field fallback only
|
|
- preserves current canonical and misspelled field fallback behaviour
|
|
- does not validate or reinterpret CRM values
|
|
|
|
### `mapAppealType(...)`
|
|
|
|
- current appeal-type-to-case-type mapping
|
|
- current alias handling
|
|
- current unknown input behaviour
|
|
|
|
### `mapSpecialistProcessStageType(...)`
|
|
|
|
- specialist-process stage override mapping
|
|
- preserves current placeholder-like CRM specialist process values
|
|
- preserves current override target keys and fallback behaviour
|
|
|
|
### `getStageCaseTypeKey(...)`
|
|
|
|
- current stage case-type resolution decision
|
|
- combines:
|
|
- appeal type mapping
|
|
- specialist-process stage override mapping
|
|
- alias normalization
|
|
- current fallback behaviour
|
|
|
|
### `getStagesForCaseTypeKey(...)`
|
|
|
|
- current stage catalogue lookup only
|
|
- preserves:
|
|
- direct key lookup
|
|
- string indirection resolution
|
|
- fallback to `[]`
|
|
- does not own stage catalogue contents
|
|
|
|
## Stage catalogue ownership and lookup
|
|
|
|
Stage catalogue arrays still live in:
|
|
|
|
- `components/case/summary/utils/caseStagesByAppealType.js`
|
|
|
|
The domain boundary currently owns **lookup behaviour only**:
|
|
|
|
- direct key lookup
|
|
- string indirection resolution
|
|
- fallback to `[]`
|
|
|
|
`getStagesForCaseTypeKey(...)` must not be treated as stage catalogue ownership yet.
|
|
|
|
Lazy access in `getStagesForCaseTypeKey(...)` is intentional:
|
|
|
|
- it avoids circular dependency issues while stage arrays remain in the legacy helper
|
|
- the domain helper must not eagerly import catalogue contents while ownership remains outside the domain boundary
|
|
|
|
Any future catalogue migration must be a separate, explicitly scoped slice.
|
|
|
|
Until catalogue ownership moves:
|
|
|
|
- stage array contents remain the source of truth in the legacy helper
|
|
- the domain lookup helper must preserve reference identity
|
|
- the domain lookup helper must preserve current fallback behaviour
|
|
|
|
## Explicit non-goals
|
|
|
|
This boundary does **not** currently own:
|
|
|
|
- stage catalogue arrays
|
|
- progress/status calculation
|
|
- closed-case handling
|
|
- representation eligibility
|
|
- dashboard layout or calculations
|
|
- translations / EN-CY labels
|
|
- CRM/OData query construction
|
|
- API routes
|
|
- Redux state shape
|
|
- upload, submit, finalisation, or notification logic
|
|
|
|
## Behaviour-preservation invariants
|
|
|
|
Future slices must preserve:
|
|
|
|
- current stage IDs
|
|
- translation keys
|
|
- alias behaviour
|
|
- unknown input behaviour
|
|
- current fallback semantics
|
|
- current specialist-process override semantics
|
|
- status-vs-stage ambiguity
|
|
- current closed-case behaviour
|
|
|
|
## Known oddities to preserve
|
|
|
|
1. `statuscode` is currently passed into stage/progress logic.
|
|
- Do not rename or reinterpret this without a separate behaviour-change decision.
|
|
|
|
2. Specialist-process overrides are intentionally narrow.
|
|
- They currently apply only through the existing appeal-type-based resolution path.
|
|
- Do not broaden this behaviour during refactor.
|
|
|
|
3. Some specialist process values appear placeholder-like.
|
|
- Do not “correct” them without CRM/product confirmation.
|
|
|
|
4. Some ROW inputs currently produce non-intuitive stage output.
|
|
- Preserve characterized behaviour unless explicitly changing business rules.
|
|
|
|
5. The test harnesses are VM-based and import-sensitive.
|
|
- Future extractions must update harness injections carefully and avoid broad rewrites.
|
|
|
|
## Testing expectations
|
|
|
|
Future slices should run:
|
|
|
|
```bash
|
|
node tests/phase22/case-lifecycle-stage-case-type-resolution.test.cjs
|
|
node tests/phase22/case-lifecycle-specialist-process-stage-mapping.test.cjs
|
|
node tests/phase22/case-lifecycle-appeal-type-mapping.test.cjs
|
|
node tests/phase22/case-lifecycle-specialist-process-normalization.test.cjs
|
|
node tests/phase22/case-lifecycle-stage-wrapper.test.cjs
|
|
node tests/phase22/representation-build-reps-arr-rules.test.cjs
|
|
npm run lint
|
|
```
|
|
|
|
## Future extraction order
|
|
|
|
Recommended future order:
|
|
|
|
1. stage catalogue lookup helper
|
|
2. stage catalogue ownership only after enough characterization coverage
|
|
3. progress/status calculation extraction
|
|
4. additional read-only consumers
|
|
5. representation eligibility only as a separate policy slice after characterization
|