536 lines
19 KiB
Markdown
536 lines
19 KiB
Markdown
# Architecture Reference
|
|
|
|
## Architecture Programme Status
|
|
|
|
### Discovery Status
|
|
|
|
Complete
|
|
|
|
### Current Phase
|
|
|
|
Adoption Planning
|
|
|
|
### Current Proven Business Decision Models
|
|
|
|
- Appeal Type Policy
|
|
- Representation Entry Policy
|
|
- Representation Type Availability
|
|
|
|
### Next Recommended Architecture Stream
|
|
|
|
Authorization architecture stream complete.
|
|
|
|
Next recommended architecture stream:
|
|
|
|
Portal authorization hardening / consistency planning (documentation-first, implementation only by explicit approval)
|
|
|
|
### Objectives
|
|
|
|
- record completed assessment conclusions
|
|
- preserve stable authorization architecture model
|
|
- use the model as a baseline for future hardening/change review
|
|
|
|
## Portal Business Capability Context
|
|
|
|
PEDW Portal should be understood as supporting two principal business capabilities:
|
|
|
|
1. **Digital Appeal Submission**
|
|
- currently applies to supported digital appeal processes only
|
|
- current MVP implementation scope is Section 78 (`S78`)
|
|
- may be extended in future to additional supported appeal processes
|
|
|
|
2. **Statutory Public Information & Public Participation**
|
|
- the portal surfaces CRM-managed statutory case information to the public
|
|
- includes case details, documents, progress, events, and participation routes where applicable
|
|
- applies across multiple statutory case types, not only appeal-submission journeys
|
|
|
|
Business responsibility clarification:
|
|
|
|
- CRM / PEDW administers the statutory planning and casework processes
|
|
- the portal provides the statutory public-facing digital service layer
|
|
|
|
This architectural reference builds on those business concepts but does not replace the more detailed terminology guide in `context/business-domain-overview.md`.
|
|
|
|
## CRM Display Infrastructure Status (2026-07-01)
|
|
|
|
### Stream status
|
|
|
|
**CRM Display Infrastructure: COMPLETE**
|
|
|
|
### Shared helper introduced
|
|
|
|
- `lib/i18n/crmDisplay/resolveCrmDisplayValue.js`
|
|
|
|
### Helper contract
|
|
|
|
The shared CRM display resolver should be understood as handling the standard CRM formatted/display-value translation concern only.
|
|
|
|
Current contract:
|
|
|
|
- missing CRM display value -> return `fallbackValue`
|
|
- English -> return CRM display value
|
|
- Welsh -> return translated value when available
|
|
- Welsh without translation -> return CRM display value
|
|
|
|
### Architectural responsibility
|
|
|
|
This helper centralises the standard CRM formatted/display-value translation pattern used across portal presentation surfaces.
|
|
|
|
It should be treated as the shared compatibility seam for:
|
|
|
|
- CRM formatted values
|
|
- CRM display values
|
|
- standard EN/CY display translation lookup
|
|
- existing consumer-specific absent-value fallback handling
|
|
|
|
### Boundary exclusions
|
|
|
|
The helper boundary intentionally excludes the following concerns:
|
|
|
|
- keyed lookup translation
|
|
- project-type list translation
|
|
- hyperlink / website rendering
|
|
- mixed presentation rows
|
|
- lifecycle interpretation
|
|
- status interpretation
|
|
- post-decision interpretation
|
|
- other presentation-specific derived values
|
|
|
|
These are separate architectural concerns and should not be folded into `resolveCrmDisplayValue(...)`.
|
|
|
|
If future work is needed in those areas, it should introduce a separate abstraction rather than broadening the helper.
|
|
|
|
## Portal API Platform Assessment Status (2026-06-20)
|
|
|
|
### Stream status
|
|
|
|
**Portal Integration Contract & API Platform Assessment: COMPLETE**
|
|
|
|
### Consolidated architectural conclusion
|
|
|
|
The PEDW API platform is large in route count but materially smaller in underlying structure than the file count first suggests.
|
|
|
|
At an architecture level it is best understood as:
|
|
|
|
```text
|
|
Large route surface
|
|
↓
|
|
small route-family vocabulary
|
|
↓
|
|
small contract-shape vocabulary
|
|
↓
|
|
small implementation-style vocabulary
|
|
```
|
|
|
|
The main architectural and maintenance issue is therefore not discovery of a fundamentally different API architecture.
|
|
|
|
It is primarily:
|
|
|
|
- findability
|
|
- ownership clarity
|
|
- consistency and reuse discipline
|
|
|
|
### Stable route-family model
|
|
|
|
The completed assessment supports the following stable API platform families:
|
|
|
|
- CRM relay routes
|
|
- storage/blob routes
|
|
- finalisation/orchestration routes
|
|
- email/notification routes
|
|
- document download routes
|
|
- auth/session routes
|
|
- admin/internal routes
|
|
- middleware/helper routes
|
|
- local utility/meta routes
|
|
|
|
### Stable contract-shape model
|
|
|
|
The completed assessment supports the following repeated contract shapes:
|
|
|
|
- Public CRM read
|
|
- User-owned CRM read
|
|
- CRM create
|
|
- CRM update/patch
|
|
- CRM delete
|
|
- Proxy/pass-through
|
|
- Lookup/config/support
|
|
- Hybrid upsert/orchestration
|
|
- Storage read/write/delete
|
|
- Queue/finalisation
|
|
- Notify send / notification orchestration
|
|
|
|
### Stable implementation-style model
|
|
|
|
Three main implementation styles explain most of the API surface:
|
|
|
|
1. **Newer helper-oriented**
|
|
- `relayGet(...)`
|
|
- `relayGetData(...)`
|
|
- `respondSuccess(...)`
|
|
- `respondError(...)`
|
|
- relay policy presets
|
|
2. **Older direct-wrapper**
|
|
- `getToken()`
|
|
- direct `axios(config)`
|
|
- manual `WEBAPI_URL + queryUrl + hashAPIPath(queryUrl)`
|
|
3. **Orchestration-heavy**
|
|
- finalisation routes
|
|
- email aggregation routes
|
|
- storage + queue + CRM side-effect routes
|
|
|
|
These older patterns are not inherently incorrect; they reflect prior delivery constraints. The key future discipline is whether they should be copied forward when shared helper patterns already exist.
|
|
|
|
### Folder drift and maintenance hotspots
|
|
|
|
Stable drift model:
|
|
|
|
- low drift: `documents`, `admin`, `middleware`, top-level utility/meta
|
|
- low/moderate drift: `auth`
|
|
- moderate drift: `email`
|
|
- high drift: `endpoint`, `file`
|
|
|
|
Highest maintenance hotspots:
|
|
|
|
- **high:** `pages/api/endpoint`, `pages/api/file`
|
|
- **medium-high:** `pages/api/auth`, `pages/api/middleware`
|
|
- **medium:** `pages/api/email`
|
|
- **lower:** `pages/api/documents`, `pages/api/admin`
|
|
|
|
### Proven / not proven status
|
|
|
|
#### Proven
|
|
|
|
- the API platform assessment is representative at the pattern level
|
|
- route count overstates true structural diversity
|
|
- most routes are explained by a small number of repeated route families, contract shapes, and implementation styles
|
|
- the main maintenance problem is findability and ownership clarity
|
|
|
|
#### Not proven
|
|
|
|
- no full route-by-route inventory was produced
|
|
- no route consolidation safety assessment has been performed
|
|
- no implementation readiness decision has been approved
|
|
- no route movement or removal is recommended at this stage
|
|
|
|
### Programme guidance
|
|
|
|
This stream should now be considered complete.
|
|
|
|
If future work is approved, it should be framed as:
|
|
|
|
- API Route Map / Maintainer Guide planning
|
|
- API rationalisation planning
|
|
|
|
and not as implementation work by default.
|
|
|
|
## Portal Authorization Architecture Status (2026-06-19)
|
|
|
|
### Stream status
|
|
|
|
**Portal API Security & Access Boundary Assessment: COMPLETE**
|
|
|
|
### Consolidated architectural conclusion
|
|
|
|
PEDW currently exhibits a **distributed authorization model**.
|
|
|
|
The dominant observed pattern is:
|
|
|
|
```text
|
|
Identity established
|
|
↓
|
|
Ownership scope established
|
|
↓
|
|
Ownership identifier propagated
|
|
↓
|
|
Integrity controls applied
|
|
↓
|
|
Operation executed
|
|
```
|
|
|
|
rather than a uniformly route-local model where identity and ownership are re-derived and re-proven inside each final handler.
|
|
|
|
### Principal authorization roots
|
|
|
|
#### Public anonymous
|
|
|
|
```text
|
|
Anonymous
|
|
→ public search
|
|
→ public case viewing
|
|
```
|
|
|
|
#### CRM-owned data
|
|
|
|
```text
|
|
NextAuth session
|
|
→ session.user.email
|
|
→ getPortalLogin(email)
|
|
→ CRM Contact
|
|
→ CRM relationships
|
|
→ CRM operations
|
|
```
|
|
|
|
#### Draft / storage-owned data
|
|
|
|
```text
|
|
NextAuth session
|
|
→ session.user.id
|
|
→ user-specific storage container
|
|
→ draft JSON
|
|
→ uploaded files
|
|
```
|
|
|
|
### Integrity and execution controls
|
|
|
|
#### Signed hash
|
|
|
|
The signed hash most clearly provides:
|
|
|
|
- route integrity
|
|
- query integrity
|
|
- parameter integrity
|
|
- identifier integrity
|
|
|
|
It should be understood as:
|
|
|
|
> an integrity control rather than an object-authorization control.
|
|
|
|
#### Azure Storage execution
|
|
|
|
```text
|
|
PEDW API
|
|
→ Azure SDK
|
|
→ storage account credentials
|
|
→ Azure Storage
|
|
```
|
|
|
|
Users do not directly access Azure Storage in the reviewed architecture.
|
|
|
|
#### Azure Relay execution
|
|
|
|
```text
|
|
PEDW API
|
|
→ signed hash
|
|
→ Azure Relay
|
|
→ CRM
|
|
```
|
|
|
|
Relay hash validation is a route/path integrity mechanism.
|
|
|
|
Relay-to-CRM authentication remains out of scope for this architecture conclusion.
|
|
|
|
### Proven / not proven status
|
|
|
|
#### Proven
|
|
|
|
- distributed authorization model exists
|
|
- ownership is generally established upstream
|
|
- identifiers are propagated downstream
|
|
- route-local referential verification is not consistently visible
|
|
- storage ownership is rooted in `session.user.id`
|
|
- CRM ownership is rooted in CRM Contact identity
|
|
- signed hash strengthens integrity controls
|
|
- storage execution is server-mediated rather than direct browser-to-storage
|
|
|
|
#### Not proven
|
|
|
|
- no confirmed exploitability
|
|
- no demonstrated User A → User B mutation
|
|
- no demonstrated authorization bypass
|
|
- no evidence that prior OWASP assessments, health checks, or penetration tests are invalid
|
|
- no evidence of direct browser-to-storage or direct browser-to-CRM access
|
|
|
|
### Risk characterization
|
|
|
|
The completed stream should be understood primarily as:
|
|
|
|
- architectural integrity risk
|
|
- auditability risk
|
|
- maintainability risk
|
|
- future-change risk
|
|
|
|
It should **not** currently be characterised as:
|
|
|
|
- a confirmed vulnerability
|
|
- a demonstrated exploit
|
|
- broken authorization
|
|
|
|
unless materially new evidence emerges.
|
|
|
|
### Programme guidance
|
|
|
|
No immediate remediation programme is recommended on current evidence alone.
|
|
|
|
If future work is approved, it should be framed as:
|
|
|
|
- authorization hardening
|
|
- consistency improvements
|
|
- maintainability improvements
|
|
|
|
rather than emergency security remediation.
|
|
|
|
## Runtime Topology
|
|
|
|
1. Next.js runtime serves UI routes and API routes (legacy custom server files are present but not active).
|
|
2. Next.js `pages/` router handles UI routes and API routes under `pages/api/**`.
|
|
3. Middleware (`middleware.js`) injects CSP nonce and security headers on requests/responses.
|
|
4. State management initialized in `pages/_app.js` with Redux wrapper and persistence.
|
|
5. Authentication handled by `next-auth` in `pages/api/auth/[...nextauth].js` with Prisma adapter.
|
|
|
|
## Key Architectural Modules
|
|
|
|
- **Presentation layer:** `pages/`, `components/`, `styles/`
|
|
- **State layer:** `store/store.js` + slice reducers
|
|
- **Domain/service helpers:** `actions/`, `lib/`
|
|
- **Auth persistence:** Prisma client + `prisma/schema.prisma` (next-auth tables in SQL Server)
|
|
- **Portal business data access:** API routes query Dynamics 365 CRM through Azure Service Bus Relay using REST + OData patterns
|
|
- **Relay integrity check:** forwarded CRM-bound API requests include a path-based hash, validated by relay with shared key before forwarding
|
|
- **Infrastructure glue:** `middleware.js`, `next.config.js`, `i18n.js` (plus legacy server files not in active runtime)
|
|
|
|
## High-Risk/Guarded Paths
|
|
|
|
1. `pages/api/auth/[...nextauth].js`
|
|
- Email sign-in flow, callback/redirect logic, session setup.
|
|
2. `middleware.js` and security headers in `next.config.js`
|
|
- CSP and browser hardening policies.
|
|
3. `store/store.js`
|
|
- HYDRATE, persistence, logout storage clearing.
|
|
4. `prisma/schema.prisma`
|
|
- Source of truth for auth/account persistence tables.
|
|
5. File and notification APIs in `pages/api/file/**`, `pages/api/email/**`
|
|
- Upload/document/email side effects and sensitive data handling.
|
|
|
|
## i18n and Routing Model
|
|
|
|
- Locales: `en`, `cy` (configured in `i18n.js`).
|
|
- Locale detection disabled; domain and route rewrites drive behavior.
|
|
- Welsh route aliases maintained in `next.config.js` rewrites.
|
|
- Any new user-facing route should consider:
|
|
- translation resources in `locales/en` and `locales/cy`
|
|
- rewrite parity where a Welsh alias is expected
|
|
- auth pages and callback URLs for locale correctness
|
|
|
|
## External Integration Touchpoints
|
|
|
|
- Dynamics 365 CRM (portal business data): reached via frontend API routes that send REST/OData queries through Azure Service Bus Relay.
|
|
- Azure Service Bus Relay request integrity: relay endpoint is configured via `API_ROOT`; request path (excluding domain) is hashed client-side and validated relay-side with shared hash key.
|
|
|
|
- Azure Storage/Queue: `actions/azurestorage.js`, selected API handlers.
|
|
- GOV.UK Notify email: `actions/index.js`, `pages/api/email/**`, next-auth email provider.
|
|
- Application Insights: `components/azureappinsights.js` and related environment configuration.
|
|
- Mapping embeds and map libs: `components/mapping/**`, DNS/search components.
|
|
- PDF generation/rendering: `pages/api/file/generate*.js`, `components/pdftemplates/**`.
|
|
|
|
## Current Endpoint Contract Hardening Status (2026-03)
|
|
|
|
Recent bounded slices in the endpoint contract-consistency stream have standardized selected high-traffic handlers from raw relay error passthrough to structured response contracts (`respondSuccess` / `respondError`) with explicit required-input guards and phase21 contract coverage.
|
|
|
|
Completed clusters include:
|
|
|
|
- Search document retrieval cluster (`getsearchdocumenthistory*`, `getsearchdocumentdetails*`, `getsearchdocumentTypes_api`)
|
|
- My portal retrieval cluster (`getmycases_api`, `getmyrepresentations_api`, `getwatchedcases_api`, `getawaitingsubmission_api`)
|
|
- Basic search family cluster (`getbasicsearchdetails_api`, `getbasicsearchdetailspaged_api`, `getbasicsearchpaged_api`, `getbasicsearch_by_lparref_api`)
|
|
|
|
Guardrail note: success payload contracts are intentionally preserved to avoid frontend regressions, while negative-path behavior is being normalized endpoint-by-endpoint with corresponding phase21 tests.
|
|
|
|
## Legacy / Inactive Components
|
|
|
|
The following files exist in the repository but are not part of the current active runtime model:
|
|
|
|
- `server.js`
|
|
- `server/server.js`
|
|
|
|
Guidance:
|
|
|
|
- Do not treat these files as active runtime architecture unless explicitly reactivated.
|
|
- If reactivation is proposed, document rationale and rollout/rollback in `memory-bank/change-log.md` and `context/runbook.md`.
|
|
|
|
## Current State Assessment and Prioritised Next Steps (2026-03-25)
|
|
|
|
### Assessment summary
|
|
|
|
The platform has moved into a stronger operational and architectural posture through sustained bounded refactor slices and contract hardening.
|
|
|
|
Strengths:
|
|
|
|
1. **Governance maturity is high**
|
|
- Guardrails are explicit for auth/session integrity, CSP/security headers, Prisma source-of-truth, relay hash integrity, and EN/CY parity.
|
|
2. **API reliability posture has improved materially**
|
|
- Endpoint contract hardening and phase21 contract test expansion have reduced inconsistency in negative-path handling.
|
|
3. **Relay operations are significantly more robust**
|
|
- Shared relay forwarding now includes bounded retry/timeout policy, structured redacted lifecycle logging, and documented rollout/rollback controls.
|
|
4. **Façade decomposition is delivering low-risk progress**
|
|
- `actions` layer migration to shared clients (`relayClient`, `endpointClient`) is reducing duplicated request boilerplate and lowering drift risk.
|
|
|
|
Primary residual risks/gaps:
|
|
|
|
1. **Remaining direct-service inconsistency**
|
|
- Some direct services still contain legacy axios/request patterns and bespoke signed-request blocks.
|
|
2. **Coverage concentration**
|
|
- Contract tests are strong in targeted slices, but end-to-end/high-value journey coverage in sensitive flows remains comparatively sparse.
|
|
3. **Logging hygiene variance**
|
|
- Structured redaction exists in relay paths, but broader codebase logging still has uneven consistency.
|
|
4. **i18n parity assurance remains process-heavy**
|
|
- EN/CY parity now has targeted automated coverage, but still relies on manual discipline for broader journey-level assurance and CI enforcement.
|
|
|
|
### Prioritised next steps
|
|
|
|
1. **Complete direct-service consistency sweep (low risk, high maintainability)**
|
|
- Prioritise `actions/services/searchDirectService.js` for `getJson`/`requestJson` adoption in bounded slices.
|
|
- Preserve existing error-return behavior contracts per function.
|
|
2. **Consolidate signed-request patterns (medium risk, high security clarity)**
|
|
- Introduce a focused signed-request helper for hash-based/signed delete/get pathways currently repeated in service modules.
|
|
- Keep existing hash/header semantics unchanged while reducing duplication.
|
|
3. **Broaden high-value regression automation (high value)**
|
|
- Initial focused checks are now in place for:
|
|
- auth callback/redirect safety
|
|
- signed-delete negative path
|
|
- upload/document authorization negative path
|
|
- EN/CY route parity
|
|
- Next, expand breadth/depth (more journey-level assertions and CI integration).
|
|
4. **Perform targeted logging hardening in sensitive paths**
|
|
- Continue replacing direct/verbose logging in `auth`, `file`, `email`, and account-sensitive endpoint paths with redacted structured logging patterns.
|
|
5. **Introduce EN/CY parity CI checks**
|
|
- Add automated checks for route rewrite parity and locale key alignment to reduce drift and manual burden.
|
|
6. **Continue endpoint sprawl reduction**
|
|
- Keep collapsing duplicated proxy/request patterns behind shared helpers in bounded route clusters while preserving public response contracts.
|
|
|
|
### Recommended execution sequence
|
|
|
|
- **Sequence A (immediate):** Step 1 + Step 3 (fastest risk reduction per effort)
|
|
- **Sequence B (next):** Step 2 + Step 4 (security/logging consistency consolidation)
|
|
- **Sequence C (after):** Step 5 + Step 6 (institutionalise parity and reduce long-tail maintenance cost)
|
|
|
|
### Status update (2026-03-25)
|
|
|
|
- Sequence A targeted intent is now covered on this branch:
|
|
- Step 1: direct-service consistency sweep completed for this bundle stream
|
|
- Step 3: focused checks added for auth redirect safety and EN/CY rewrite parity, alongside existing signed-delete and upload/document negative-path coverage
|
|
- Remaining work is primarily Sequence B and Sequence C scope.
|
|
|
|
### Cross-check update vs debt list and architect review (2026-03-25)
|
|
|
|
This architecture status has been cross-checked against:
|
|
|
|
- `memory-bank/debt-list.md`
|
|
- `memory-bank/architect-review.md`
|
|
|
|
Current progress snapshot:
|
|
|
|
1. **Actions monolith decomposition** -> in progress with strong momentum
|
|
- shared clients/helpers introduced (`relayClient`, `endpointClient`, `fileClient`, `fileRouteBuilder`) and adopted across key service modules
|
|
- residual monolith risk remains until broader domain split is complete
|
|
2. **API contract consistency** -> materially improved
|
|
- large endpoint hardening footprint already delivered, with remaining long-tail cleanup still open
|
|
3. **Sensitive logging hardening** -> partial
|
|
- relay path improvements exist, but wider auth/email/file logging standardization remains open
|
|
4. **Endpoint sprawl reduction** -> materially improved
|
|
- repeated relay/proxy patterns reduced through helper reuse
|
|
5. **i18n parity assurance** -> initial automation in place
|
|
- targeted EN/CY rewrite parity checks now exist; CI-level institutionalization still recommended
|
|
6. **High-risk regression automation** -> materially improved
|
|
- focused auth redirect safety + signed-delete + upload/document negative-path + EN/CY parity checks now covered
|
|
7. **Runtime canonicalization** -> still open
|
|
- server entrypoint ambiguity (`server.js` vs `server/server.js`) remains an explicit follow-on architecture decision.
|