2835 lines
90 KiB
Markdown
2835 lines
90 KiB
Markdown
# Portal API Platform Assessment
|
||
|
||
## Status
|
||
|
||
Assessment-only.
|
||
|
||
First bounded slice complete:
|
||
|
||
- **Slice A — API Family Classification Sample**
|
||
|
||
No refactor, implementation, or runtime behaviour change was performed.
|
||
|
||
## Required context read
|
||
|
||
The following files were read before this assessment slice:
|
||
|
||
- `context/architecture.md`
|
||
- `context/portal-api-security-boundary-assessment.md`
|
||
- `context/integration-map.md`
|
||
- `memory-bank/debt-list.md`
|
||
- `memory-bank/change-log.md`
|
||
|
||
## Sample scope
|
||
|
||
This slice intentionally inspected only the following API areas:
|
||
|
||
- `pages/api/endpoint`
|
||
- `pages/api/file`
|
||
- `pages/api/email`
|
||
- `pages/api/documents`
|
||
- `pages/api/auth`
|
||
|
||
This is **not** a full route catalogue.
|
||
|
||
Representative sample files reviewed directly:
|
||
|
||
- `pages/api/endpoint/getbasicsearch_api.js`
|
||
- `pages/api/endpoint/getmycases_api.js`
|
||
- `pages/api/endpoint/createcase_api.js`
|
||
- `pages/api/file/getbloblist.js`
|
||
- `pages/api/file/upload.js`
|
||
- `pages/api/file/createappealcompletemessage_api.js`
|
||
- `pages/api/email/notify.js`
|
||
- `pages/api/email/getall.js`
|
||
- `pages/api/documents/download/[id].js`
|
||
- `pages/api/auth/[...nextauth].js`
|
||
- `pages/api/auth/resolve-locale.js`
|
||
|
||
Supporting bounded inspection also covered:
|
||
|
||
- top-level file listings for each sampled folder
|
||
- `pages/api/middleware/*`
|
||
- targeted pattern searches inside the sampled folders only
|
||
|
||
## Findings
|
||
|
||
The sampled API surface already shows a clear split between:
|
||
|
||
1. **newer helper-oriented relay handlers**
|
||
- typically using `relayGet(...)`
|
||
- standard `respondError(...)`
|
||
- explicit required-query validation
|
||
2. **older direct integration/orchestration handlers**
|
||
- typically using `axios(...)` directly
|
||
- constructing CRM relay URLs manually
|
||
- invoking `hashAPIPath(...)` inline
|
||
- mixing multiple responsibilities in a single route
|
||
|
||
The sample suggests the platform is not one uniform API layer, but a mixed platform of:
|
||
|
||
- CRM relay facades
|
||
- Azure Storage facades
|
||
- queue/finalisation orchestration routes
|
||
- GOV.UK Notify routes
|
||
- NextAuth/session routes
|
||
- a small number of utility/meta helpers
|
||
|
||
## API family classification
|
||
|
||
### 1. CRM relay read
|
||
|
||
Observed sample indicators:
|
||
|
||
- `pages/api/endpoint/getbasicsearch_api.js`
|
||
- `pages/api/endpoint/getmycases_api.js`
|
||
|
||
Characteristics:
|
||
|
||
- reads CRM data through relay-backed query URLs
|
||
- often uses `relayGet(...)`
|
||
- usually validates required query fields first
|
||
- may lightly transform CRM results before returning
|
||
|
||
Assessment classification:
|
||
|
||
- `endpoint/` is primarily **CRM relay read** plus some write variants
|
||
|
||
### 2. CRM relay write
|
||
|
||
Observed sample indicators:
|
||
|
||
- `pages/api/endpoint/createcase_api.js`
|
||
|
||
Characteristics:
|
||
|
||
- uses direct `axios(...)` with bearer token
|
||
- constructs CRM URL as `WEBAPI_URL + queryUrl + hashAPIPath(queryUrl)`
|
||
- forwards create/update/patch/delete actions into CRM
|
||
|
||
Assessment classification:
|
||
|
||
- part of `endpoint/` is **CRM relay write**
|
||
|
||
### 3. storage/blob read
|
||
|
||
Observed sample indicators:
|
||
|
||
- `pages/api/file/getbloblist.js`
|
||
|
||
Characteristics:
|
||
|
||
- validates `container`, `casefolderID`, `hash`
|
||
- verifies request integrity with candidate-path hash comparison
|
||
- calls Azure storage helpers such as `getBlobs(...)`
|
||
|
||
Assessment classification:
|
||
|
||
- part of `file/` is **storage/blob read**
|
||
|
||
### 4. storage/blob write
|
||
|
||
Observed sample indicators:
|
||
|
||
- `pages/api/file/upload.js`
|
||
|
||
Characteristics:
|
||
|
||
- validates upload/body fields and hash
|
||
- uses multipart middleware
|
||
- writes through Azure storage helpers such as `createBlob(...)` / `createRepBlob(...)`
|
||
|
||
Assessment classification:
|
||
|
||
- part of `file/` is **storage/blob write**
|
||
|
||
### 5. queue/finalisation
|
||
|
||
Observed sample indicators:
|
||
|
||
- `pages/api/file/createappealcompletemessage_api.js`
|
||
|
||
Characteristics:
|
||
|
||
- reads and rewrites draft/progress blob state
|
||
- updates completion markers
|
||
- writes case blobs
|
||
- triggers completion/finalisation helper `createCaseCompleteMessage(...)`
|
||
- may also trigger secondary account side effects
|
||
|
||
Assessment classification:
|
||
|
||
- part of `file/` is **queue/finalisation** and **mixed orchestration**
|
||
|
||
### 6. email/notification
|
||
|
||
Observed sample indicators:
|
||
|
||
- `pages/api/email/notify.js`
|
||
- `pages/api/email/getall.js`
|
||
|
||
Characteristics:
|
||
|
||
- GOV.UK Notify send operations
|
||
- some routes also fetch CRM/watchlist/document/event data before building email payloads
|
||
- bilingual template selection appears embedded in route logic
|
||
|
||
Assessment classification:
|
||
|
||
- `email/` is primarily **email/notification**
|
||
- some routes are simple send helpers, others are broader orchestration/batch workflows
|
||
|
||
### 7. document download
|
||
|
||
Observed sample indicators:
|
||
|
||
- `pages/api/documents/download/[id].js`
|
||
|
||
Characteristics:
|
||
|
||
- streams a relay-backed document response
|
||
- passes through `id` + `hash`
|
||
- sets download headers
|
||
- redirects to `/filenotavailable` on failure
|
||
|
||
Assessment classification:
|
||
|
||
- `documents/` is **document download**
|
||
|
||
### 8. auth/session
|
||
|
||
Observed sample indicators:
|
||
|
||
- `pages/api/auth/[...nextauth].js`
|
||
- `pages/api/auth/resolve-locale.js`
|
||
|
||
Characteristics:
|
||
|
||
- NextAuth session establishment and callback handling
|
||
- verification email send
|
||
- locale-aware redirect handling
|
||
- CRM-backed preferred-language resolution
|
||
|
||
Assessment classification:
|
||
|
||
- `auth/` is primarily **auth/session**
|
||
|
||
### 9. local utility/meta
|
||
|
||
Observed sample indicators:
|
||
|
||
- `pages/api/auth/resolve-locale.js`
|
||
|
||
Characteristics:
|
||
|
||
- small helper-style route
|
||
- returns locale metadata rather than handling a full business operation
|
||
|
||
Assessment classification:
|
||
|
||
- some sampled routes behave as **local utility/meta**, even when they consult CRM
|
||
|
||
### 10. middleware/helper
|
||
|
||
Observed sampled middleware area:
|
||
|
||
- `pages/api/middleware/apiResponse.js`
|
||
- `pages/api/middleware/middleware.js`
|
||
- `pages/api/middleware/relayForwarding.js`
|
||
- `pages/api/middleware/relayPolicyPresets.js`
|
||
|
||
Characteristics:
|
||
|
||
- response envelope helper
|
||
- multipart parsing helper
|
||
- shared relay forwarding helper
|
||
- relay policy presets
|
||
|
||
Assessment classification:
|
||
|
||
- `pages/api/middleware/*` is clearly **middleware/helper**
|
||
|
||
## Integration responsibility map
|
||
|
||
| Sampled family | Primary responsibility | Backing integration classification |
|
||
| ------------------------------------------------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------- |
|
||
| `pages/api/endpoint` read sample (`getbasicsearch_api`, `getmycases_api`) | CRM query relay | **CRM relay-backed** |
|
||
| `pages/api/endpoint` write sample (`createcase_api`) | CRM create/write | **CRM relay-backed** |
|
||
| `pages/api/file` read sample (`getbloblist`) | blob listing/read | **Azure Storage SDK-backed** |
|
||
| `pages/api/file` write sample (`upload`) | blob upload/write | **Azure Storage SDK-backed** |
|
||
| `pages/api/file` finalisation sample (`createappealcompletemessage_api`) | draft/blob + completion + account side effects | **mixed/orchestration** |
|
||
| `pages/api/email/notify` | outbound transactional email | **GOV.UK Notify-backed** |
|
||
| `pages/api/email/getall` | CRM/watchlist/document/event aggregation + notify send | **mixed/orchestration** |
|
||
| `pages/api/documents/download/[id]` | streamed document retrieval via relay | **CRM relay-backed** |
|
||
| `pages/api/auth/[...nextauth]` | session/auth + verification email | **NextAuth-backed** with **GOV.UK Notify-backed** email send and CRM locale lookup |
|
||
| `pages/api/auth/resolve-locale` | locale helper | **mixed/orchestration** leaning **local-only utility with CRM lookup** |
|
||
| `pages/api/middleware/*` | shared route support | **local-only** |
|
||
|
||
### Responsibility notes from the sample
|
||
|
||
- `endpoint/` is mostly a **CRM relay platform family**.
|
||
- `file/` is mostly an **Azure Storage platform family**, but includes finalisation/orchestration routes that cross into CRM/account workflows.
|
||
- `email/` is not just a thin Notify wrapper; at least one sampled route is an orchestration layer over CRM + Notify.
|
||
- `auth/` is centered on NextAuth, but locale and sign-in email behavior pull in CRM and Notify responsibilities.
|
||
|
||
## Repeated patterns observed
|
||
|
||
Observed only from the bounded sample and targeted searches within sampled folders.
|
||
|
||
### hash validation
|
||
|
||
Clearly repeated in sampled `file/` routes and visible more broadly in sampled-folder searches.
|
||
|
||
Observed forms:
|
||
|
||
- candidate path arrays
|
||
- raw/encoded path variants
|
||
- compare `hashAPIPath(candidatePath)` against `&hash=` or `?hash=` + provided hash
|
||
|
||
Examples:
|
||
|
||
- `pages/api/file/getbloblist.js`
|
||
- `pages/api/file/upload.js`
|
||
- `pages/api/file/createappealcompletemessage_api.js`
|
||
|
||
### signed request helper usage
|
||
|
||
Observed in the newer relay family through shared helpers rather than inline hash construction.
|
||
|
||
Examples:
|
||
|
||
- `relayGet(...)` in `getbasicsearch_api.js`
|
||
- `relayGet(...)` in `getmycases_api.js`
|
||
|
||
Assessment note:
|
||
|
||
- helper usage is present, but not yet universal across sampled families
|
||
|
||
### relay forwarding
|
||
|
||
Observed strongly in the newer `endpoint/` read family.
|
||
|
||
Characteristics:
|
||
|
||
- `relayGet(...)`
|
||
- relay policy preset import
|
||
- optional transform step
|
||
- structured error envelope
|
||
|
||
### required query validation
|
||
|
||
Strongly repeated across all sampled families.
|
||
|
||
Examples:
|
||
|
||
- `searchString` required
|
||
- `loggedInUserId` required
|
||
- `container`, `casefolderID`, `hash` required
|
||
- `id`/`hash` required in download flow
|
||
|
||
### response envelope style
|
||
|
||
Repeated modern pattern:
|
||
|
||
- `respondSuccess(...)`
|
||
- `respondError(...)`
|
||
|
||
Observed across sampled endpoint/file/email routes.
|
||
|
||
Assessment note:
|
||
|
||
- response helpers are widespread in the sample even when integration patterns differ underneath
|
||
|
||
### raw CRM URL building
|
||
|
||
Repeated in older direct-write/orchestration routes.
|
||
|
||
Examples:
|
||
|
||
- `WEBAPI_URL + queryUrl + hashAPIPath(queryUrl)`
|
||
- direct axios config objects with bearer headers
|
||
|
||
Observed in:
|
||
|
||
- `pages/api/endpoint/createcase_api.js`
|
||
- `pages/api/email/getall.js`
|
||
- visible across targeted searches in multiple sampled folders
|
||
|
||
### Azure blob path construction
|
||
|
||
Repeated in sampled `file/` routes.
|
||
|
||
Examples:
|
||
|
||
- `container` + `casefolderID`
|
||
- `tempCaseRef + "/" + tempCaseRef + "_case.json"`
|
||
- split path handling for representation files using `/`
|
||
|
||
### logging style
|
||
|
||
Mixed styles observed:
|
||
|
||
- structured-ish redacted `console.info(...)` in `email/notify.js` and `auth/[...nextauth].js`
|
||
- plain `console.log(...)` in `createcase_api.js` and `documents/download/[id].js`
|
||
- `consoleLogger(...)` used for error logging in many routes
|
||
|
||
Assessment note:
|
||
|
||
- logging style is visibly inconsistent within the sample
|
||
|
||
## Obvious duplication candidates
|
||
|
||
These are sample-based family-level observations only. No consolidation is recommended yet.
|
||
|
||
### paged / unpaged endpoint variants
|
||
|
||
Observed from folder listing and targeted search patterns:
|
||
|
||
- `getbasicsearch_api` / `getbasicsearchpaged_api`
|
||
- `getbasicsearchdetails_api` / `getbasicsearchdetailspaged_api`
|
||
- `getadvancedsearch_api` / `getadvancedsearchpaged_api`
|
||
- document detail/history paged variants
|
||
|
||
Classification:
|
||
|
||
- **likely intentional**
|
||
|
||
Reason:
|
||
|
||
- naming and existing contract-hardening history suggest explicit contract variants rather than accidental duplicates
|
||
|
||
### search / detail / history variants
|
||
|
||
Observed from `endpoint/` sample family:
|
||
|
||
- search results
|
||
- detail retrieval
|
||
- history retrieval
|
||
- document-type retrieval
|
||
|
||
Classification:
|
||
|
||
- **likely intentional**
|
||
|
||
### blob list / download / delete variants
|
||
|
||
Observed from `file/` sample family and listings:
|
||
|
||
- `getbloblist`
|
||
- `downloadblob`
|
||
- `deleteblob`
|
||
- `deleteblobcase`
|
||
- `deleteblobrep`
|
||
- proxy variants
|
||
|
||
Classification:
|
||
|
||
- **likely historical**
|
||
|
||
Reason:
|
||
|
||
- the split between case/rep/proxy variants and repeated hash-validation shapes suggests growth by accretion
|
||
|
||
### create / update / patch CRM wrappers
|
||
|
||
Observed from `endpoint/` and `file/` folder listings plus sample:
|
||
|
||
- `createcase_api`
|
||
- `updatecase_api`
|
||
- `patchcase_api`
|
||
- `updateaccount_api`
|
||
- `createaccount_api`
|
||
|
||
Classification:
|
||
|
||
- **likely historical**
|
||
|
||
Reason:
|
||
|
||
- similar direct axios + token + hash + relay URL patterns recur across wrappers
|
||
|
||
### email batch / send helpers
|
||
|
||
Observed from `email/` sample:
|
||
|
||
- `notify.js` as a focused send route
|
||
- `getall.js` as a broad gather-and-send batch route
|
||
- related support routes `getdocuments.js`, `getevents.js`, `getmailinglist.js`, `getcaseref.js`
|
||
|
||
Classification:
|
||
|
||
- **unclear**
|
||
|
||
Reason:
|
||
|
||
- some separation may reflect legitimate batch assembly boundaries, but the family also shows orchestration overlap
|
||
|
||
## Contract-critical families
|
||
|
||
From the sample, the following families appear contract-critical.
|
||
|
||
### public search
|
||
|
||
Yes.
|
||
|
||
Evidence:
|
||
|
||
- `getbasicsearch_api.js`
|
||
- search/detail/history family naming in `endpoint/`
|
||
|
||
Why critical:
|
||
|
||
- public-facing query/filter/result contracts likely feed core search UI behavior
|
||
|
||
### myportal / dashboard
|
||
|
||
Yes.
|
||
|
||
Evidence:
|
||
|
||
- `getmycases_api.js`
|
||
|
||
Why critical:
|
||
|
||
- dashboard and authenticated case-list flows depend on these payloads and identifiers
|
||
|
||
### submission / finalisation
|
||
|
||
Yes.
|
||
|
||
Evidence:
|
||
|
||
- `createappealcompletemessage_api.js`
|
||
|
||
Why critical:
|
||
|
||
- this looks like a transition point from draft/blob state into completion/finalisation processing
|
||
|
||
### file upload / download
|
||
|
||
Yes.
|
||
|
||
Evidence:
|
||
|
||
- `upload.js`
|
||
- `getbloblist.js`
|
||
- broader file folder sample
|
||
|
||
Why critical:
|
||
|
||
- these routes underpin draft persistence and user document handling
|
||
|
||
### document download
|
||
|
||
Yes.
|
||
|
||
Evidence:
|
||
|
||
- `documents/download/[id].js`
|
||
|
||
Why critical:
|
||
|
||
- direct binary/document delivery contract with failure redirect behavior
|
||
|
||
### auth / session
|
||
|
||
Yes.
|
||
|
||
Evidence:
|
||
|
||
- `auth/[...nextauth].js`
|
||
|
||
Why critical:
|
||
|
||
- session establishment, callback routing, verification email, and locale-aware redirects are central platform contracts
|
||
|
||
### email / notification
|
||
|
||
Yes.
|
||
|
||
Evidence:
|
||
|
||
- `email/notify.js`
|
||
- `email/getall.js`
|
||
|
||
Why critical:
|
||
|
||
- user communications, watchlist notifications, and sign-in email flows depend on these contracts
|
||
|
||
## Risks / cautions
|
||
|
||
This slice is intentionally high-level and sample-based.
|
||
|
||
Key cautions:
|
||
|
||
1. **Do not over-generalise from one sample per family**
|
||
- especially in `endpoint/`, where newer helper-based routes and older direct axios routes coexist
|
||
2. **Integration responsibility is not always single-system**
|
||
- some routes are clearly orchestration routes rather than thin adapters
|
||
3. **Naming can conceal contract differences**
|
||
- proxy, paged, history, detail, and case/rep variants may preserve subtle caller expectations
|
||
4. **The sample confirms structural inconsistency, not implementation priority**
|
||
- this assessment does not yet decide what should be consolidated
|
||
5. **Auth/email boundaries are cross-cutting**
|
||
- `auth/[...nextauth].js` is not just auth/session; it also includes Notify and CRM locale lookups
|
||
|
||
## Validation performed
|
||
|
||
Manual inspection and small targeted searches only.
|
||
|
||
Performed:
|
||
|
||
- direct reading of required context files
|
||
- small directory listings for:
|
||
- `pages/api/endpoint`
|
||
- `pages/api/file`
|
||
- `pages/api/email`
|
||
- `pages/api/documents`
|
||
- `pages/api/auth`
|
||
- `pages/api/middleware`
|
||
- direct bounded file inspection of representative samples only
|
||
- targeted pattern searches limited to sampled folders for:
|
||
- `relayGet`
|
||
- `respondError` / `respondSuccess`
|
||
- `hashAPIPath`
|
||
- `axios`
|
||
- `NotifyClient`
|
||
- `getPortalLogin`
|
||
- locale/redirect handling
|
||
|
||
Not performed:
|
||
|
||
- no repo-wide automated analysis
|
||
- no bulk inventory generation
|
||
- no Python
|
||
- no runtime code changes
|
||
- no lint/tests, because this slice is documentation-only
|
||
|
||
## Recommendation
|
||
|
||
Next bounded slice only:
|
||
|
||
### Slice B — Endpoint CRM Relay Shape Sample
|
||
|
||
Inspect a small representative subset within `pages/api/endpoint` only, split into:
|
||
|
||
- public search/read routes
|
||
- authenticated myportal read routes
|
||
- CRM mutation/write routes
|
||
- proxy variants
|
||
|
||
Goal of Slice B:
|
||
|
||
- distinguish newer `relayGet(...)` handler families from older direct `axios + hashAPIPath` relay wrappers
|
||
- identify the main contract shapes and the most common wrapper patterns inside `endpoint/`
|
||
- remain classification-only, with no consolidation proposal yet
|
||
|
||
---
|
||
|
||
## Slice B — Endpoint CRM Relay Contract Shape Sample
|
||
|
||
### Required context read
|
||
|
||
The following files were re-read before Slice B:
|
||
|
||
- `context/portal-api-platform-assessment.md`
|
||
- `context/portal-api-security-boundary-assessment.md`
|
||
- `context/architecture.md`
|
||
- `memory-bank/change-log.md`
|
||
|
||
### Sample scope
|
||
|
||
Slice B intentionally focused only on:
|
||
|
||
- `pages/api/endpoint`
|
||
|
||
This remained a representative subset only, not a folder-wide route inventory.
|
||
|
||
Representative routes reviewed directly:
|
||
|
||
#### 1. Public read/search
|
||
|
||
- `getbasicsearch_api.js`
|
||
- `getbasicsearchpaged_api.js`
|
||
- `getadvancedsearch_api.js`
|
||
- `getsearchdocumentdetails_api.js`
|
||
- `getsearchdocumenthistory_api.js`
|
||
|
||
#### 2. Authenticated/myportal read
|
||
|
||
- `getmycases_api.js`
|
||
- `getmyrepresentations_api.js`
|
||
- `getwatchedcases_api.js`
|
||
- `getawaitingsubmission_api.js`
|
||
- `getpersonalaccount_api.js`
|
||
|
||
#### 3. CRM create/write
|
||
|
||
- `createcase_api.js`
|
||
- `createaccount_api.js`
|
||
- `createwatchedcases_api.js`
|
||
|
||
#### 4. CRM update/patch/delete
|
||
|
||
- `updateaccount_api.js`
|
||
- `patchcase_api.js`
|
||
- `deletewatchedcases_api.js`
|
||
- `deletemyrepresentations_api.js`
|
||
|
||
#### 5. Proxy/pass-through or legacy variants
|
||
|
||
- `getwatchedcasesproxy_api.js`
|
||
|
||
Supporting bounded inspection also included targeted endpoint-only searches for:
|
||
|
||
- `relayGet(...)`
|
||
- `relayGetData(...)`
|
||
- `axios(...)`
|
||
- `hashAPIPath(...)`
|
||
- `respondError(...)` / `respondSuccess(...)`
|
||
- `transformData`
|
||
- `@odata.nextLink`
|
||
- common explicit status codes
|
||
|
||
### Findings
|
||
|
||
The sampled `pages/api/endpoint` family appears to collapse into a modest number of repeated contract shapes even though the implementation layer is mixed.
|
||
|
||
The clearest split is:
|
||
|
||
1. **newer helper-oriented relay read contracts**
|
||
- structured request guards
|
||
- `relayGet(...)`
|
||
- shared response helper usage
|
||
- optional `transformData`
|
||
- optional relay policy presets
|
||
2. **older direct-wrapper mutation contracts**
|
||
- `getToken()`
|
||
- manual `queryUrl`
|
||
- direct `axios(config)`
|
||
- `WEBAPI_URL + queryUrl + hashAPIPath(queryUrl)`
|
||
- explicit method-specific config for create/update/delete
|
||
|
||
The sample suggests the endpoint layer is not dominated by many bespoke business contracts.
|
||
|
||
Instead, it looks like a relatively small set of repeated relay contract shapes with route-by-route variations in:
|
||
|
||
- validation breadth
|
||
- transforms
|
||
- pagination options
|
||
- identifier type
|
||
- whether the route is read vs write vs delete
|
||
|
||
### Endpoint contract shapes
|
||
|
||
#### A. Public CRM read
|
||
|
||
Observed sample routes:
|
||
|
||
- `getbasicsearch_api.js`
|
||
- `getbasicsearchpaged_api.js`
|
||
- `getadvancedsearch_api.js`
|
||
- `getsearchdocumentdetails_api.js`
|
||
- `getsearchdocumenthistory_api.js`
|
||
|
||
Observed shape:
|
||
|
||
```text
|
||
query params
|
||
→ CRM relay read
|
||
→ optional transform / pagination normalization
|
||
→ response
|
||
```
|
||
|
||
Characteristics:
|
||
|
||
- public-style filter or lookup params
|
||
- no route-local session enforcement visible
|
||
- usually `relayGet(...)`
|
||
- often optional transform stage
|
||
- often `@odata.nextLink` normalization for paged families
|
||
|
||
#### B. User-owned CRM read
|
||
|
||
Observed sample routes:
|
||
|
||
- `getmycases_api.js`
|
||
- `getmyrepresentations_api.js`
|
||
- `getwatchedcases_api.js`
|
||
- `getawaitingsubmission_api.js`
|
||
- `getpersonalaccount_api.js`
|
||
|
||
Observed shape:
|
||
|
||
```text
|
||
contact/user identifier
|
||
→ CRM relay read
|
||
→ optional transform
|
||
→ response
|
||
```
|
||
|
||
Characteristics:
|
||
|
||
- caller supplies `loggedInUserId` or `contactid`
|
||
- route validates identifier presence
|
||
- route forwards CRM query via `relayGet(...)`
|
||
- some routes enrich/flatten CRM response before return
|
||
|
||
#### C. CRM create
|
||
|
||
Observed sample routes:
|
||
|
||
- `createcase_api.js`
|
||
- `createaccount_api.js`
|
||
|
||
Observed shape:
|
||
|
||
```text
|
||
payload + identifiers
|
||
→ CRM create
|
||
→ optional side effects
|
||
→ response
|
||
```
|
||
|
||
Characteristics:
|
||
|
||
- `req.body` plus required identifiers
|
||
- manual relay URL construction
|
||
- direct bearer-token axios config
|
||
- response typically passes upstream CRM response through `respondSuccess(...)`
|
||
- some routes add secondary side effects (`createcase_api.js` also writes a case blob)
|
||
|
||
#### D. CRM update/patch
|
||
|
||
Observed sample routes:
|
||
|
||
- `updateaccount_api.js`
|
||
- `patchcase_api.js`
|
||
|
||
Observed shape:
|
||
|
||
```text
|
||
record identifier + payload or patch intent
|
||
→ CRM patch/update
|
||
→ response
|
||
```
|
||
|
||
Characteristics:
|
||
|
||
- single record identifier in query
|
||
- patch body either supplied directly or built in-route
|
||
- direct `axios(config)` with hashed relay URL
|
||
|
||
#### E. CRM delete
|
||
|
||
Observed sample routes:
|
||
|
||
- `deletewatchedcases_api.js`
|
||
- `deletemyrepresentations_api.js`
|
||
|
||
Observed shape:
|
||
|
||
```text
|
||
record identifier
|
||
→ CRM delete
|
||
→ response
|
||
```
|
||
|
||
Characteristics:
|
||
|
||
- single record identifier required
|
||
- direct `axios(config)` delete
|
||
- same manual hashed relay URL pattern as create/update wrappers
|
||
|
||
#### F. Proxy/pass-through
|
||
|
||
Observed sample routes:
|
||
|
||
- `getwatchedcasesproxy_api.js`
|
||
|
||
Observed shape:
|
||
|
||
```text
|
||
caller request
|
||
→ relay-backed wrapper
|
||
→ optional transform
|
||
→ response
|
||
```
|
||
|
||
Characteristics:
|
||
|
||
- structurally very close to corresponding non-proxy read route
|
||
- often preserves nearly identical query and transform logic
|
||
- main distinction is naming/contract boundary rather than drastically different internal shape
|
||
|
||
#### G. Lookup/config/support
|
||
|
||
Observed indirectly in sample and endpoint-only search evidence:
|
||
|
||
- account/login/config/lookup families such as `getaccounts_api.js`, `getpreferredlanguage_api.js`, `getappealtypes_api.js`, `getformdata_api.js`
|
||
|
||
Observed shape:
|
||
|
||
```text
|
||
lookup key or config selector
|
||
→ CRM option/config/query
|
||
→ response
|
||
```
|
||
|
||
Characteristics:
|
||
|
||
- frequently helper-oriented `relayGet(...)`
|
||
- lighter transforms than search/myportal routes
|
||
- often shared response helper/error contracts
|
||
|
||
#### H. Upsert/orchestration hybrid
|
||
|
||
Observed sample route:
|
||
|
||
- `createwatchedcases_api.js`
|
||
|
||
Observed shape:
|
||
|
||
```text
|
||
payload bindings
|
||
→ pre-check / existence lookup
|
||
→ create or patch decision
|
||
→ CRM write
|
||
→ response
|
||
```
|
||
|
||
Characteristics:
|
||
|
||
- not a pure create route
|
||
- combines a read-style pre-check (`relayGetData(...)`) with a write-style direct axios relay call
|
||
- looks like a distinct hybrid contract shape inside `endpoint/`
|
||
|
||
### Implementation style map
|
||
|
||
#### Newer helper-oriented routes
|
||
|
||
Strongly represented by sampled public reads, myportal reads, and many proxy/read families.
|
||
|
||
Typical characteristics:
|
||
|
||
- `relayGet(...)`
|
||
- sometimes `relayGetData(...)` for supplementary lookups
|
||
- `respondError(...)` used for input guards
|
||
- shared `errorResponse` object passed to relay helper
|
||
- optional `transformData`
|
||
- optional relay policy preset import
|
||
- optional header-builder injection for paged/custom reads
|
||
|
||
Sample examples:
|
||
|
||
- `getbasicsearch_api.js`
|
||
- `getbasicsearchpaged_api.js`
|
||
- `getadvancedsearch_api.js`
|
||
- `getsearchdocumentdetails_api.js`
|
||
- `getsearchdocumenthistory_api.js`
|
||
- `getmycases_api.js`
|
||
- `getmyrepresentations_api.js`
|
||
- `getwatchedcases_api.js`
|
||
- `getawaitingsubmission_api.js`
|
||
- `getpersonalaccount_api.js`
|
||
- `getwatchedcasesproxy_api.js`
|
||
|
||
#### Older direct-wrapper routes
|
||
|
||
Strongly represented by sampled create/update/delete families.
|
||
|
||
Typical characteristics:
|
||
|
||
- direct `axios(config)`
|
||
- explicit `getToken()` call
|
||
- manual `queryUrl`
|
||
- manual `WEBAPI_URL + queryUrl + hashAPIPath(queryUrl)` construction
|
||
- method-specific config (`post`, `patch`, `delete`)
|
||
- direct upstream response passthrough via `respondSuccess(...)`
|
||
|
||
Sample examples:
|
||
|
||
- `createcase_api.js`
|
||
- `createaccount_api.js`
|
||
- `updateaccount_api.js`
|
||
- `patchcase_api.js`
|
||
- `deletewatchedcases_api.js`
|
||
- `deletemyrepresentations_api.js`
|
||
|
||
#### Hybrid routes
|
||
|
||
Observed route:
|
||
|
||
- `createwatchedcases_api.js`
|
||
|
||
Typical characteristics:
|
||
|
||
- combines helper-oriented pre-check (`relayGetData`) with direct-wrapper mutation (`axios + hashAPIPath`)
|
||
- performs route-local branching between `post` and `patch`
|
||
|
||
### Contract consistency findings
|
||
|
||
#### Request parameter style
|
||
|
||
Observed pattern:
|
||
|
||
- generally explicit and route-local
|
||
- mostly query-string driven for reads and record-targeted mutations
|
||
- body + query combination common for create/update routes
|
||
|
||
Assessment:
|
||
|
||
- **partially consistent**
|
||
- parameter naming still varies by route family (`searchString`, `searchstring`, `loggedInUserId`, `contactid`, `contactId`, `incidentid`, `watchedCaseID`, `myRepresentationsID`)
|
||
|
||
#### Response envelope style
|
||
|
||
Observed pattern:
|
||
|
||
- `respondError(...)` and `respondSuccess(...)` are broadly used across both newer and older implementations
|
||
|
||
Assessment:
|
||
|
||
- **more consistent than implementation style**
|
||
- shared response helpers appear to be a stronger common contract layer than the underlying integration code
|
||
|
||
#### Error handling
|
||
|
||
Observed pattern:
|
||
|
||
- required-input guards often return `400`
|
||
- route-level catch blocks usually convert failures to route-specific coded `400`
|
||
- some non-sampled evidence in the folder shows occasional `404` and `405`
|
||
|
||
Assessment:
|
||
|
||
- **generally consistent at a high level**
|
||
- but status-code precision is not fully uniform across the folder
|
||
|
||
#### Status codes
|
||
|
||
Observed sample emphasis:
|
||
|
||
- `400` dominates for missing input and upstream failure handling
|
||
- endpoint-only searches show some explicit `404` and `405` usage in other route types
|
||
|
||
Assessment:
|
||
|
||
- **mostly normalized but not fully uniform**
|
||
- the sampled create/update/delete routes all converge heavily on `400`
|
||
|
||
#### Logging
|
||
|
||
Observed pattern:
|
||
|
||
- helper-oriented read routes often avoid explicit in-route logging except for special enrichment failures
|
||
- older direct-wrapper routes commonly call `consoleLogger(error)` in catch blocks
|
||
- some routes retain more bespoke logging around supplementary sub-queries
|
||
|
||
Assessment:
|
||
|
||
- **mixed**
|
||
- logging is more consistent in direct-wrapper mutations than in complex read/orchestration routes
|
||
|
||
#### Transforms
|
||
|
||
Observed pattern:
|
||
|
||
- common in read families
|
||
- used for:
|
||
- title projection
|
||
- flattening/expanding related CRM objects
|
||
- hash-link enrichment
|
||
- document-date fallback
|
||
- `@odata.nextLink` normalization
|
||
- post-filter enrichment for advanced search
|
||
|
||
Assessment:
|
||
|
||
- **transform-heavy read contracts are a real recurring shape**
|
||
- not every read route is a thin pass-through
|
||
|
||
#### Pagination handling
|
||
|
||
Observed pattern:
|
||
|
||
- paged search/document families require extra params such as `orderby`, `fieldSort`, `showNumberOfRecords`
|
||
- `@odata.nextLink` normalization is repeatedly applied
|
||
- paged headers are injected through custom request option builders
|
||
|
||
Assessment:
|
||
|
||
- **paged read is a distinct repeated contract variant**, not just a small option on base reads
|
||
|
||
#### Hash/signing assumptions
|
||
|
||
Observed pattern:
|
||
|
||
- helper-oriented reads generally hide relay signing behind shared helper layers
|
||
- older mutations perform route-local `hashAPIPath(queryUrl)` construction directly
|
||
- some support/lookup routes such as `getportallogin_api.js` visibly validate caller-provided hash input before relay read
|
||
|
||
Assessment:
|
||
|
||
- **signing assumptions are structurally inconsistent across shapes**
|
||
- read families usually abstract signing away; direct write/delete families usually expose it explicitly in route code
|
||
|
||
### Rationalisation insight
|
||
|
||
Evidence from the sample suggests:
|
||
|
||
- **few repeated contract shapes**
|
||
|
||
More specifically:
|
||
|
||
- the folder appears to contain a large number of routes
|
||
- but many of those routes seem to fit into a comparatively small number of recurring patterns:
|
||
- public CRM read
|
||
- user-owned CRM read
|
||
- paged read variant
|
||
- config/lookup read
|
||
- CRM create
|
||
- CRM patch/update
|
||
- CRM delete
|
||
- proxy/pass-through
|
||
- hybrid upsert/orchestration
|
||
|
||
So the route count likely overstates the number of distinct underlying contract shapes.
|
||
|
||
### Contract-critical cautions
|
||
|
||
The following sampled contract shapes look high-risk to change.
|
||
|
||
#### Public search/read
|
||
|
||
High caution.
|
||
|
||
Reason:
|
||
|
||
- public-facing search and document contracts likely drive multiple search and case-view experiences
|
||
- paged/unpaged variants may have frontend expectations around filtering, `@odata.nextLink`, ordering, and transformed fields
|
||
|
||
#### Myportal/dashboard reads
|
||
|
||
High caution.
|
||
|
||
Reason:
|
||
|
||
- these contracts appear central to dashboard, watched-case, representation, and awaiting-submission views
|
||
- transforms such as `pinswg_title`, watched-case flattening, and title projection may be relied upon directly by callers
|
||
|
||
#### Account/profile reads
|
||
|
||
High caution.
|
||
|
||
Reason:
|
||
|
||
- `getpersonalaccount_api.js` is a small route shape but contract-critical because it likely underpins profile bootstrap and account editing journeys
|
||
|
||
#### Case creation/update
|
||
|
||
High caution.
|
||
|
||
Reason:
|
||
|
||
- create/update routes use older direct wrappers and sometimes carry side effects beyond the CRM write itself
|
||
- `createcase_api.js` is especially sensitive because it combines CRM write with blob-side persistence work
|
||
|
||
#### Deletion routes
|
||
|
||
High caution.
|
||
|
||
Reason:
|
||
|
||
- delete contracts are simple in visible shape but operationally sensitive
|
||
- they rely on record identifiers and direct CRM deletion wrappers
|
||
|
||
#### Proxy variants
|
||
|
||
Medium-high to high caution.
|
||
|
||
Reason:
|
||
|
||
- proxy variants often look almost identical to primary routes, which suggests they may exist for compatibility or caller-specific contract reasons rather than redundancy alone
|
||
|
||
### Risks / cautions
|
||
|
||
1. **Sample bias remains real**
|
||
- this slice still used a bounded subset, not all endpoint handlers
|
||
2. **Read routes are not all equally simple**
|
||
- some helper-based reads are effectively mini-orchestration routes because transforms and supplementary lookups are embedded in them
|
||
3. **Route count may exaggerate uniqueness**
|
||
- many files appear to be repeated contract variants rather than genuinely new platform shapes
|
||
4. **Implementation age and contract shape are related but not identical**
|
||
- newer helper-based reads and older direct-wrapper writes are dominant patterns, but hybrid routes like `createwatchedcases_api.js` show overlap
|
||
5. **Security-boundary concerns should not be conflated with this slice**
|
||
- Slice B is about platform contract shapes and maintainability patterns, even though the sampled user-owned routes still expose the previously documented identifier-trust model
|
||
|
||
### Validation performed
|
||
|
||
Manual inspection and bounded searches only.
|
||
|
||
Performed:
|
||
|
||
- re-read required Slice B context files
|
||
- direct inspection of a representative endpoint-only subset across:
|
||
- public read/search
|
||
- authenticated/myportal read
|
||
- CRM create
|
||
- CRM update/patch/delete
|
||
- proxy/pass-through
|
||
- targeted endpoint-only searches for:
|
||
- `relayGet(...)`
|
||
- `relayGetData(...)`
|
||
- `axios(...)`
|
||
- `hashAPIPath(...)`
|
||
- `respondSuccess(...)` / `respondError(...)`
|
||
- `transformData`
|
||
- `@odata.nextLink`
|
||
- explicit status code patterns
|
||
|
||
Not performed:
|
||
|
||
- no full endpoint inventory
|
||
- no repo-wide automated analysis
|
||
- no Python
|
||
- no runtime code changes
|
||
- no lint/tests, because this remains documentation-only assessment work
|
||
|
||
### Recommendation
|
||
|
||
Next bounded slice only:
|
||
|
||
#### Slice C — Endpoint Transform and Pagination Pattern Sample
|
||
|
||
Restrict scope to a representative subset of `pages/api/endpoint` routes that use:
|
||
|
||
- `transformData`
|
||
- `@odata.nextLink` normalization
|
||
- paged/unpaged route pairs
|
||
- supplementary `relayGetData(...)` enrichment
|
||
|
||
Goal:
|
||
|
||
- determine whether transform/pagination behavior itself collapses into a small number of reusable contract sub-patterns
|
||
- stay assessment-only
|
||
- do not propose implementation yet
|
||
|
||
---
|
||
|
||
## Slice C — API Maintenance Map & Reuse Baseline
|
||
|
||
### Required context read
|
||
|
||
The following files were read before Slice C:
|
||
|
||
- `context/portal-api-platform-assessment.md`
|
||
- `context/architecture.md`
|
||
- `context/integration-map.md`
|
||
- `memory-bank/debt-list.md`
|
||
- `memory-bank/change-log.md`
|
||
|
||
### Findings
|
||
|
||
The current API surface appears maintainable only with prior local knowledge because folder responsibility and naming have drifted over time.
|
||
|
||
The strongest current maintenance pattern is:
|
||
|
||
- **`pages/api/endpoint` is still the main historical CRM relay catch-all**
|
||
- later folders (`file`, `email`, `documents`, `auth`, `admin`) were added for newer needs
|
||
- but those later folders are not purely technical or domain-clean boundaries
|
||
|
||
The result is a maintenance problem of **findability first, consistency second**:
|
||
|
||
1. a developer must often know the history of the route family to know where to look
|
||
2. once found, they must still determine whether the family uses newer shared helpers or older direct wrappers
|
||
|
||
The codebase does already contain reusable API building blocks, but they are not yet expressed in one obvious maintenance navigation model.
|
||
|
||
### Folder Responsibility Map
|
||
|
||
#### `pages/api/endpoint`
|
||
|
||
- **Intended responsibility if visible:** general portal business-data APIs via CRM relay
|
||
- **Actual responsibility based on sampled evidence:** broad catch-all for CRM reads, account/profile support, portal user reads, public search, document metadata, lookup/config, and many create/update/delete mutation wrappers
|
||
- **Does folder naming still match responsibility?** partially
|
||
- **Assessment:** **mixed / historical**
|
||
|
||
Maintenance note:
|
||
|
||
- this is still the first place to look for most CRM-backed portal behavior
|
||
- but it is too broad to communicate ownership clearly by folder name alone
|
||
|
||
#### `pages/api/file`
|
||
|
||
- **Intended responsibility if visible:** file/blob/document upload/download operations
|
||
- **Actual responsibility based on sampled evidence:** Azure Storage blob operations, uploads, draft reads, delete/download/list flows, generated PDFs, finalisation routes, some queue/completion work, and some CRM-adjacent orchestration/involvement routes
|
||
- **Does folder naming still match responsibility?** only partially
|
||
- **Assessment:** **mixed**
|
||
|
||
Maintenance note:
|
||
|
||
- a developer working on drafts/submission may need this folder even when the main change is not “just files”
|
||
|
||
#### `pages/api/email`
|
||
|
||
- **Intended responsibility if visible:** email and notification handling
|
||
- **Actual responsibility based on sampled evidence:** direct Notify send, mailing list/event/document gathering, watchlist notification batch assembly, and CRM-backed orchestration before send
|
||
- **Does folder naming still match responsibility?** partially
|
||
- **Assessment:** **mixed**
|
||
|
||
Maintenance note:
|
||
|
||
- some email routes are thin notification endpoints, others are multi-step orchestration routes
|
||
|
||
#### `pages/api/documents`
|
||
|
||
- **Intended responsibility if visible:** document download
|
||
- **Actual responsibility based on sampled evidence:** essentially a narrow direct document download proxy family
|
||
- **Does folder naming still match responsibility?** yes
|
||
- **Assessment:** **coherent**
|
||
|
||
Maintenance note:
|
||
|
||
- the folder is clear, but broader document-related behavior is still split across `documents`, `endpoint`, and `file`
|
||
|
||
#### `pages/api/auth`
|
||
|
||
- **Intended responsibility if visible:** authentication/session routes
|
||
- **Actual responsibility based on sampled evidence:** NextAuth boundary plus locale-resolution/auth-support logic with CRM preferred-language lookup and Notify email behavior
|
||
- **Does folder naming still match responsibility?** yes, mostly
|
||
- **Assessment:** **acceptable**
|
||
|
||
Maintenance note:
|
||
|
||
- coherent enough for findability, but auth behavior still crosses into CRM and Notify concerns
|
||
|
||
#### `pages/api/admin`
|
||
|
||
- **Intended responsibility if visible:** admin/internal reporting routes
|
||
- **Actual responsibility based on sampled evidence:** administrative CRM reporting/read APIs, including status counts, latest documents, and new-appeal reporting-style queries
|
||
- **Does folder naming still match responsibility?** yes
|
||
- **Assessment:** **coherent**
|
||
|
||
Maintenance note:
|
||
|
||
- this folder looks like one of the clearest top-level API ownership areas
|
||
|
||
#### `pages/api/middleware`
|
||
|
||
- **Intended responsibility if visible:** shared API support utilities
|
||
- **Actual responsibility based on sampled evidence:** response envelopes, multipart parsing, shared relay forwarding, relay retry/timeouts/policy presets
|
||
- **Does folder naming still match responsibility?** yes
|
||
- **Assessment:** **coherent**
|
||
|
||
Maintenance note:
|
||
|
||
- this folder already contains some of the strongest reuse primitives for future API work
|
||
|
||
#### Top-level utility API files
|
||
|
||
Reviewed/observed:
|
||
|
||
- `pages/api/health.js`
|
||
- `pages/api/doc.ts`
|
||
- `pages/api/notices/index.js`
|
||
|
||
Assessment:
|
||
|
||
- **Intended responsibility:** utility/meta/support endpoints
|
||
- **Actual responsibility:** health/status, swagger/openapi docs, static notice feed
|
||
- **Does naming still match?** mostly yes
|
||
- **Assessment:** **coherent** for utility/meta
|
||
|
||
Maintenance note:
|
||
|
||
- these files are easy to find, but they sit alongside folders in a way that reinforces the overall mixed top-level structure
|
||
|
||
### Feature-to-API Maintenance Map
|
||
|
||
| Feature area | Likely API folder(s) | Likely route family names | Integration touched | Contract-critical? | Folder fit |
|
||
| -------------------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------- | ------------------ | ------------------ |
|
||
| public search | `endpoint` | `getbasicsearch*`, `getadvancedsearch*`, `getbasicdnssearch*` | CRM relay | yes | acceptable |
|
||
| advanced/address search | `endpoint` | `getadvancedsearch*`, `getbasicsearch_by_address_api`, `getbasicsearch_by_lparref_api` | CRM relay | yes | acceptable |
|
||
| case details | `endpoint` | `getcase*`, `getincidentbyid_api`, `getcasemessage_api`, `getlinkedcases_api` | CRM relay | yes | acceptable |
|
||
| document download | `documents`, `endpoint`, `file` | `documents/download/[id]`, `getsearchdocumentdetails*`, `getsearchdocumenthistory*`, blob download routes | CRM relay, Azure Storage | yes | confusing |
|
||
| my portal dashboard | `endpoint`, `file` | `getmycases_api`, `getmyrepresentations_api`, `getwatchedcases_api`, `getawaitingsubmission_api`, draft blob reads | CRM relay, Azure Storage | yes | acceptable |
|
||
| watched cases | `endpoint` | `getwatchedcases*`, `createwatchedcases_api`, `deletewatchedcases*` | CRM relay | yes | good |
|
||
| representations | `endpoint`, `file` | `getrepresentations*`, `getmyrepresentations*`, representation involvement/completion routes | CRM relay, Azure Storage | yes | acceptable |
|
||
| new appeal drafts | `file` | `getprogressobjblob`, `getbloblist`, `upload*`, `deleteblobcase`, `setupcontainer` | Azure Storage | yes | acceptable |
|
||
| representation drafts | `file` | `getrepsblob*`, `upload*`, `deleteblobrep`, `editRepJson` | Azure Storage | yes | acceptable |
|
||
| appeal submission/finalisation | `file`, `endpoint` | `createappealcompletemessage*`, `createcase_api`, `patchcase_api`, `updatecase_api` | Azure Storage, Azure Queue, CRM relay | yes | historical/unclear |
|
||
| representation submission/finalisation | `file`, `endpoint` | `createrepcompletemessage_api`, involvement routes, representation delete/update families | Azure Storage, Azure Queue, CRM relay | yes | historical/unclear |
|
||
| account registration | `endpoint`, `auth` | `createaccount_api`, `getemailaccountcheck_api`, `getportallogin_api` | CRM relay, NextAuth | yes | acceptable |
|
||
| personal details/account update | `endpoint` | `getpersonalaccount_api`, `updateaccount_api`, `updatepassword_api` | CRM relay | yes | acceptable |
|
||
| authentication/sign-in | `auth`, `endpoint` | `[...nextauth]`, `resolve-locale`, `getportallogin_api`, `getpreferredlanguage_api` | NextAuth, GOV.UK Notify, CRM relay | yes | confusing |
|
||
| email/notifications | `email`, `auth` | `notify`, `getall`, `getdocuments`, `getevents`, next-auth verification email flow | GOV.UK Notify, CRM relay | yes | acceptable |
|
||
| admin/internal reporting | `admin`, `endpoint` | `getnewappeals_api`, `getlatestdocuments_api`, status-count routes | CRM relay | no/mostly internal | good |
|
||
|
||
### Folder Drift / Naming Drift
|
||
|
||
Observed maintenance drift areas:
|
||
|
||
#### CRM routes living under `file`
|
||
|
||
Examples from existing sampled evidence:
|
||
|
||
- involvement creation routes
|
||
- completion/finalisation routes
|
||
- case-related orchestration in `file`
|
||
|
||
Why it affects maintenance:
|
||
|
||
- a developer may not think to search `file/` when the change is really about case submission, involvement, or CRM completion side effects
|
||
|
||
#### Orchestration routes living under `email`
|
||
|
||
Example:
|
||
|
||
- `pages/api/email/getall.js`
|
||
|
||
Why it affects maintenance:
|
||
|
||
- the route is not just “send an email”; it assembles CRM/watchlist/document/event data before notification send
|
||
|
||
#### Document behavior split across `endpoint`, `documents`, and `file`
|
||
|
||
Examples:
|
||
|
||
- `documents/download/[id].js`
|
||
- search document metadata under `endpoint`
|
||
- blob document/file flows under `file`
|
||
|
||
Why it affects maintenance:
|
||
|
||
- developers must know whether they are dealing with published CRM-backed document retrieval, draft/blob files, or a direct download proxy before they know where to look
|
||
|
||
#### Finalisation routes under `file`
|
||
|
||
Examples:
|
||
|
||
- `createappealcompletemessage_api.js`
|
||
- `createrepcompletemessage_api.js`
|
||
|
||
Why it affects maintenance:
|
||
|
||
- these are not merely file operations; they sit near a business transition boundary from draft to submitted state
|
||
|
||
#### Account/auth-support routes under `endpoint`
|
||
|
||
Examples:
|
||
|
||
- `getportallogin_api.js`
|
||
- `getpreferredlanguage_api.js`
|
||
- `getemailaccountcheck_api.js`
|
||
- `getpersonalaccount_api.js`
|
||
|
||
Why it affects maintenance:
|
||
|
||
- account and auth-adjacent responsibilities are split between `auth/` and `endpoint/`, which weakens findability
|
||
|
||
#### Historical naming conventions
|
||
|
||
Examples:
|
||
|
||
- `_api` suffix routes
|
||
- `proxy` variants
|
||
- `paged` variants
|
||
- `details` / `history` / `Types` variants
|
||
|
||
Why it affects maintenance:
|
||
|
||
- naming often reflects historical delivery slices more than current ownership boundaries
|
||
- similar names can hide materially different caller expectations or integration behavior
|
||
|
||
### Common Building Blocks
|
||
|
||
#### `relayGet(...)`
|
||
|
||
- **What it standardizes:** CRM relay GET forwarding, token/header/hash handling, success response path, error response path, optional transforms
|
||
- **Where it is already used:** widely across `pages/api/endpoint/**`, especially read families
|
||
- **Preferred for future work?** yes, for new CRM read APIs where the route fits the shared relay-read model
|
||
- **Do legacy alternatives still exist?** yes, many older direct axios wrappers remain
|
||
|
||
#### `relayGetData(...)`
|
||
|
||
- **What it standardizes:** relay-backed data fetches for sub-queries or enrichments without directly writing to `res`
|
||
- **Where it is already used:** complex endpoint reads and hybrids such as advanced search enrichment, address/LPA lookups, `createwatchedcases_api.js`
|
||
- **Preferred for future work?** yes, where a route needs supplementary relay reads inside orchestration logic
|
||
- **Do legacy alternatives still exist?** yes, direct `axios.get(WEBAPI_URL + queryUrl + hashAPIPath(queryUrl))`
|
||
|
||
#### `respondSuccess(...)` / `respondError(...)`
|
||
|
||
- **What they standardize:** top-level JSON response conventions and coded error envelopes
|
||
- **Where they are already used:** broadly across endpoint, file, email, admin, and middleware-aware routes
|
||
- **Preferred for future work?** yes
|
||
- **Do legacy alternatives still exist?** yes, some raw `res.status(...).json(...)` patterns still exist in the wider API surface and utility endpoints
|
||
|
||
#### Relay policy presets
|
||
|
||
- **What they standardize:** retry/timeout profiles for read families (`STRICT_LOGIN`, `LOOKUP`, `BOUNDED_READ`, `SEARCH_PAGED`)
|
||
- **Where they are already used:** many `endpoint` read routes
|
||
- **Preferred for future work?** yes, where relay-backed reads need an existing policy profile
|
||
- **Do legacy alternatives still exist?** yes, older routes without policy presets and direct axios wrappers
|
||
|
||
#### `signedRequestClient` helpers
|
||
|
||
- **What they standardize:** signed GET/POST/DELETE execution using existing hashed URL generation
|
||
- **Where they are already used:** service/client layer rather than route layer (`actions/clients/signedRequestClient.js`)
|
||
- **Preferred for future work?** likely yes for new signed client/service flows
|
||
- **Do legacy alternatives still exist?** yes, many inline `buildHashedQueryUrl` and direct request patterns remain outside or beneath this layer
|
||
|
||
#### Hash/path validation helpers
|
||
|
||
- **What they standardize:** HMAC path signing and validation expectations (`hashAPIPath(...)`, signed URL generation)
|
||
- **Where they are already used:** widespread across relay and file/blob flows
|
||
- **Preferred for future work?** yes, where existing signed route models must be preserved
|
||
- **Do legacy alternatives still exist?** yes, many route-local manual candidate-path checks and inline hash construction blocks
|
||
|
||
#### Azure storage helpers
|
||
|
||
- **What they standardize:** blob/container/queue operations and related metadata assembly
|
||
- **Where they are already used:** `pages/api/file/**`, some endpoint/file orchestration flows, service layer helpers
|
||
- **Preferred for future work?** yes for storage-facing work
|
||
- **Do legacy alternatives still exist?** some routes still mix storage helpers with route-local orchestration logic rather than remaining thin wrappers
|
||
|
||
#### Notify helpers / Notify integration patterns
|
||
|
||
- **What they standardize:** currently more implicit than explicit; direct Notify client usage exists, but some shared behavior lives in service modules and auth flow
|
||
- **Where they are already used:** `pages/api/email/**`, `pages/api/auth/[...nextauth].js`, service layer
|
||
- **Preferred for future work?** partially; direct Notify usage is established, but orchestration should be chosen deliberately
|
||
- **Do legacy alternatives still exist?** yes, thin send routes and broad orchestration routes coexist
|
||
|
||
#### Auth/session helpers
|
||
|
||
- **What they standardize:** session establishment primarily via NextAuth route; locale support via `resolve-locale`; broader auth-context helpers live outside `pages/api`
|
||
- **Where they are already used:** `pages/api/auth/**`, SSR/service layers elsewhere in repo
|
||
- **Preferred for future work?** yes for auth-specific work inside existing NextAuth boundary
|
||
- **Do legacy alternatives still exist?** account/auth-support behavior still partly lives under `endpoint/`
|
||
|
||
#### Logging helpers
|
||
|
||
- **What they standardize:** `consoleLogger(...)`, redaction helper usage, some structured relay logging
|
||
- **Where they are already used:** many API routes, especially catch blocks and relay middleware
|
||
- **Preferred for future work?** yes
|
||
- **Do legacy alternatives still exist?** yes, direct `console.log(...)` / `console.info(...)` still exist in sampled folders
|
||
|
||
### Future Consistency Baseline
|
||
|
||
This is guidance only for future maintainability work, not an implementation mandate.
|
||
|
||
Suggested baseline:
|
||
|
||
- new CRM read APIs should prefer shared relay helpers such as `relayGet(...)` where the route fits that contract shape
|
||
- new relay-backed sub-query/enrichment logic should prefer existing helper-style relay fetches rather than bespoke inline wrappers where suitable
|
||
- new JSON responses should prefer `respondSuccess(...)` / `respondError(...)`
|
||
- new storage-facing APIs should reuse existing Azure storage helpers and established hash-validation patterns
|
||
- new Notify-facing APIs should keep thin send routes thin, and only mix broader orchestration where there is a clear need
|
||
- new APIs should make it easier to identify:
|
||
- owning feature area
|
||
- integration touched
|
||
- whether the route is contract-critical
|
||
- existing direct `axios + hashAPIPath` wrappers may remain where behaviour is stable, but they should not be copied blindly into new work when shared helper patterns already exist
|
||
- future API additions should aim to improve findability as well as technical consistency, so developers can more quickly identify the right folder and family before editing
|
||
|
||
### Maintenance Pain Points
|
||
|
||
The main maintenance pain points visible in this slice are:
|
||
|
||
#### Route findability
|
||
|
||
- similar behavior is split across multiple top-level folders
|
||
- some folders are historical rather than cleanly responsibility-based
|
||
|
||
#### Route name similarity
|
||
|
||
- many near-identical names (`proxy`, `paged`, `details`, `history`, `_api`) increase scan cost
|
||
|
||
#### Folder responsibility overlap
|
||
|
||
- CRM behavior exists in `endpoint`, `file`, `email`, `auth`, and `admin`
|
||
- document behavior exists in `endpoint`, `documents`, and `file`
|
||
|
||
#### Mixed integration responsibilities
|
||
|
||
- some folders contain thin wrappers, others contain orchestration routes that cross CRM/storage/Notify boundaries
|
||
|
||
#### Older/newer implementation styles
|
||
|
||
- helper-oriented relay contracts and older direct wrappers coexist, so developers must determine style before making even a small change
|
||
|
||
#### Missing route ownership documentation
|
||
|
||
- a future contributor often has to infer “owning feature” from names and code shape rather than from explicit maintenance guidance
|
||
|
||
#### Repeated boilerplate and historical growth
|
||
|
||
- even where shared helpers now exist, route families still show signs of incremental historical accretion
|
||
|
||
### Risks / Cautions
|
||
|
||
1. **This is still a bounded maintenance assessment**
|
||
- it is not a full route inventory or migration plan
|
||
2. **Folder drift does not automatically mean incorrect architecture**
|
||
- some historical placements may still reflect practical delivery constraints or compatibility concerns
|
||
3. **Reuse guidance should not erase contract-specific nuance**
|
||
- some route families genuinely need transforms, enrichments, or special caller behavior
|
||
4. **Findability and consistency are related but different problems**
|
||
- a route can be technically well-structured yet still be hard to find in the current folder layout
|
||
5. **Legacy patterns should be treated carefully**
|
||
- older direct wrappers are not automatically wrong; the main risk is copying them forward uncritically for new work
|
||
|
||
### Validation performed
|
||
|
||
Manual inspection and bounded searches only.
|
||
|
||
Performed:
|
||
|
||
- re-read required Slice C context files
|
||
- small top-level API listings for:
|
||
- `pages/api`
|
||
- `pages/api/admin`
|
||
- direct representative inspection of:
|
||
- admin routes
|
||
- top-level utility/meta routes
|
||
- shared middleware/support files
|
||
- existing shared client/helper files
|
||
- previously reviewed assessment evidence from Slices A and B
|
||
- targeted searches for existing building blocks and helper usage across `pages/api`
|
||
|
||
Not performed:
|
||
|
||
- no repo-wide automated analysis
|
||
- no Python
|
||
- no bulk route inventory generation
|
||
- no runtime code changes
|
||
- no lint/tests, because this remains documentation-only assessment work
|
||
|
||
### Recommendation
|
||
|
||
Next bounded assessment step only:
|
||
|
||
#### Slice D — API Route Ownership & Change-Entry Sample
|
||
|
||
Focus on a bounded set of high-value feature journeys and trace:
|
||
|
||
- first likely API entry points a maintainer would touch
|
||
- adjacent supporting routes/helpers they would also need to inspect
|
||
- the minimum “change entry set” for safe edits
|
||
|
||
Suggested bounded feature sample:
|
||
|
||
- watched cases
|
||
- account/personal details
|
||
- public document retrieval
|
||
- appeal submission/finalisation
|
||
|
||
Goal:
|
||
|
||
- make future change entry points more explicit without proposing refactor yet
|
||
|
||
---
|
||
|
||
## Slice D — API Route Ownership & Change-Entry Sample
|
||
|
||
### Required context read
|
||
|
||
The following files were re-read before Slice D:
|
||
|
||
- `context/portal-api-platform-assessment.md`
|
||
- `context/architecture.md`
|
||
- `context/integration-map.md`
|
||
- `memory-bank/change-log.md`
|
||
|
||
### Findings
|
||
|
||
For the sampled journeys, the main maintainer problem is not usually “what does this one route do?” but rather:
|
||
|
||
```text
|
||
which UI entry point started this journey,
|
||
which service helper actually owns the API call,
|
||
which route performs the final contract,
|
||
and which adjacent state/helpers must also be checked before changing behaviour?
|
||
```
|
||
|
||
The four sampled journeys differ in complexity:
|
||
|
||
- watched cases = feature-led CRM relay journey with several UI entry points
|
||
- account/personal details = account/profile journey split across SSR/page state and CRM update APIs
|
||
- public document retrieval = public search-driven document metadata + download proxy journey
|
||
- appeal submission/finalisation = orchestration-heavy draft-to-submission journey crossing storage, queue/finalisation, and CRM mutation boundaries
|
||
|
||
### Journey Change-Entry Sets
|
||
|
||
#### 1. Watched cases
|
||
|
||
##### Primary UI/component entry points
|
||
|
||
- `components/search/searchresults.js`
|
||
- `components/search/addresssearchresults.js`
|
||
- `components/search/dnssearchresults.js`
|
||
- `components/case/summary.js`
|
||
- `components/myportal/topthree.js`
|
||
- `components/myportal/viewall.js`
|
||
|
||
##### Likely service helpers
|
||
|
||
- `actions/services/portalDirectService.js`
|
||
- `getWatchedCases`
|
||
- `getWatchedCasesProxy`
|
||
- `createWatchedCases`
|
||
- `deleteWatchedCases`
|
||
|
||
##### API routes
|
||
|
||
- `pages/api/endpoint/getwatchedcases_api.js`
|
||
- `pages/api/endpoint/getwatchedcasesproxy_api.js`
|
||
- `pages/api/endpoint/createwatchedcases_api.js`
|
||
- `pages/api/endpoint/deletewatchedcases_api.js`
|
||
- `pages/api/endpoint/deletewatchedcasesproxy_api.js` as adjacent compatibility variant
|
||
|
||
##### Shared clients/helpers
|
||
|
||
- `relayGet(...)`
|
||
- `relayGetData(...)`
|
||
- `respondError(...)` / `respondSuccess(...)`
|
||
- relay policy presets
|
||
- `hashAPIPath(...)`
|
||
- route/query builders in portal services
|
||
- `splitWatchedCasesBySubmissionState(...)`
|
||
- `getDetailsProxy(...)`
|
||
|
||
##### State/store modules
|
||
|
||
- `store/watchedCases/{action,reducer}.js`
|
||
- `store/currentView/action.js`
|
||
- `store/accountDetails/action.js`
|
||
|
||
##### External integration touched
|
||
|
||
- CRM relay
|
||
- local-only state/helpers
|
||
|
||
#### 2. Account / personal details
|
||
|
||
##### Primary UI/component entry points
|
||
|
||
- `pages/account/personaldetails.js`
|
||
- `components/account/personaldetails.js`
|
||
- adjacent completion/check components referenced there:
|
||
- `components/account/personaldetailsCheck.js`
|
||
- `components/account/personaldetailsComplete.js`
|
||
|
||
##### Likely service helpers
|
||
|
||
- `actions/services/accountDirectService.js`
|
||
- `getPersonalAccount`
|
||
- `updateAccount`
|
||
- `getPortalLogin` as identity/bootstrap adjacent helper
|
||
|
||
##### API routes
|
||
|
||
- `pages/api/endpoint/getpersonalaccount_api.js`
|
||
- `pages/api/endpoint/updateaccount_api.js`
|
||
- adjacent account/auth-support routes often relevant during investigation:
|
||
- `getportallogin_api.js`
|
||
- `getemailaccountcheck_api.js`
|
||
- `updatepassword_api.js`
|
||
|
||
##### Shared clients/helpers
|
||
|
||
- `relayGet(...)`
|
||
- `respondError(...)` / `respondSuccess(...)`
|
||
- `getToken()`
|
||
- `hashAPIPath(...)`
|
||
- signed request / relay client helpers in the service layer
|
||
|
||
##### State/store modules
|
||
|
||
- `store/accountDetails/action.js`
|
||
- `setAccountDetails`
|
||
- `setLoggedInUserId`
|
||
|
||
##### External integration touched
|
||
|
||
- CRM relay
|
||
- NextAuth (session presence at page level)
|
||
- local-only state/helpers
|
||
|
||
#### 3. Public document retrieval
|
||
|
||
##### Primary UI/component entry points
|
||
|
||
- `components/search/searchresults.js` and related search flows as user discovery entry points
|
||
- document metadata/search document routes act as upstream API entry before download
|
||
|
||
##### Likely service helpers
|
||
|
||
- `actions/services/searchDirectService.js`
|
||
- `getSearchDocumentDetails`
|
||
- related search document retrieval helpers
|
||
|
||
##### API routes
|
||
|
||
- `pages/api/endpoint/getsearchdocumentdetails_api.js`
|
||
- `pages/api/endpoint/getsearchdocumentdetailspaged_api.js`
|
||
- `pages/api/endpoint/getsearchdocumenthistory_api.js`
|
||
- `pages/api/endpoint/getsearchdocumenthistorypaged_api.js`
|
||
- `pages/api/endpoint/getsearchdocumentTypes_api.js`
|
||
- `pages/api/documents/download/[id].js`
|
||
|
||
##### Shared clients/helpers
|
||
|
||
- `relayGet(...)`
|
||
- `respondError(...)`
|
||
- document hash-link generation logic using HMAC/hash helpers
|
||
- `getToken()` inside direct download proxy
|
||
- `consoleLogger(...)`
|
||
|
||
##### State/store modules
|
||
|
||
- usually lighter direct store involvement than account/watched cases
|
||
- search result/detail state may still be relevant through search result flows
|
||
|
||
##### External integration touched
|
||
|
||
- CRM relay
|
||
- local-only helper logic
|
||
|
||
#### 4. Appeal submission / finalisation
|
||
|
||
##### Primary UI/component entry points
|
||
|
||
- `pages/myportal/[appealtypes].js` as journey page entry
|
||
- `lib/myportal/loadMyPortalAppealPage.js` as key journey loader
|
||
- adjacent finalisation/completion UI evidence from completion components and journey state transitions
|
||
|
||
##### Likely service helpers
|
||
|
||
- `actions/services/documentDirectService.js`
|
||
- `getFilesFromBlob`
|
||
- `getProgressFromBlob`
|
||
- `getAwaitingSubmissionFromBlob`
|
||
- `actions/services/accountDirectService.js`
|
||
- `getPersonalAccount`
|
||
- route-adjacent helpers in storage layer:
|
||
- `actions/azurestorage.js`
|
||
|
||
##### API routes
|
||
|
||
- `pages/api/file/createappealcompletemessage_api.js`
|
||
- `pages/api/file/createappealcompletemessageproxy_api.js`
|
||
- `pages/api/endpoint/createcase_api.js`
|
||
- `pages/api/endpoint/patchcase_api.js`
|
||
- `pages/api/endpoint/updatecase_api.js`
|
||
- adjacent draft/blob routes usually relevant:
|
||
- `pages/api/file/getbloblist.js`
|
||
- `pages/api/file/getprogressobjblob.js`
|
||
- `pages/api/file/upload.js`
|
||
- `pages/api/file/deleteblobcase.js`
|
||
|
||
##### Shared clients/helpers
|
||
|
||
- Azure storage helpers (`getCaseBlob`, progress/blob helpers, completion-message helpers)
|
||
- `respondError(...)` / `respondSuccess(...)`
|
||
- `hashAPIPath(...)`
|
||
- `relayGet(...)` and direct-wrapper mutation patterns
|
||
- route-builder/signed-request helpers in services
|
||
- loader guards in `lib/myportal/loadMyPortalAppealPage.js`
|
||
|
||
##### State/store modules
|
||
|
||
- `store/accountDetails/*`
|
||
- `store/appealType/*`
|
||
- `store/currentView/*`
|
||
- `store/awaitingSubmission/*`
|
||
- `store/formData/*` as adjacent journey support
|
||
|
||
##### External integration touched
|
||
|
||
- Azure Storage
|
||
- Azure Queue / completion handoff
|
||
- CRM relay
|
||
- local-only state/helpers
|
||
|
||
### Route Ownership Classification
|
||
|
||
#### Watched cases journey
|
||
|
||
- `getwatchedcases_api`
|
||
- **feature-owned** by watched cases
|
||
- integration: CRM relay
|
||
- `getwatchedcasesproxy_api`
|
||
- **ambiguous/historical**
|
||
- integration: CRM relay
|
||
- `createwatchedcases_api`
|
||
- **orchestration-owned** by watched cases
|
||
- integrations: CRM relay, helper/read pre-check
|
||
- `deletewatchedcases_api`
|
||
- **feature-owned** by watched cases
|
||
- integration: CRM relay
|
||
- `deletewatchedcasesproxy_api`
|
||
- **ambiguous/historical**
|
||
- integration: CRM relay
|
||
|
||
#### Account / personal details journey
|
||
|
||
- `getpersonalaccount_api`
|
||
- **feature-owned** by account/profile
|
||
- integration: CRM relay
|
||
- `updateaccount_api`
|
||
- **feature-owned** by account/profile
|
||
- integration: CRM relay
|
||
- `getportallogin_api`
|
||
- **helper/support** for account/auth bootstrap
|
||
- integration: CRM relay
|
||
- `getemailaccountcheck_api`
|
||
- **helper/support** for registration/account support
|
||
- integration: CRM relay
|
||
- `updatepassword_api`
|
||
- **ambiguous/historical** in current live account journey terms
|
||
- integration: CRM relay
|
||
|
||
#### Public document retrieval journey
|
||
|
||
- `getsearchdocumentdetails_api`
|
||
- **feature-owned** by public document retrieval/search detail
|
||
- integration: CRM relay
|
||
- `getsearchdocumentdetailspaged_api`
|
||
- **feature-owned** by public document retrieval/search detail
|
||
- integration: CRM relay
|
||
- `getsearchdocumenthistory_api`
|
||
- **feature-owned** by public document retrieval/history
|
||
- integration: CRM relay
|
||
- `getsearchdocumenthistorypaged_api`
|
||
- **feature-owned** by public document retrieval/history
|
||
- integration: CRM relay
|
||
- `getsearchdocumentTypes_api`
|
||
- **helper/support** for document retrieval/search filtering
|
||
- integration: CRM relay
|
||
- `documents/download/[id].js`
|
||
- **integration-owned** download proxy used by public document retrieval
|
||
- integration: CRM relay
|
||
|
||
#### Appeal submission / finalisation journey
|
||
|
||
- `createappealcompletemessage_api`
|
||
- **orchestration-owned** by appeal finalisation
|
||
- integrations: Azure Storage, Azure Queue/finalisation, CRM/account side effect
|
||
- `createappealcompletemessageproxy_api`
|
||
- **helper/support** or **ambiguous/historical** compatibility wrapper
|
||
- integrations: local proxy + file/finalisation path
|
||
- `createcase_api`
|
||
- **orchestration-owned** by appeal submission
|
||
- integrations: CRM relay, Azure Storage side effect
|
||
- `patchcase_api`
|
||
- **feature-owned** by appeal submission/final transition
|
||
- integration: CRM relay
|
||
- `updatecase_api`
|
||
- **feature-owned** by appeal mutation/submission support
|
||
- integration: CRM relay
|
||
- draft/blob support routes (`getbloblist`, `getprogressobjblob`, `upload`, `deleteblobcase`)
|
||
- **integration-owned** storage support for the appeal draft/finalisation journey
|
||
- integration: Azure Storage
|
||
|
||
### Change Risk Classification
|
||
|
||
#### Watched cases
|
||
|
||
- **Risk:** high
|
||
|
||
Reason:
|
||
|
||
- multiple UI entry points
|
||
- CRM read + create/delete paths
|
||
- feature state refreshed after mutation
|
||
- proxy and non-proxy variants add maintenance ambiguity
|
||
|
||
#### Account / personal details
|
||
|
||
- **Risk:** high
|
||
|
||
Reason:
|
||
|
||
- account/profile contracts are user-critical
|
||
- session/bootstrap and CRM profile identity are tightly coupled
|
||
- mutation route is simple in code shape but high impact to users
|
||
|
||
#### Public document retrieval
|
||
|
||
- **Risk:** medium-high
|
||
|
||
Reason:
|
||
|
||
- public users are affected directly
|
||
- metadata, hash-link generation, and download proxy are split across different areas
|
||
- fewer stateful side effects than account/finalisation
|
||
|
||
#### Appeal submission / finalisation
|
||
|
||
- **Risk:** very high
|
||
|
||
Reason:
|
||
|
||
- multiple integrations touched
|
||
- orchestration-heavy
|
||
- draft/blob + submission transition + finalisation behavior
|
||
- contract-critical journey
|
||
- state passed across loaders, services, blob data, and CRM write paths
|
||
|
||
### First-Look Checklists
|
||
|
||
#### Watched cases
|
||
|
||
Before changing this journey, inspect:
|
||
|
||
1. `components/search/searchresults.js` and `components/case/summary.js`
|
||
2. `components/myportal/viewall.js` and `components/myportal/topthree.js`
|
||
3. `actions/services/portalDirectService.js` watched-case helpers
|
||
4. `pages/api/endpoint/{getwatchedcases_api,getwatchedcasesproxy_api,createwatchedcases_api,deletewatchedcases_api}.js`
|
||
5. `store/watchedCases/*` and `store/currentView/*`
|
||
6. Slice B / security-boundary notes touching watched-case identifiers in `context/portal-api-platform-assessment.md`
|
||
|
||
#### Account / personal details
|
||
|
||
Before changing this journey, inspect:
|
||
|
||
1. `pages/account/personaldetails.js`
|
||
2. `components/account/personaldetails.js` and adjacent check/complete components
|
||
3. `actions/services/accountDirectService.js`
|
||
4. `pages/api/endpoint/{getpersonalaccount_api,updateaccount_api}.js`
|
||
5. adjacent bootstrap/support routes: `getportallogin_api.js`, `getemailaccountcheck_api.js`
|
||
6. `store/accountDetails/*`
|
||
|
||
#### Public document retrieval
|
||
|
||
Before changing this journey, inspect:
|
||
|
||
1. search UI entry points that surface document links
|
||
2. `actions/services/searchDirectService.js` search document helpers
|
||
3. `pages/api/endpoint/{getsearchdocumentdetails_api,getsearchdocumenthistory_api,getsearchdocumentTypes_api}.js`
|
||
4. `pages/api/documents/download/[id].js`
|
||
5. any route-local document hash-link generation logic in endpoint/admin/email families
|
||
6. Slice B findings on public read/document contract shapes
|
||
|
||
#### Appeal submission / finalisation
|
||
|
||
Before changing this journey, inspect:
|
||
|
||
1. `lib/myportal/loadMyPortalAppealPage.js`
|
||
2. the page entry and current appeal/draft UI entry points
|
||
3. `actions/services/documentDirectService.js` draft blob helpers
|
||
4. `pages/api/file/createappealcompletemessage_api.js`
|
||
5. `pages/api/endpoint/{createcase_api,patchcase_api,updatecase_api}.js`
|
||
6. `actions/azurestorage.js` completion/blob helpers
|
||
7. `store/{appealType,currentView,awaitingSubmission,accountDetails}/*`
|
||
8. Slice C maintenance-map notes on finalisation folder drift
|
||
|
||
### Reuse Opportunities
|
||
|
||
#### Watched cases
|
||
|
||
- `relayGet(...)` for read routes
|
||
- `relayGetData(...)` for upsert pre-check style behavior
|
||
- `respondSuccess(...)` / `respondError(...)`
|
||
- relay policy presets
|
||
- logging helpers
|
||
- route-builder/query helper patterns in portal services
|
||
|
||
#### Account / personal details
|
||
|
||
- `relayGet(...)` for profile reads
|
||
- `respondSuccess(...)` / `respondError(...)`
|
||
- token/hash helpers in update flows
|
||
- signed/relay client helpers in account service layer
|
||
- logging helpers
|
||
|
||
#### Public document retrieval
|
||
|
||
- `relayGet(...)` for document metadata/history reads
|
||
- `respondError(...)`-style guard handling
|
||
- document hash-link generation logic already present in multiple route families
|
||
- logging helpers
|
||
|
||
#### Appeal submission / finalisation
|
||
|
||
- Azure storage helpers
|
||
- `respondSuccess(...)` / `respondError(...)`
|
||
- hash/path validation helpers
|
||
- direct-wrapper mutation pattern already established in CRM write routes
|
||
- signed request / route builder helpers in service layer
|
||
- loader guard patterns in `lib/myportal/loadMyPortalAppealPage.js`
|
||
|
||
### Risks / Cautions
|
||
|
||
1. **These are first-look entry sets, not exhaustive dependency maps**
|
||
- each journey has adjacent supporting files beyond what is listed here
|
||
2. **UI entry points are distributed**
|
||
- watched cases especially can begin from search results, case pages, and myportal views
|
||
3. **Route ownership is sometimes mixed or historical**
|
||
- proxy and finalisation routes especially need careful interpretation
|
||
4. **Submission/finalisation should be treated as the most sensitive sampled journey**
|
||
- storage, queue/finalisation, and CRM boundaries all meet there
|
||
5. **Account and watched-case journeys rely on earlier identity/bootstrap context**
|
||
- a maintainer may need to inspect SSR/session/bootstrap files even when changing a single API route
|
||
|
||
### Validation performed
|
||
|
||
Manual inspection and bounded searches only.
|
||
|
||
Performed:
|
||
|
||
- re-read required Slice D context files
|
||
- targeted bounded searches across `components`, `actions/services`, `pages`, `lib`, and `store` for the four sampled journeys
|
||
- direct file inspection of representative first-look journey files including:
|
||
- `components/myportal/viewall.js`
|
||
- `pages/account/personaldetails.js`
|
||
- `components/account/personaldetails.js`
|
||
- `components/search/searchresults.js`
|
||
- `lib/myportal/loadMyPortalAppealPage.js`
|
||
- `components/case/representation/representationComplete.js`
|
||
- reuse of already reviewed route/service evidence from Slices A–C for linked API ownership and building-block classification
|
||
|
||
Not performed:
|
||
|
||
- no full dependency inventory
|
||
- no repo-wide automated analysis
|
||
- no Python
|
||
- no runtime code changes
|
||
- no lint/tests, because this remains documentation-only assessment work
|
||
|
||
### Recommendation
|
||
|
||
Next bounded assessment step only:
|
||
|
||
#### Slice E — API Maintainer Decision Guide Sample
|
||
|
||
Focus on a small sample of common maintenance intents, such as:
|
||
|
||
- adding a new CRM read route
|
||
- extending a watched-case style mutation
|
||
- adding a document-related route
|
||
- extending a finalisation-side orchestration path
|
||
|
||
Goal:
|
||
|
||
- document which current patterns a maintainer would most likely copy or reuse
|
||
- identify which existing patterns appear preferred vs legacy-for-compatibility
|
||
- remain assessment-only
|
||
|
||
---
|
||
|
||
## Slice E — Wider API Surface Pattern Validation
|
||
|
||
### Required context read
|
||
|
||
The following files were re-read before Slice E:
|
||
|
||
- `context/portal-api-platform-assessment.md`
|
||
- `context/architecture.md`
|
||
- `context/integration-map.md`
|
||
- `memory-bank/change-log.md`
|
||
|
||
### Findings
|
||
|
||
The wider validation pass supports the earlier assessment model.
|
||
|
||
The API surface is large in file count, but the underlying vocabulary still appears relatively small:
|
||
|
||
- **large route surface**
|
||
- **small contract vocabulary**
|
||
- **small implementation-style vocabulary**
|
||
- **main maintenance issue remains findability and ownership**
|
||
|
||
The folder scan and outlier checks did **not** reveal a major additional platform family that would overturn Slices A–D.
|
||
|
||
Instead, the wider surface mostly reinforces that:
|
||
|
||
1. `pages/api/endpoint` contains the majority of CRM-facing route variants
|
||
2. `pages/api/file` is the main secondary mixed folder where storage plus orchestration concerns accumulate
|
||
3. most routes still fit the previously identified contract shapes and implementation styles
|
||
4. the main uncertainty is not “unknown route technology” but “where a maintainer should look first”
|
||
|
||
### Folder-Level Validation
|
||
|
||
Approximate file counts from the bounded listing/count pass:
|
||
|
||
- `pages/api/endpoint` -> **74** files
|
||
- `pages/api/file` -> **26** files
|
||
- `pages/api/email` -> **6** files
|
||
- `pages/api/documents` -> **1** file
|
||
- `pages/api/auth` -> **2** files
|
||
- `pages/api/admin` -> **5** files
|
||
- `pages/api/middleware` -> **4** files
|
||
- top-level `pages/api` files -> **4**
|
||
|
||
#### `pages/api/endpoint`
|
||
|
||
- **Approximate size:** very large
|
||
- **Apparent responsibility:** CRM relay-facing portal/business-data API catch-all
|
||
- **Do Slice A–D findings still appear representative?** yes
|
||
- **Unexpected route families?** no major new family found
|
||
|
||
Validation note:
|
||
|
||
- route names continue to cluster around search/read, myportal reads, document metadata, account/profile, create/update/delete, lookup/config, and proxy variants
|
||
|
||
#### `pages/api/file`
|
||
|
||
- **Approximate size:** medium-large
|
||
- **Apparent responsibility:** storage/blob routes plus draft/finalisation and some CRM-adjacent orchestration
|
||
- **Do Slice A–D findings still appear representative?** yes
|
||
- **Unexpected route families?** no major new family, but PDF-generation and involvement routes reinforce the mixed/orchestration character
|
||
|
||
Validation note:
|
||
|
||
- outlier review (`createcaseinvolvement_api.js`, `generateappealpdf.js`) still fits the same mixed file/storage/orchestration pattern already documented
|
||
|
||
#### `pages/api/email`
|
||
|
||
- **Approximate size:** small
|
||
- **Apparent responsibility:** Notify send plus document/event/list aggregation for email workflows
|
||
- **Do Slice A–D findings still appear representative?** yes
|
||
- **Unexpected route families?** no
|
||
|
||
Validation note:
|
||
|
||
- `getdocuments.js` reinforces that email routes often combine CRM read + document-link generation + downstream notification support rather than introducing a new route family
|
||
|
||
#### `pages/api/documents`
|
||
|
||
- **Approximate size:** very small
|
||
- **Apparent responsibility:** direct document download proxy
|
||
- **Do Slice A–D findings still appear representative?** yes
|
||
- **Unexpected route families?** no
|
||
|
||
#### `pages/api/auth`
|
||
|
||
- **Approximate size:** very small
|
||
- **Apparent responsibility:** auth/session and locale support
|
||
- **Do Slice A–D findings still appear representative?** yes
|
||
- **Unexpected route families?** no
|
||
|
||
#### `pages/api/admin`
|
||
|
||
- **Approximate size:** small
|
||
- **Apparent responsibility:** internal/admin reporting and grouped CRM read views
|
||
- **Do Slice A–D findings still appear representative?** yes
|
||
- **Unexpected route families?** no
|
||
|
||
Validation note:
|
||
|
||
- `getStatusCountsByAppealAndLPA_api.js` strengthens the view that admin routes are mostly grouped reporting/read transforms over CRM relay data
|
||
|
||
#### `pages/api/middleware`
|
||
|
||
- **Approximate size:** very small
|
||
- **Apparent responsibility:** shared API support and relay/runtime helper logic
|
||
- **Do Slice A–D findings still appear representative?** yes
|
||
- **Unexpected route families?** no
|
||
|
||
#### Top-level API routes
|
||
|
||
- **Approximate size:** very small
|
||
- **Apparent responsibility:** health/meta/static support
|
||
- **Do Slice A–D findings still appear representative?** yes
|
||
- **Unexpected route families?** no
|
||
|
||
### Route Family Validation
|
||
|
||
Previously identified route families still appear to cover the wider surface:
|
||
|
||
- search/read
|
||
- myportal reads
|
||
- account/profile
|
||
- create/update/delete
|
||
- document retrieval
|
||
- storage/blob
|
||
- queue/finalisation
|
||
- notifications
|
||
- admin/reporting
|
||
- auth/session
|
||
- lookup/config/support
|
||
|
||
Additional observations from wider route-name validation:
|
||
|
||
- static/local support data routes such as `getmandatoryfields_api`, `getpicklists_api`, and `getappealtypesfornewappeal_api` are better treated as part of the already-documented **lookup/config/support** family rather than a genuinely new family
|
||
- CRM task/contact routes such as `createcrmtask_api.js` fit the existing **CRM create/write** family
|
||
- involvement routes under `file/` fit the existing **orchestration-owned CRM-related mutation** pattern already noted in earlier slices
|
||
- PDF-generation routes under `file/` fit the existing **storage/document generation orchestration** pattern rather than requiring a wholly separate top-level family
|
||
|
||
Assessment:
|
||
|
||
- **no genuinely new major route family identified**
|
||
|
||
### Contract Shape Validation
|
||
|
||
The previously identified contract shapes still appear sufficient for most of the wider surface:
|
||
|
||
- Public CRM read
|
||
- User-owned CRM read
|
||
- CRM create
|
||
- CRM update/patch
|
||
- CRM delete
|
||
- Proxy/pass-through
|
||
- Lookup/config/support
|
||
- Hybrid upsert/orchestration
|
||
|
||
Additional validation insight:
|
||
|
||
- local/static JSON/data support routes (`getmandatoryfields_api`, `getpicklists_api`) fit comfortably within **lookup/config/support**
|
||
- admin grouped-reporting routes fit as **CRM read + transform** rather than a separate contract family
|
||
- file-side involvement and PDF routes fit as **orchestration** or **support** variants rather than forcing a new contract class
|
||
|
||
Assessment:
|
||
|
||
- **these contract shapes appear to cover most routes**
|
||
- no additional mandatory contract shape is currently required for the architecture model
|
||
|
||
### Implementation Style Validation
|
||
|
||
The implementation-style model also still holds:
|
||
|
||
#### 1. Helper-oriented relay routes
|
||
|
||
Still strongly present, especially in `endpoint/` and modern admin/reporting reads.
|
||
|
||
Indicators:
|
||
|
||
- `relayGet(...)`
|
||
- `relayGetData(...)`
|
||
- `respondError(...)` / `respondSuccess(...)`
|
||
- relay policy presets
|
||
|
||
#### 2. Direct-wrapper routes
|
||
|
||
Still strongly present, especially for CRM create/update/delete and some file-side CRM mutations.
|
||
|
||
Indicators:
|
||
|
||
- `getToken()`
|
||
- route-local `queryUrl`
|
||
- `WEBAPI_URL + queryUrl + hashAPIPath(queryUrl)`
|
||
- direct `axios(config)`
|
||
|
||
#### 3. Orchestration routes
|
||
|
||
Still clearly present in:
|
||
|
||
- `file/` completion/finalisation
|
||
- PDF generation
|
||
- involvement creation
|
||
- email-side aggregation routes
|
||
|
||
Additional major implementation style found?
|
||
|
||
- **No**
|
||
|
||
Closest extra pattern:
|
||
|
||
- local/static support routes using in-repo JSON/data reads
|
||
|
||
But this is better treated as a small **support variant**, not a fourth major implementation style.
|
||
|
||
### Folder Drift Validation
|
||
|
||
#### `pages/api/documents`
|
||
|
||
- **Drift:** low
|
||
- **Reason:** narrow folder name still matches actual responsibility closely
|
||
|
||
#### `pages/api/auth`
|
||
|
||
- **Drift:** low to moderate
|
||
- **Reason:** still mostly coherent, though CRM locale and Notify behavior cross the folder boundary conceptually
|
||
|
||
#### `pages/api/admin`
|
||
|
||
- **Drift:** low
|
||
- **Reason:** sampled routes still align with internal/admin reporting responsibility
|
||
|
||
#### `pages/api/middleware`
|
||
|
||
- **Drift:** low
|
||
- **Reason:** folder remains clearly reuse/support oriented
|
||
|
||
#### Top-level API routes
|
||
|
||
- **Drift:** low
|
||
- **Reason:** health/meta/static support usage remains straightforward
|
||
|
||
#### `pages/api/email`
|
||
|
||
- **Drift:** moderate
|
||
- **Reason:** naming suggests email-only behavior, but actual routes can perform CRM/document/event aggregation before notification send
|
||
|
||
#### `pages/api/file`
|
||
|
||
- **Drift:** high
|
||
- **Reason:** storage/blob naming no longer fully describes draft orchestration, finalisation, involvement creation, PDF generation, and CRM-adjacent journey behavior housed there
|
||
|
||
#### `pages/api/endpoint`
|
||
|
||
- **Drift:** high
|
||
- **Reason:** folder behaves as the historical general-purpose CRM relay catch-all rather than a clearly bounded current responsibility area
|
||
|
||
### Maintenance Hotspots
|
||
|
||
#### `pages/api/endpoint`
|
||
|
||
- **Hotspot level:** high
|
||
|
||
Reason:
|
||
|
||
- highest route count
|
||
- mixed business responsibilities
|
||
- helper-oriented and direct-wrapper styles coexist
|
||
- many contract-critical routes
|
||
- ownership ambiguity highest here
|
||
|
||
#### `pages/api/file`
|
||
|
||
- **Hotspot level:** high
|
||
|
||
Reason:
|
||
|
||
- second-largest route area
|
||
- storage + orchestration + finalisation mixed together
|
||
- touches high-risk flows and multiple integrations
|
||
|
||
#### `pages/api/email`
|
||
|
||
- **Hotspot level:** medium
|
||
|
||
Reason:
|
||
|
||
- smaller route count, but orchestration overlap can surprise maintainers
|
||
|
||
#### `pages/api/admin`
|
||
|
||
- **Hotspot level:** medium-low
|
||
|
||
Reason:
|
||
|
||
- coherent but still CRM-transform heavy
|
||
|
||
#### `pages/api/auth`
|
||
|
||
- **Hotspot level:** medium-high
|
||
|
||
Reason:
|
||
|
||
- low file count, but highly sensitive behavior and cross-cutting auth/session implications
|
||
|
||
#### `pages/api/documents`
|
||
|
||
- **Hotspot level:** low
|
||
|
||
Reason:
|
||
|
||
- very small, narrow responsibility
|
||
|
||
#### `pages/api/middleware`
|
||
|
||
- **Hotspot level:** medium-high
|
||
|
||
Reason:
|
||
|
||
- tiny surface, but shared helper impact is wide and mistakes would propagate broadly
|
||
|
||
### Confidence Assessment
|
||
|
||
#### Representativeness of Slices A–D
|
||
|
||
- **Confidence:** high confidence
|
||
|
||
Why:
|
||
|
||
1. folder-size validation shows the biggest unknown risk area was `endpoint/`, and that area has already been sampled repeatedly across earlier slices
|
||
2. `file/` outlier checks still fit the previously identified mixed storage/orchestration model
|
||
3. smaller folders (`email`, `documents`, `auth`, `admin`, `middleware`) did not reveal materially new route families or implementation styles
|
||
4. the outlier review found support variants and special cases, but not a new dominant architectural pattern
|
||
|
||
Residual caution:
|
||
|
||
- confidence is high at the **platform pattern** level, not at the full-route behavioral nuance level
|
||
|
||
### Risks / Cautions
|
||
|
||
1. **This remains a pattern-validation pass, not a full inventory**
|
||
- there may still be route-local nuances not captured here
|
||
2. **High confidence does not mean all individual routes are equivalent**
|
||
- some outlier handlers still have special transforms, signing rules, or side effects
|
||
3. **Folder-level conclusions should not be mistaken for migration recommendations**
|
||
- this slice validates representativeness, not reorganisation scope
|
||
4. **The biggest remaining maintenance risk is still ownership ambiguity**
|
||
- especially in `endpoint/` and `file/`
|
||
|
||
### Validation performed
|
||
|
||
Manual inspection and bounded searches only.
|
||
|
||
Performed:
|
||
|
||
- re-read required Slice E context files
|
||
- bounded folder-size count pass across top-level API folders
|
||
- targeted route-name searches inside `endpoint`, `file`, and `pages/api` to validate naming families and implementation indicators
|
||
- direct representative inspection of selected outlier-style routes, including:
|
||
- `pages/api/endpoint/getmandatoryfields_api.js`
|
||
- `pages/api/endpoint/createcrmtask_api.js`
|
||
- `pages/api/file/createcaseinvolvement_api.js`
|
||
- `pages/api/file/generateappealpdf.js`
|
||
- `pages/api/email/getdocuments.js`
|
||
- `pages/api/admin/getStatusCountsByAppealAndLPA_api.js`
|
||
- reuse of conclusions and evidence from Slices A–D for comparison
|
||
|
||
Not performed:
|
||
|
||
- no full route inventory
|
||
- no repo-wide automated analysis
|
||
- no Python
|
||
- no scripts
|
||
- no runtime code changes
|
||
- no lint/tests, because this remains documentation-only assessment work
|
||
|
||
### Architectural Conclusion
|
||
|
||
The existing API platform model is now considered **representative of the wider API surface at the pattern level**.
|
||
|
||
Current architectural conclusion:
|
||
|
||
- the wider API surface does **not** appear to require a materially different platform model from Slices A–D
|
||
- the earlier findings generalise well:
|
||
- `endpoint/` is the dominant historical CRM relay catch-all
|
||
- `file/` is the main secondary mixed storage/orchestration area
|
||
- route families largely collapse into a limited contract vocabulary
|
||
- implementation styles largely collapse into helper-oriented, direct-wrapper, and orchestration styles
|
||
- the primary maintainability issue remains **findability and ownership**, not discovery of a fundamentally different API architecture
|
||
|
||
### Recommendation
|
||
|
||
Next bounded assessment step only:
|
||
|
||
#### Slice F — API Platform Final Synthesis
|
||
|
||
Goal:
|
||
|
||
- consolidate Slices A–E into one concise architecture-level API platform view
|
||
- state the stable route family model, contract model, implementation-style model, drift model, and maintainer guidance baseline
|
||
- remain assessment-only
|
||
|
||
---
|
||
|
||
## Slice F — API Platform Final Synthesis
|
||
|
||
### Programme status
|
||
|
||
```text
|
||
Portal Integration Contract & API Platform Assessment
|
||
Status: COMPLETE
|
||
```
|
||
|
||
Closure is supported by the existing evidence because:
|
||
|
||
- Slices A–E established a stable route-family model
|
||
- the wider validation pass reached high confidence at the platform pattern level
|
||
- no materially different API platform family or implementation model emerged during bounded wider-surface validation
|
||
|
||
### Executive Summary
|
||
|
||
The PEDW API platform is large in route count but smaller in underlying structure than the file count first suggests.
|
||
|
||
At a platform level it can be understood as:
|
||
|
||
```text
|
||
~120 route files
|
||
↓
|
||
small route-family vocabulary
|
||
↓
|
||
small contract-shape vocabulary
|
||
↓
|
||
small implementation-style vocabulary
|
||
```
|
||
|
||
The API platform therefore feels large primarily because:
|
||
|
||
- route files are numerous
|
||
- route naming has grown historically
|
||
- folder responsibility has drifted unevenly
|
||
- feature ownership is not always obvious from folder or file name alone
|
||
- older and newer implementation styles coexist
|
||
|
||
The main maintenance problem is not discovery of a fundamentally different API architecture.
|
||
|
||
The main maintenance problem is:
|
||
|
||
- **findability**
|
||
- **ownership clarity**
|
||
- **consistency and reuse discipline**
|
||
|
||
### Final API Platform Model
|
||
|
||
Stable architecture-level model:
|
||
|
||
- the dominant platform family is still **CRM relay-backed portal APIs**
|
||
- the main secondary platform family is **storage/blob plus draft/finalisation orchestration**
|
||
- notification, auth, documents, admin, and middleware form smaller supporting families
|
||
- route count overstates structural diversity because many routes are variants of repeated contract shapes
|
||
- the platform is mixed but explainable once grouped by route family, contract shape, and implementation style
|
||
|
||
### Route-Family Model
|
||
|
||
The stable route-family model is:
|
||
|
||
#### 1. CRM relay routes
|
||
|
||
- mainly under `pages/api/endpoint`
|
||
- includes search, myportal reads, account/profile reads, lookups, and CRM mutations
|
||
|
||
#### 2. Storage/blob routes
|
||
|
||
- mainly under `pages/api/file`
|
||
- includes blob listing, upload, delete, progress, and draft file handling
|
||
|
||
#### 3. Finalisation/orchestration routes
|
||
|
||
- concentrated in `pages/api/file`, with supporting CRM mutation routes in `endpoint`
|
||
- includes draft-to-submission transitions, completion-message flows, PDF generation, and related side effects
|
||
|
||
#### 4. Email/notification routes
|
||
|
||
- mainly under `pages/api/email`
|
||
- includes thin Notify send routes and broader aggregation/orchestration routes
|
||
|
||
#### 5. Document download routes
|
||
|
||
- mainly under `pages/api/documents`
|
||
- narrow published-document download proxy behavior
|
||
|
||
#### 6. Auth/session routes
|
||
|
||
- mainly under `pages/api/auth`
|
||
- includes NextAuth/session behavior and locale-aware auth support
|
||
|
||
#### 7. Admin/internal routes
|
||
|
||
- mainly under `pages/api/admin`
|
||
- grouped CRM reporting/read transforms for internal/admin use
|
||
|
||
#### 8. Middleware/helper routes
|
||
|
||
- under `pages/api/middleware`
|
||
- response helpers, relay forwarding, multipart support, retry/policy helpers
|
||
|
||
#### 9. Local utility/meta routes
|
||
|
||
- top-level API utility files and a few support-style routes
|
||
- health, docs/static/meta support, and local/config data reads
|
||
|
||
### Contract-Shape Model
|
||
|
||
The stable contract-shape model is:
|
||
|
||
#### CRM-facing 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/finalisation/notification shapes
|
||
|
||
- Storage read/write/delete
|
||
- Queue/finalisation
|
||
- Notify send / notification orchestration
|
||
|
||
Assessment note:
|
||
|
||
- these shapes are sufficient to explain most of the observed API surface
|
||
- many apparent route differences are variants of one of these shapes rather than separate architectural categories
|
||
|
||
### Implementation-Style Model
|
||
|
||
The stable implementation-style model consists of three main styles.
|
||
|
||
#### 1. Newer helper-oriented
|
||
|
||
Typical indicators:
|
||
|
||
- `relayGet(...)`
|
||
- `relayGetData(...)`
|
||
- `respondSuccess(...)`
|
||
- `respondError(...)`
|
||
- relay policy presets
|
||
|
||
Typical fit:
|
||
|
||
- CRM read routes
|
||
- proxy/read routes
|
||
- grouped read/transform routes
|
||
|
||
#### 2. Older direct-wrapper
|
||
|
||
Typical indicators:
|
||
|
||
- `getToken()`
|
||
- direct `axios(config)`
|
||
- manual `WEBAPI_URL + queryUrl + hashAPIPath(queryUrl)`
|
||
|
||
Typical fit:
|
||
|
||
- CRM create/update/delete wrappers
|
||
- some file-side CRM mutation helpers
|
||
|
||
Assessment note:
|
||
|
||
- these patterns are not “wrong”; they reflect prior delivery needs and stable historical route construction
|
||
- the main maintainability question is whether they should be copied forward into new work when shared helpers now exist
|
||
|
||
#### 3. Orchestration-heavy
|
||
|
||
Typical fit:
|
||
|
||
- finalisation routes
|
||
- email aggregation routes
|
||
- storage + queue + CRM side-effect routes
|
||
- PDF generation and file-adjacent journey transitions
|
||
|
||
Assessment note:
|
||
|
||
- these routes are structurally important because they cross integration boundaries and often sit at contract-critical workflow transitions
|
||
|
||
### Folder Drift Model
|
||
|
||
Folder drift affects maintainability because folder name and actual responsibility do not always align.
|
||
|
||
#### Low drift
|
||
|
||
- `documents`
|
||
- `admin`
|
||
- `middleware`
|
||
- top-level utility/meta
|
||
|
||
These are relatively easy to find and reason about.
|
||
|
||
#### Low / moderate drift
|
||
|
||
- `auth`
|
||
|
||
The folder is still coherent, but auth behavior crosses into CRM and Notify concerns.
|
||
|
||
#### Moderate drift
|
||
|
||
- `email`
|
||
|
||
The folder name suggests email-only work, but some routes perform CRM/document/event aggregation before notification send.
|
||
|
||
#### High drift
|
||
|
||
- `endpoint`
|
||
- `file`
|
||
|
||
Why this matters:
|
||
|
||
- `endpoint` behaves as a historical general-purpose CRM relay catch-all
|
||
- `file` now contains blob/storage behavior, draft support, finalisation, involvement creation, PDF generation, and CRM-adjacent orchestration
|
||
- this drift increases scan cost and weakens ownership clarity
|
||
|
||
### Maintenance Hotspots
|
||
|
||
#### High
|
||
|
||
- `pages/api/endpoint`
|
||
- `pages/api/file`
|
||
|
||
Why:
|
||
|
||
- highest route concentration
|
||
- mixed responsibilities
|
||
- mixed implementation styles
|
||
- many contract-critical routes
|
||
- ownership ambiguity is strongest here
|
||
|
||
#### Medium-high
|
||
|
||
- `pages/api/auth`
|
||
- `pages/api/middleware`
|
||
|
||
Why:
|
||
|
||
- small surfaces but high leverage and high sensitivity
|
||
- mistakes there can have broad downstream effects
|
||
|
||
#### Medium
|
||
|
||
- `pages/api/email`
|
||
|
||
Why:
|
||
|
||
- route count is small, but orchestration overlap makes behavior less obvious than the folder name suggests
|
||
|
||
#### Lower
|
||
|
||
- `pages/api/documents`
|
||
- `pages/api/admin`
|
||
|
||
Why:
|
||
|
||
- narrower and more coherent responsibilities
|
||
- still important, but less structurally confusing than `endpoint` and `file`
|
||
|
||
### Maintainer Guidance Baseline
|
||
|
||
For future API work, the stable baseline should be:
|
||
|
||
1. **Identify the owning feature or journey first**
|
||
- do not start from route name alone if the flow is contract-critical
|
||
2. **Identify the integration touched**
|
||
- CRM relay, Azure Storage, Azure Queue/finalisation, Notify, NextAuth, or local-only support
|
||
3. **Identify contract-criticality before editing**
|
||
- public search, myportal, file handling, document delivery, auth/session, and finalisation need higher caution
|
||
4. **Prefer existing shared helpers where suitable**
|
||
- especially for CRM read routes and standardized response handling
|
||
5. **Prefer `respondSuccess(...)` / `respondError(...)` for new JSON responses**
|
||
6. **Prefer helper-oriented relay reads for new CRM reads where appropriate**
|
||
7. **Reuse storage helpers and established hash validation patterns for storage APIs**
|
||
8. **Keep Notify routes thin unless orchestration is genuinely required**
|
||
9. **Do not blindly copy older direct-wrapper patterns into new work**
|
||
10. **Do not refactor stable legacy routes without explicit approval and characterization**
|
||
|
||
### What Is Proven / Not Proven
|
||
|
||
#### Proven
|
||
|
||
- Slices A–E are representative at the API platform pattern level
|
||
- route count overstates true structural diversity
|
||
- the main maintenance issue is findability and ownership
|
||
- a small number of repeated contract and implementation patterns explain most routes
|
||
|
||
#### Not Proven
|
||
|
||
- no full route-by-route inventory was produced
|
||
- no consolidation safety assessment has been performed
|
||
- no implementation readiness has been approved
|
||
- no route movement or removal is recommended yet
|
||
|
||
### Recommendation
|
||
|
||
The Portal Integration Contract & API Platform Assessment should now be considered **complete**.
|
||
|
||
Recommended future planning stream only:
|
||
|
||
- **API Route Map / Maintainer Guide**
|
||
|
||
or
|
||
|
||
- **API Rationalisation Planning**
|
||
|
||
But only as a future planning stream.
|
||
|
||
No implementation work is recommended from this assessment alone.
|