Merged PR 2427: update api facade

Related work items: #23754
This commit is contained in:
Robert Bond
2026-06-25 08:11:14 +00:00
parent 5483c4cdf2
commit 153f0d679e
9 changed files with 1839 additions and 4 deletions
+4 -4
View File
@@ -85,7 +85,7 @@ export const getRepresentationsProxy = (incidentID) => {
};
export const getWatchedCases = (loggedInUserId) => {
const route = buildFileQuery("/api/endpoint/getwatchedcases_api", {
const route = buildFileQuery("/api/subscriptions/get-watched-cases", {
loggedInUserId
});
@@ -95,7 +95,7 @@ export const getWatchedCases = (loggedInUserId) => {
};
export const getWatchedCasesProxy = (loggedInUserId) => {
const route = buildFileQuery("/api/endpoint/getwatchedcasesproxy_api", {
const route = buildFileQuery("/api/subscriptions/get-watched-cases-proxy", {
loggedInUserId
});
@@ -129,7 +129,7 @@ export const getAwaitingSubmission = (loggedInUserId) => {
export const createWatchedCases = async (formValues) => {
var data = formValues;
var queryUrl = buildFileQuery("/api/endpoint/createwatchedcases_api");
var queryUrl = buildFileQuery("/api/subscriptions/create-watched-case");
var config = {
method: "post",
@@ -181,7 +181,7 @@ export const deleteAwaitingSubmissions = (incidentID) => {
};
export const deleteWatchedCases = async (watchedCaseID) => {
var queryUrl = buildFileQuery("/api/endpoint/deletewatchedcases_api", {
var queryUrl = buildFileQuery("/api/subscriptions/delete-watched-case", {
watchedCaseID
});
+378
View File
@@ -0,0 +1,378 @@
# API Grouping Adoption Roadmap
## Status
Planning only.
Pilot status update (2026-06-25):
- first additive grouping façade pilot implemented for watched-case APIs under `pages/api/subscriptions/`
- first internal consumer (`actions/services/portalDirectService.js` watched-case methods) now targets the grouped façade routes
- the active watched-case vertical slice now includes grouped adoption for both normal watched-case reads and proxy watched-case reads used by the current UI journey
- legacy watched-case endpoint routes remain canonical and stable
- no old route removal or migration has occurred
- runtime behaviour is intended to remain unchanged because the grouped routes delegate to the existing handlers
This document describes how PEDW could **gradually adopt** the future journey-owned API grouping model over time without disrupting existing functionality.
It is an **architectural roadmap only**.
It does **not** recommend implementation, migration, route movement, route renaming, API deletion, consolidation, contract change, or behaviour change.
---
## Required Context Read
The following files were read before drafting this roadmap:
- `context/api-grouping-plan.md`
- `context/api-route-map.md`
- `context/journey-architecture-map.md`
- `context/portal-api-platform-assessment.md`
- `context/architecture.md`
- `context/integration-map.md`
- `memory-bank/change-log.md`
---
## Files Modified
- `context/api-grouping-adoption-roadmap.md`
- `memory-bank/change-log.md`
---
## Findings
- The completed architecture programme already established that PEDWs API platform is structurally smaller than its route count first suggests.
- The main maintainability problems are already known:
- findability
- ownership clarity
- consistency
- reuse discipline
- The current runtime is stable even though folder ownership is historically mixed.
- The current top-level API shape still reflects historical growth more than clean journey ownership, especially in:
- `pages/api/endpoint`
- `pages/api/file`
- The route map, journey map, and API grouping plan already support a **journey-first conceptual model** without requiring physical route movement.
- The strongest safe planning assumption is therefore:
> PEDW should adopt future journey-owned API grouping gradually through future development guidance, improved documentation, and incremental consistency rather than large-scale migration.
---
## Adoption Philosophy
PEDW should favour **gradual evolution** over large structural change.
Why:
1. The current platform is already live and stable.
2. Many APIs are contract-critical even where current folder ownership is historically inconsistent.
3. Several route families are orchestration-heavy and cross multiple integrations, making physical reorganisation riskier than conceptual reclassification.
4. The completed architecture programme has already shown that the main problem is not missing discovery; it is making ownership and maintainability clearer.
For that reason, PEDW should prefer:
- gradual evolution
- behaviour preservation
- contract preservation
- incremental consistency
- reuse of shared helpers
- documentation-led clarity
over:
- large restructures
- wholesale folder moves
- API rewrites
- mass renaming
- cosmetic reorganisation without delivery value
Adoption guidance:
- existing APIs should remain stable
- existing routes should continue to work
- existing URLs should continue to work
- existing contracts should continue to work
- future grouping should emerge naturally as future work touches relevant areas
---
## Adoption Stages
### Stage 1 — Current State
#### Purpose
Record todays platform as the baseline for future adoption thinking.
#### Current State Summary
- the API platform reflects historical growth
- current top-level folders remain implementation hosts rather than clean business ownership boundaries
- ownership is mixed across business journeys, integrations, and shared support concerns
- the runtime is stable and should be preserved
#### Architecture Notes
- `endpoint/` remains the main historical CRM relay catch-all
- `file/` remains the main secondary storage/orchestration catch-all
- smaller families such as `admin/`, `documents/`, and `auth/` are more coherent, though not always perfectly isolated
- shared helpers and route patterns already exist and provide a safer basis for future consistency than folder movement alone
#### Roadmap Meaning
Stage 1 is not a problem statement that justifies migration.
It is the baseline that explains why PEDW should improve ownership clarity **without destabilising the current runtime**.
---
### Stage 2 — Future Development Guidance
#### Purpose
Guide future API work so that PEDW gradually becomes more journey-owned over time without requiring broad reorganisation.
#### Guidance
- new APIs should naturally follow journey ownership
- new work should start from the journey-owned model before considering current folder habits
- new APIs should reuse existing shared helpers where suitable
- avoid creating additional catch-all folders
- avoid copying historical direct-wrapper patterns where shared helpers already exist
- keep integrations behind journey-owned API boundaries conceptually, even when current files remain where they are
- preserve published-document and draft-storage distinctions
- preserve established auth/session and authorization boundaries
#### Practical Interpretation
This stage does **not** mean:
- move existing routes now
- rename existing routes now
- rewrite older APIs now
It means:
- when future work naturally touches an area, use the future grouping plan as the conceptual ownership guide
- prefer additive clarity over structural churn
#### Proven pilot pattern
- The watched-case subscriptions pilot demonstrates a low-risk adoption shape:
- add grouped façade routes in a journey-owned folder
- delegate directly to the existing canonical handlers
- keep existing routes live and unchanged
- adopt the grouped routes incrementally through a carefully selected internal consumer first
- This should be treated as additive proof of the grouping model, not as rationalisation or deprecation.
#### Incremental adoption proof point
- The first internal consumer adoption is now in place for watched-case methods in `actions/services/portalDirectService.js`.
- For the intended watched-case journey scope, the active vertical slice now covers:
- `getWatchedCases`
- `getWatchedCasesProxy`
- `createWatchedCases`
- `deleteWatchedCases`
- Legacy watched-case endpoint routes remain the canonical implementations behind the façade.
- No route deprecation, removal, or contract migration has occurred.
- This validates that grouped journey-owned routes can be introduced first and then adopted incrementally without changing runtime behaviour.
#### Current pilot completion meaning
- For this pilot, a complete watched-case/subscriptions vertical slice means:
- grouped subscriptions façade routes exist for the active watched-case journey calls
- `actions/services/portalDirectService.js` targets those grouped routes for the active watched-case journey methods
- legacy endpoint handlers remain present and canonical behind the façade
- runtime behaviour remains unchanged through delegation
- `deletewatchedcasesproxy_api` remains a legacy/support route outside the grouped pilot scope because it is not part of the currently adopted normal watched-case service path.
---
### Stage 3 — Documentation Maturity
#### Purpose
Improve maintainability through better documentation and route ownership guidance before any physical restructuring is ever considered.
#### Maturity Outcomes
- improved maintainer guidance
- improved route ownership clarity
- improved discoverability
- improved architectural consistency in how new work is described and reviewed
- better onboarding for contributors who need to understand where to start
#### Examples of Documentation-Led Adoption
- route ownership described by journey rather than folder alone
- shared platform helpers clearly separated from business APIs
- cross-cutting concerns such as auth and notifications documented as cross-cutting rather than forced into one business domain
- future grouping candidates captured as architectural guidance only
#### Important Constraint
This stage improves understanding **without moving routes**.
---
### Stage 4 — Future Opportunities
#### Purpose
Record possible future opportunities that could align with the grouping model if future work naturally justifies them.
#### Possible Future Opportunities
- selective grouping within areas already being changed for other approved reasons
- helper extraction where duplication remains visible
- improved shared platform reuse across journey-owned APIs
- stronger consistency in naming, ownership notes, and maintainer entry guidance
- clearer distinction between journey-owned APIs and shared/platform concerns
#### Constraint
These are **future opportunities only**.
They are not implementation recommendations.
They do not approve:
- route movement
- file movement
- migrations
- refactoring programmes
- API rewrites
---
## Adoption Principles
1. Preserve stable APIs.
2. Preserve contracts.
3. Preserve integrations.
4. Preserve CRM as the source of truth for CRM-owned business data.
5. Preserve Azure Storage ownership boundaries for draft-owned content.
6. Preserve established auth/session and authorization boundaries.
7. Prefer additive improvements.
8. Avoid unnecessary churn.
9. Improve findability first.
10. Improve consistency second.
11. Reuse shared helpers instead of duplicating infrastructure logic.
12. Use journey ownership as the conceptual guide for future work.
13. Consider physical grouping only when future approved work naturally touches an area.
14. Never move APIs solely for cosmetic reasons.
15. Do not force cross-cutting concerns into one journey-owned bucket.
16. Continue treating shared/platform capabilities as shared platform concerns rather than business-domain ownership.
---
## Decision Matrix
| Situation | Guidance |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| New API | Place it conceptually within the journey-owned model first, then implement using the safest existing route/helper patterns. |
| Existing stable API | Leave unchanged. |
| Existing API being enhanced | Consider alignment with journey ownership in documentation and helper usage, without assuming route movement. |
| Shared infrastructure | Keep in shared/platform concern classification. |
| Cross-cutting concern | Avoid forcing it into one journey if its real ownership is platform-wide or multi-journey. |
| Historical catch-all folder | Treat it as a current host location, not as the preferred future ownership model. |
| Orchestration-heavy route | Classify conceptually by business journey, but preserve existing integration and sequencing behavior. |
| Documentation update | Improve findability and ownership clarity before considering any structural change. |
| Cosmetic restructuring idea | Do not pursue unless separately justified by future approved work. |
---
## Success Measures
Success should be understood qualitatively at architecture and maintainability level, not as an implementation delivery target.
Indicators of success:
- developers can find relevant APIs faster
- maintainers can identify likely owning journeys more easily
- shared infrastructure code is reused more consistently
- journey ownership becomes clearer in future documentation and code review discussions
- onboarding becomes simpler because route ownership is easier to explain
- maintenance effort is reduced through clearer patterns and less duplicated infrastructure logic
- future API additions align more naturally with business capability rather than historical folder drift
Avoid treating success as:
- number of routes moved
- number of folders renamed
- reduction in route count
- migration completion percentage
---
## Non-Goals
This roadmap explicitly does **not** approve or recommend:
- migrations
- implementation
- route movement
- route renaming
- API deletion
- API consolidation
- folder restructuring
- refactoring programmes
- mass renaming
- contract changes
- behaviour changes
This roadmap defines **architectural direction**, not delivery.
---
## Risks / Cautions
1. This roadmap is intentionally architecture-only.
2. It should not be mistaken for an implementation plan.
3. Stable runtime behavior matters more than conceptual neatness.
4. Several PEDW API areas remain orchestration-heavy and cross integration boundaries; conceptual grouping is safer than physical reorganisation.
5. `endpoint/` and `file/` remain historically important host folders even though they are not ideal future ownership concepts.
6. `auth/` and `notifications/` remain cross-cutting concerns and should not be over-simplified.
7. Dashboard-related APIs are aggregation-oriented and should be mapped back to owning journeys rather than treated as a separate long-term grouping target.
8. Future adoption should happen through natural change pressure, not through standalone cosmetic restructuring.
---
## Validation Performed
Manual synthesis only.
Performed:
- read the required roadmap context listed above
- reused the completed architecture programme as the evidence base
- reused the completed API grouping plan rather than reopening discovery
- kept the roadmap at architecture-roadmap level only
Not performed:
- no new API inspection
- no new API inventory
- no implementation design
- no migration proposal
- no refactor proposal
- no lint/tests, because this is documentation-only planning work
---
## Recommendation
Recommended next architecture planning document only:
### `context/api-maintainer-guidance-v2.md`
Suggested purpose:
- extend the existing maintainer guidance with clearer decision support for future API additions
- strengthen journey-owned ownership cues and shared-helper selection guidance
- improve onboarding and change-entry clarity without recommending implementation or restructuring
No implementation work is recommended from this roadmap alone.
+915
View File
@@ -0,0 +1,915 @@
# API Grouping Plan
## Status
Planning only.
Pilot status update (2026-06-25):
- first additive grouping façade pilot implemented for watched-case APIs under `pages/api/subscriptions/`
- legacy watched-case endpoint routes under `pages/api/endpoint/` remain canonical and stable
- no route removal, migration, contract change, or behaviour change has occurred
- the pilot validates the journey-owned grouping model through additive façade wrappers only
This document defines a **future journey-owned API grouping model** for PEDW using the completed architecture programme as its evidence base.
It does **not** recommend implementation, migration, route movement, route renaming, file movement, contract change, or behaviour change.
---
## Required Context Read
The following files were read before drafting this plan:
- `context/api-route-map.md`
- `context/journey-architecture-map.md`
- `context/portal-api-platform-assessment.md`
- `context/architecture.md`
- `context/integration-map.md`
- `memory-bank/change-log.md`
---
## Files Modified
- `context/api-grouping-plan.md`
- `memory-bank/change-log.md`
---
## Findings
- The completed architecture programme already established that PEDW has a **large route surface** but a **smaller underlying architectural vocabulary**.
- The main API maintenance problem is not missing discovery. It is primarily:
- findability
- ownership clarity
- consistency
- reuse discipline
- Existing top-level folders do not consistently express current business ownership.
- The strongest current drift remains in:
- `pages/api/endpoint`
- `pages/api/file`
- The most stable architecture-level API families are already known and should be treated as established:
- CRM relay routes
- storage/blob routes
- finalisation/orchestration routes
- email/notification routes
- document download routes
- auth/session routes
- admin/internal routes
- middleware/helper routes
- local utility/meta routes
- The journey and route maps already support a journey-owned view of the platform. This plan therefore synthesises those findings into a maintainability-focused future grouping model only.
---
## Proposed API Grouping Model
Future grouping concepts for documentation guidance only:
```text
pages/api/
account/
admin/
appeals/
auth/
cases/
documents/
notifications/
platform/
representations/
search/
subscriptions/
shared/
```
Interpretation guidance:
- These are **architectural grouping concepts only**.
- They describe **future journey ownership**, not approved folder structure.
- They do **not** imply that current routes should move.
- They do **not** imply that route count should reduce.
- They do **not** imply that contracts, integrations, or behaviour should change.
---
## Group Definitions
### 1. `account/`
#### Purpose
Owns authenticated user account creation, account bootstrap, personal details retrieval, and account maintenance behavior.
#### Primary Journeys Supported
- account registration
- personal details
- account maintenance
- post-sign-in account bootstrap
#### Typical Integrations
- CRM
- NextAuth
#### Typical Route Types
- read
- create
- update
- lookup
#### Example Existing Routes
- `pages/api/endpoint/createaccount_api.js`
- `pages/api/endpoint/getpersonalaccount_api.js`
- `pages/api/endpoint/updateaccount_api.js`
- `pages/api/endpoint/getemailaccountcheck_api.js`
#### Shared Components Used
- relay helpers
- response helpers
- auth/session helpers
- signed request helpers
#### Relationship To Other Groups
- depends on `auth/` for identity establishment
- supports `appeals/`, `representations/`, and `subscriptions/` where CRM contact identity is required
- relies on `shared/` and `platform/` helper layers
#### Migration Cautions
- Future grouping candidate only.
- Account routes remain tightly coupled to session bootstrap and CRM contact identity.
- Documentation guidance only; any future grouping would need to preserve current session-to-contact resolution and all existing contracts.
---
### 2. `admin/`
#### Purpose
Owns internal reporting, operational summaries, and admin-facing grouped data views.
#### Primary Journeys Supported
- admin reporting
- operational status views
- internal appeal/document summaries
#### Typical Integrations
- CRM
#### Typical Route Types
- read
- lookup
- aggregation
#### Example Existing Routes
- `pages/api/admin/getnewappeals_api.js`
- `pages/api/admin/getlatestdocuments_api.js`
- `pages/api/admin/getStatusCountsByAppealAndLPA_api.js`
#### Shared Components Used
- relay helpers
- response helpers
- logging helpers
#### Relationship To Other Groups
- depends on shared CRM relay/platform helpers
- generally adjacent to `cases/`, `appeals/`, and `documents/` data rather than owning those journeys
#### Migration Cautions
- Leave current admin routes effectively unchanged for now at the architecture level.
- This is already one of the more coherent current families.
- Documentation guidance only.
---
### 3. `appeals/`
#### Purpose
Owns draft appeal progression, appeal submission/finalisation, and appeal-specific workflow orchestration.
#### Primary Journeys Supported
- start appeal
- save and exit
- resume appeal
- upload supporting files for appeal draft
- check answers
- submit appeal
- appeal completion
#### Typical Integrations
- CRM
- Azure Storage
- Azure Queue
- NextAuth
#### Typical Route Types
- read
- create
- update
- upload
- delete
- orchestration
#### Example Existing Routes
- `pages/api/file/getprogressobjblob.js`
- `pages/api/file/getbloblist.js`
- `pages/api/file/createappealcompletemessage_api.js`
- `pages/api/endpoint/createcase_api.js`
- `pages/api/endpoint/patchcase_api.js`
#### Shared Components Used
- Azure SDK helpers
- hash helpers
- relay helpers
- response helpers
- auth/session helpers
#### Relationship To Other Groups
- depends on `account/` for authenticated contact context
- depends on `platform/` / `shared/` for storage, queue, relay, validation, and response support
- intersects with `documents/` for user-facing file handling patterns
#### Migration Cautions
- Future grouping candidate only.
- Appeal flows cross storage-owned draft state and CRM-owned submitted state.
- Any future grouping would need to preserve sequencing, payload shapes, queue handoff, and contract-critical finalisation behavior.
---
### 4. `auth/`
#### Purpose
Owns session establishment, sign-in callbacks, locale-aware auth routing, and auth-support bootstrap behavior.
#### Primary Journeys Supported
- sign in
- verify request
- callback/redirect handling
- locale-aware auth bootstrap
#### Typical Integrations
- NextAuth
- GOV.UK Notify
- CRM
#### Typical Route Types
- orchestration
- lookup
- support
#### Example Existing Routes
- `pages/api/auth/[...nextauth].js`
- `pages/api/auth/resolve-locale.js`
- adjacent support routes such as `pages/api/endpoint/getpreferredlanguage_api.js`
#### Shared Components Used
- auth/session helpers
- Notify helpers
- response helpers
- logging helpers
#### Relationship To Other Groups
- foundational cross-cutting dependency for `account/`, `appeals/`, `representations/`, and `subscriptions/`
- shares responsibility boundaries with `notifications/` where auth emails are sent
#### Migration Cautions
- Cross-cutting concern; not a simple journey folder.
- Future grouping candidate only.
- Any future grouping would need to preserve current callback, redirect, locale, verification-email, and session behavior exactly.
---
### 5. `cases/`
#### Purpose
Owns case-detail retrieval, case messages, linked-case reads, and case-adjacent read models used by public and portal journeys.
#### Primary Journeys Supported
- public case details
- linked case viewing
- case messages/notices
- case-adjacent portal detail lookups
#### Typical Integrations
- CRM
#### Typical Route Types
- read
- lookup
- aggregation
#### Example Existing Routes
- `pages/api/endpoint/getcase_api.js`
- `pages/api/endpoint/getcasebyid_api.js`
- `pages/api/endpoint/getcasemessage_api.js`
- `pages/api/endpoint/getlinkedcases_api.js`
- `pages/api/endpoint/getportalmoduledetails_api.js`
#### Shared Components Used
- relay helpers
- response helpers
- signed request helpers
#### Relationship To Other Groups
- closely related to `search/` because public case detail often begins through search-family reads
- supports `subscriptions/` and `representations/` journeys that need case context
- relies on shared CRM/platform helpers
#### Migration Cautions
- Future grouping candidate only.
- Current case-detail retrieval is partly search-shaped rather than purely case-by-route shaped.
- Documentation guidance only; any future grouping would need to preserve current identifier assumptions and case-detail payload contracts.
---
### 6. `documents/`
#### Purpose
Owns published document metadata retrieval and published document delivery/download behavior.
#### Primary Journeys Supported
- published document discovery
- published document download
- document history/detail retrieval
#### Typical Integrations
- CRM
- Azure Relay
#### Typical Route Types
- read
- lookup
- download
#### Example Existing Routes
- `pages/api/endpoint/getsearchdocumentdetails_api.js`
- `pages/api/endpoint/getsearchdocumenthistory_api.js`
- `pages/api/endpoint/getsearchdocumentTypes_api.js`
- `pages/api/documents/download/[id].js`
#### Shared Components Used
- relay helpers
- hash helpers
- response helpers
- signed request helpers
#### Relationship To Other Groups
- closely related to `search/` and `cases/` because those journeys surface published document links
- distinct from appeal/representation draft storage APIs
#### Migration Cautions
- Natural future grouping candidate for published-document behavior.
- Keep published-document discovery separate from draft-storage document handling in any future planning.
- Documentation guidance only.
---
### 7. `notifications/`
#### Purpose
Owns outbound notification sending and orchestration routes that gather business data before sending transactional communications.
#### Primary Journeys Supported
- sign-in verification email
- completion notifications
- watchlist-related notifications
- business-triggered outbound email
#### Typical Integrations
- GOV.UK Notify
- CRM
#### Typical Route Types
- create
- orchestration
- lookup
- aggregation
#### Example Existing Routes
- `pages/api/email/notify.js`
- `pages/api/email/getall.js`
- `pages/api/email/getdocuments.js`
- `pages/api/email/getevents.js`
#### Shared Components Used
- Notify helpers
- relay helpers
- response helpers
- logging helpers
#### Relationship To Other Groups
- intersects with `auth/` for verification/sign-in email behavior
- intersects with `subscriptions/`, `appeals/`, and `representations/` for journey-triggered notifications
#### Migration Cautions
- Cross-cutting concern rather than a single business journey.
- Notification routes vary from thin send helpers to broader orchestration routes.
- Documentation guidance only; no implementation recommendation.
---
### 8. `platform/`
#### Purpose
Owns platform-level support routes and utility/meta endpoints that are not naturally journey-owned business APIs.
#### Primary Journeys Supported
- platform health/support
- utility/meta API behaviors
- route-level support concerns
#### Typical Integrations
- local-only
- CRM lookup support where applicable
#### Typical Route Types
- support
- lookup
- meta
- health
#### Example Existing Routes
- `pages/api/health.js`
- `pages/api/doc.ts`
- `pages/api/notices/index.js`
#### Shared Components Used
- response helpers
- logging helpers
- validation helpers
#### Relationship To Other Groups
- supports all journey groups indirectly
- distinct from `shared/`, which is a component/helper classification rather than an API-journey group
#### Migration Cautions
- Likely leave unchanged for now at the API-family level unless a future planning slice establishes clearer journey ownership.
- Documentation guidance only.
---
### 9. `representations/`
#### Purpose
Owns representation retrieval, draft representation lifecycle, and representation submission/finalisation orchestration.
#### Primary Journeys Supported
- start representation
- select capacity / representation type
- enter content
- upload supporting files
- save and resume representation draft
- check answers
- submit representation
- representation completion
#### Typical Integrations
- CRM
- Azure Storage
- Azure Queue
- GOV.UK Notify
- NextAuth
#### Typical Route Types
- read
- create
- update
- upload
- delete
- orchestration
#### Example Existing Routes
- `pages/api/file/getrepsblob.js`
- `pages/api/file/editRepJson.js`
- `pages/api/file/createrepcompletemessage_api.js`
- `pages/api/file/createrepinvolvement_api.js`
- `pages/api/endpoint/getrepresentations_api.js`
#### Shared Components Used
- Azure SDK helpers
- hash helpers
- relay helpers
- Notify helpers
- response helpers
- auth/session helpers
#### Relationship To Other Groups
- depends on `cases/` for case context
- depends on `account/` and `auth/` for identity/bootstrap
- intersects with `notifications/` for representation communications
- depends on `platform/` / `shared/` helpers for storage, queue, relay, and validation
#### Migration Cautions
- Future grouping candidate only.
- Representation routes span both read models and orchestration-heavy submission side effects.
- Any future grouping would need to preserve storage ownership, CRM representation relationships, and completion sequencing.
---
### 10. `search/`
#### Purpose
Owns public search, advanced search, search-detail expansion, and public discovery-oriented lookups.
#### Primary Journeys Supported
- basic search
- advanced search
- result paging and sorting
- search-to-case navigation bootstrap
#### Typical Integrations
- CRM
#### Typical Route Types
- read
- lookup
- aggregation
#### Example Existing Routes
- `pages/api/endpoint/getbasicsearch_api.js`
- `pages/api/endpoint/getbasicsearchpaged_api.js`
- `pages/api/endpoint/getadvancedsearch_api.js`
- `pages/api/endpoint/getadvancedsearchpaged_api.js`
- `pages/api/endpoint/getbasicsearchdetails_api.js`
#### Shared Components Used
- relay helpers
- response helpers
- relay policy helpers
- signed request helpers
#### Relationship To Other Groups
- upstream journey dependency for `cases/` and `documents/`
- relies on shared CRM/platform helpers
#### Migration Cautions
- Natural future grouping candidate.
- Preserve public search contracts, paging assumptions, and detail-expansion behavior.
- Documentation guidance only.
---
### 11. `subscriptions/`
#### Purpose
Owns watched-case and unsubscribe-related behavior, including subscription-like user relationships to cases and related notification preferences.
#### Primary Journeys Supported
- watch case
- unwatch case
- view watched cases
- unsubscribe / unsubscribe-all flows
#### Typical Integrations
- CRM
- GOV.UK Notify
#### Typical Route Types
- read
- create
- delete
- update
- orchestration
#### Example Existing Routes
- `pages/api/endpoint/getwatchedcases_api.js`
- `pages/api/endpoint/createwatchedcases_api.js`
- `pages/api/endpoint/deletewatchedcases_api.js`
- `pages/api/endpoint/deletewatchedcasesproxy_api.js`
#### Shared Components Used
- relay helpers
- relayGetData helpers
- response helpers
- auth/session helpers
#### Relationship To Other Groups
- depends on `account/` and `auth/` for identity context
- supports `cases/`, `search/`, and `my portal` style journeys
- intersects with `notifications/` because watchlist state participates in notification behavior
#### Migration Cautions
- Future grouping candidate only.
- Some notification behavior is owned by CRM watchlist state rather than Notify routes alone.
- Documentation guidance only; preserve create/upsert/delete semantics and watchlist relationship model.
#### Additive façade pilot note
- A first additive façade pilot now exists for watched-case APIs only:
- `pages/api/subscriptions/get-watched-cases.js`
- `pages/api/subscriptions/create-watched-case.js`
- `pages/api/subscriptions/delete-watched-case.js`
- These routes delegate to the existing endpoint handlers.
- Existing endpoint routes remain canonical/stable:
- `pages/api/endpoint/getwatchedcases_api.js`
- `pages/api/endpoint/createwatchedcases_api.js`
- `pages/api/endpoint/deletewatchedcases_api.js`
- No legacy route removal or frontend migration has occurred.
---
### 12. `shared/`
#### Purpose
Represents shared platform components and reusable support primitives that should remain shared regardless of journey grouping.
#### Primary Journeys Supported
- all journeys indirectly
#### Typical Integrations
- CRM relay support
- Azure Storage support
- GOV.UK Notify support
- NextAuth/session support
- local-only middleware/helper support
#### Typical Route Types
- not primarily a journey-owned API route family
- middleware
- helper
- support
#### Example Existing Routes / Areas
- `pages/api/middleware/apiResponse.js`
- `pages/api/middleware/relayForwarding.js`
- `pages/api/middleware/relayPolicyPresets.js`
- `pages/api/middleware/middleware.js`
#### Shared Components Used
- relay helpers
- response helpers
- hash helpers
- signed request helpers
- Azure SDK helpers
- logging helpers
- validation helpers
- auth/session helpers
- Notify helpers
#### Relationship To Other Groups
- foundational dependency for every journey-owned group
#### Migration Cautions
- This is primarily a classification for **Shared Platform Components**, not a recommendation for a user-facing API area.
- Documentation guidance only.
---
## Shared Platform Components
The following capabilities should remain classified as **Shared Platform Components**, not journey-owned APIs:
- relay helpers
- `relayGet(...)`
- `relayGetData(...)`
- relay forwarding helpers
- relay policy presets
- response helpers
- `respondSuccess(...)`
- `respondError(...)`
- hash helpers
- path signing
- integrity validation
- signed request helpers
- signed GET/POST/DELETE request execution
- Azure Storage helpers
- blob/container/queue operations
- auth/session helpers
- session establishment
- locale resolution support
- auth-support bootstrap helpers
- Notify helpers
- send behavior and shared notification composition support
- logging helpers
- structured/redacted logging support
- validation helpers
- required-input and route guard helpers
Classification note:
> These are shared platform concerns. They should be reused by journey-owned APIs rather than reclassified as journey-owned business capabilities.
---
## Journey-to-Group Mapping
This section works at the **journey/API-family level** only.
It does **not** classify every individual API file.
| Existing API family / journey area | Proposed future group | Classification | Notes |
| -------------------------------------------------- | --------------------------------------------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| Public search | `search/` | Natural fit | Strong journey ownership already established in the route map. |
| Search detail expansion | `search/` | Natural fit | Closely tied to search contracts and result shaping. |
| Case details | `cases/` | Natural fit | Strong case-read ownership, even where current bootstrapping begins through search. |
| Case messages / notices | `cases/` | Natural fit | Best understood as case-page content rather than notifications. |
| Published documents metadata | `documents/` | Natural fit | Naturally grouped with published document discovery. |
| Published document download | `documents/` | Natural fit | Dedicated download boundary already coherent. |
| My portal dashboard CRM reads | `cases/` or `representations/` depending on journey | Likely fit | Dashboard is an aggregator, not one clean business capability. Leave journey reads with their owning domains conceptually. |
| Watched cases / watchlist | `subscriptions/` | Natural fit | Clear subscription-like relationship model. |
| Unsubscribe flows | `subscriptions/` | Natural fit | Closely tied to watchlist/subscription ownership. |
| Draft appeals | `appeals/` | Likely fit | Strong journey ownership, but current implementation crosses storage/platform boundaries. |
| Appeal submission / finalisation | `appeals/` | Likely fit | Business ownership is appeals, but implementation remains orchestration-heavy. |
| Representation reads | `representations/` | Natural fit | Strong journey ownership. |
| Draft representations | `representations/` | Likely fit | Strong journey ownership with storage/platform dependency. |
| Representation submission / finalisation | `representations/` | Likely fit | Business ownership is clear, but route shape is orchestration-heavy. |
| Account registration | `account/` | Natural fit | Clear account lifecycle ownership. |
| Personal details / account management | `account/` | Natural fit | Clear account lifecycle ownership. |
| Authentication / sign-in | `auth/` | Cross-cutting concern | Foundational platform behavior touching locale, session, and Notify. |
| Notifications / email | `notifications/` | Cross-cutting concern | Includes both thin sends and orchestration-heavy flows. |
| Admin / reporting | `admin/` | Leave unchanged for now | Already relatively coherent compared with `endpoint` and `file`. |
| Documented middleware / helper routes | `shared/` / `platform/` | Shared / Platform concern | Not journey-owned business APIs. |
| Health / meta / support routes | `platform/` | Shared / Platform concern | Platform support rather than business journey ownership. |
| Legacy catch-all CRM relay families in `endpoint/` | Depends on owning journey | Leave unchanged for now | Useful as current implementation location, but not a future ownership concept by themselves. |
| Storage-heavy families in `file/` | Depends on owning journey plus shared platform | Leave unchanged for now | Current folder is an implementation host, not a stable future ownership model. |
---
## Architectural Principles
Future development guidance only:
1. Prefer journey ownership over historical folder ownership.
2. Group by business capability rather than by transport or technology alone.
3. Keep integrations behind journey-owned APIs where possible at the architecture level.
4. Reuse shared helpers rather than duplicating infrastructure logic.
5. Preserve API contracts.
6. Preserve current route behavior.
7. Preserve CRM as the source of truth for CRM-owned business data.
8. Preserve Azure Storage ownership boundaries for draft-owned content.
9. Preserve established authorization boundaries and session/bootstrap assumptions.
10. Preserve EN/CY parity and locale-aware behavior.
11. Treat orchestration-heavy routes as business-owned conceptually even when they depend on multiple shared platform capabilities.
12. Do not reorganise stable APIs without explicit business justification and explicit approval.
13. Do not treat `endpoint/` or `file/` as preferred future ownership models simply because they are current implementation locations.
14. Continue distinguishing between published-document APIs and draft-storage file APIs.
---
## Non-Goals
This document explicitly does **not** approve or recommend:
- implementation
- migrations
- folder restructuring
- route movement
- route renaming
- API deletions
- API consolidation
- merging APIs
- reducing route count
- changing contracts
- changing payload shapes
- changing validation rules
- changing authorization behavior
- changing session behavior
- changing integration boundaries
- changing business behavior
This is **architectural direction only**.
---
## Risks / Cautions
1. This plan is deliberately **planning-only**.
2. Future grouping concepts should not be mistaken for implementation approval.
3. Several current route families are orchestration-heavy and cross integration boundaries; they are easier to classify architecturally than to reorganise safely.
4. `auth/` and `notifications/` remain cross-cutting and should not be oversimplified into narrow folder ownership assumptions.
5. `endpoint/` and `file/` remain current implementation hotspots, but they should be interpreted as historical host folders rather than ideal future ownership concepts.
6. The dashboard remains an aggregation journey and does not justify a separate future grouping here; ownership is clearer when mapped back to cases, representations, subscriptions, and account concerns.
7. Published-document retrieval and draft-storage file handling should remain conceptually distinct.
8. Any future grouping exercise would need explicit migration cautions, but no migration planning is being proposed in this document.
---
## Validation Performed
Manual synthesis only.
Performed:
- read the required context files listed above
- confirmed active branch rules and guardrails before drafting
- reused the completed architecture programme as the evidence base
- checked the current top-level `pages/api` shape only to compare proposed future groups against todays folder structure without producing a new inventory
Not performed:
- no implementation
- no runtime analysis
- no route-by-route re-inventory
- no refactor proposal
- no migration planning
- no lint/tests, because this is documentation-only planning work
---
## Recommendation
Recommended next architecture planning document only:
### `context/api-rationalisation-planning.md`
Suggested purpose:
- evaluate, at a planning level only, where future API families appear structurally duplicated or historically drifted
- define criteria for when a future rationalisation candidate is documentation-worthy
- preserve the same non-goals as this document: no implementation, no migration, no route movement, and no contract change without separate approval
No implementation work is recommended from this document alone.
+329
View File
@@ -18,6 +18,335 @@ Follow-ups:
---
### CL-2026-06-25-API-GROUPING-FACADE-SUBSCRIPTIONS-VERTICAL-SLICE-COMPLETION: watched-case proxy read adoption and scope closure
date: 2026-06-25
author: Cline
scope: `pages/api/subscriptions/get-watched-cases-proxy.js`, `actions/services/portalDirectService.js`, `tests/phase22/api-grouping-facade-subscriptions.test.cjs`, `context/api-grouping-adoption-roadmap.md`
type: change
rationale: Complete the intended subscriptions/watched-cases vertical slice by covering the active proxy read path still used by the normal watched-case UI journey, while keeping legacy endpoint and proxy handlers in place as canonical/support implementation routes.
impact: Runtime behaviour is intended to remain unchanged; the grouped subscriptions façade now covers the active watched-case journey service methods including proxy reads, while legacy handlers remain canonical and no route deletion, migration, auth/session change, CRM query change, payload change, or status-code change has occurred.
status: completed
Summary:
- Performed a bounded watched-case usage audit across services, pages, and components.
- Audit findings established that:
- no frontend components directly call legacy watched-case endpoint URLs
- normal watched-case journey calls are routed through `actions/services/portalDirectService.js`
- `getWatchedCasesProxy()` is actively used in the current watched-case UI journey
- `deletewatchedcasesproxy_api` remains present but is not part of the currently adopted normal watched-case service path
- Added grouped façade route:
- `pages/api/subscriptions/get-watched-cases-proxy.js`
- delegates directly to `pages/api/endpoint/getwatchedcasesproxy_api.js`
- Updated `actions/services/portalDirectService.js` so `getWatchedCasesProxy` now targets:
- `/api/subscriptions/get-watched-cases-proxy`
- Extended the existing subscriptions façade characterization test to prove:
- grouped proxy façade delegation works
- legacy proxy handler remains present
- watched-case service methods now target grouped subscriptions routes for both normal and proxy watched-case reads
- adopted methods no longer target the legacy watched-case endpoint URLs directly
- delete proxy remains outside grouped pilot scope and legacy support route remains present
- Updated the adoption roadmap to define what “complete vertical slice” means for this pilot and to record the proxy-scope boundary.
Validation:
- Focused validation only:
- `npx eslint actions/services/portalDirectService.js tests/phase22/api-grouping-facade-subscriptions.test.cjs pages/api/subscriptions/get-watched-cases.js pages/api/subscriptions/get-watched-cases-proxy.js pages/api/subscriptions/create-watched-case.js pages/api/subscriptions/delete-watched-case.js`
- `node tests/phase22/api-grouping-facade-subscriptions.test.cjs`
- No repository-wide test suite run.
Follow-ups:
- For the intended watched-case/subscriptions scope, the pilot now forms a complete vertical slice:
- subscriptions journey
- service layer
- grouped façade routes
- legacy canonical endpoint handlers
- unchanged behaviour
- Any future expansion beyond this scope should be a separate bounded slice (for example, deciding whether legacy/support proxy delete routes also need grouped façade coverage).
### CL-2026-06-25-API-GROUPING-FACADE-SUBSCRIPTIONS-INTERNAL-ADOPTION: first internal consumer targets grouped watched-case routes
date: 2026-06-25
author: Cline
scope: `actions/services/portalDirectService.js`, `tests/phase22/api-grouping-facade-subscriptions.test.cjs`, `context/api-grouping-adoption-roadmap.md`
type: change
rationale: Validate the subscriptions façade pilot through one carefully selected internal consumer by updating watched-case service methods in `portalDirectService` to call the new grouped subscriptions routes while leaving the legacy endpoint handlers unchanged and canonical behind the façade.
impact: Runtime behaviour is intended to remain unchanged because the grouped routes still delegate to the existing watched-case handlers; validates incremental internal adoption without route migration, deprecation, auth/session change, CRM query change, payload change, or signed-request behaviour change.
status: completed
Summary:
- Re-read required continuation context before implementation:
- `context/api-grouping-plan.md`
- `context/api-grouping-adoption-roadmap.md`
- `context/api-route-map.md`
- `memory-bank/change-log.md`
- Updated only the watched-case methods in `actions/services/portalDirectService.js` to target grouped façade routes:
- `getWatchedCases` -> `/api/subscriptions/get-watched-cases`
- `createWatchedCases` -> `/api/subscriptions/create-watched-case`
- `deleteWatchedCases` -> `/api/subscriptions/delete-watched-case`
- Did not modify any other service methods in `portalDirectService.js`.
- Did not modify underlying watched-case endpoint handlers or façade handler delegation.
- Extended the existing façade characterization test to prove:
- grouped façade delegation still works
- legacy endpoint handler files remain present
- the internal service layer now targets `/api/subscriptions/...`
- the adopted watched-case methods no longer point at legacy `/api/endpoint/...` routes
- key service-layer request-contract cues remain present (`loggedInUserId`, `watchedCaseID`, POST method)
- Updated the adoption roadmap to record:
- first internal consumer adoption has occurred
- legacy routes remain canonical implementations
- no migration or deprecation has occurred
- this validates incremental adoption of grouped journey-owned routes
Validation:
- Focused validation only:
- `npx eslint actions/services/portalDirectService.js tests/phase22/api-grouping-facade-subscriptions.test.cjs context/api-grouping-adoption-roadmap.md memory-bank/change-log.md`
- `node tests/phase22/api-grouping-facade-subscriptions.test.cjs`
- No repository-wide test suite run.
Follow-ups:
- The subscriptions façade pattern has now been validated through both additive route introduction and one successful internal service adoption.
- Any further adoption should continue incrementally and only with the same behaviour-preserving characterization discipline.
### CL-2026-06-25-API-GROUPING-FACADE-PILOT-SUBSCRIPTIONS: additive watched-case subscriptions façade routes
date: 2026-06-25
author: Cline
scope: `pages/api/subscriptions/*`, watched-case API façade pilot, focused characterization tests, and grouping-plan/adoption-roadmap documentation
type: change
rationale: Implement the first additive API grouping façade pilot by adding journey-owned subscriptions wrapper routes for watched-case read/create/delete operations that delegate to the existing canonical endpoint handlers without changing current frontend call sites, contracts, or behaviour.
impact: Runtime impact is intentionally additive only; existing watched-case endpoint routes remain canonical/stable; no auth/session, CRM query, hash/signing, payload, status-code, i18n, or frontend-callsite behaviour change intended; documentation now records the pilot and its non-migration status.
status: completed
Summary:
- Confirmed required implementation context was read before changes:
- `context/api-grouping-plan.md`
- `context/api-grouping-adoption-roadmap.md`
- `context/api-route-map.md`
- `context/journey-architecture-map.md`
- `context/portal-api-platform-assessment.md`
- `context/architecture.md`
- `memory-bank/change-log.md`
- Added the first grouped façade routes under `pages/api/subscriptions/`:
- `get-watched-cases.js`
- `create-watched-case.js`
- `delete-watched-case.js`
- Implemented each façade as the smallest safe compatibility wrapper:
- import the existing watched-case endpoint handler
- delegate `req` and `res` directly to that existing handler
- Preserved the existing canonical watched-case routes unchanged:
- `pages/api/endpoint/getwatchedcases_api.js`
- `pages/api/endpoint/createwatchedcases_api.js`
- `pages/api/endpoint/deletewatchedcases_api.js`
- Did not change frontend call sites; `actions/services/portalDirectService.js` continues to call the legacy endpoint routes.
- Added a focused characterization test file to prove:
- grouped façade route files exist and delegate to the expected legacy handlers
- legacy endpoint files still exist
- frontend watched-case service call sites were not migrated to `/api/subscriptions/`
- Updated the API grouping plan and adoption roadmap to record:
- this is the first additive grouping façade pilot
- existing watched-case endpoint routes remain canonical/stable
- new subscriptions routes are grouped façade routes
- no old route removal or migration has occurred
Validation:
- Focused implementation only; no broad refactor performed.
- Characterization coverage added for façade delegation and unchanged frontend call sites.
- Intended validation set for this slice:
- `npx eslint pages/api/subscriptions/*.js tests/phase22/api-grouping-facade-subscriptions.test.cjs`
- `node tests/phase22/api-grouping-facade-subscriptions.test.cjs`
- Existing watched-case endpoint files were preserved in place.
Follow-ups:
- If the pilot is accepted, use the same additive façade pattern for future journey-owned grouping candidates only where behaviour preservation can be equally well characterized.
### CL-2026-06-25-API-GROUPING-ADOPTION-ROADMAP: gradual adoption roadmap for future journey-owned API grouping
date: 2026-06-25
author: Cline
scope: `context/api-grouping-adoption-roadmap.md`, architecture roadmap for gradual adoption of future API grouping concepts
type: milestone
rationale: Create a planning-only roadmap document describing how PEDW could gradually adopt the future journey-owned API grouping model over time through documentation guidance, additive consistency, and future-development discipline rather than migration or restructuring.
impact: Documentation/context only; improves architecture planning clarity for gradual API grouping adoption, maintainability direction, and future decision support; no runtime, auth, CRM, storage, queue, notification, i18n, contract, or behaviour change.
status: completed
Summary:
- Confirmed the required roadmap context was read before drafting:
- `context/api-grouping-plan.md`
- `context/api-route-map.md`
- `context/journey-architecture-map.md`
- `context/portal-api-platform-assessment.md`
- `context/architecture.md`
- `context/integration-map.md`
- `memory-bank/change-log.md`
- Added new document: `context/api-grouping-adoption-roadmap.md`.
- Kept the roadmap explicitly scoped to **architecture planning only**.
- Recorded the core adoption philosophy that PEDW should favour:
- gradual evolution
- behaviour preservation
- contract preservation
- incremental consistency
- reuse of shared helpers
over large restructures, wholesale moves, rewrites, or mass renaming.
- Added a staged roadmap covering:
- Stage 1 — Current state
- Stage 2 — Future development guidance
- Stage 3 — Documentation maturity
- Stage 4 — Future opportunities
- Added concise adoption principles emphasising:
- preserve stable APIs
- preserve contracts and integrations
- prefer additive improvements
- improve findability first
- avoid unnecessary churn
- never move APIs solely for cosmetic reasons
- Added a future-development decision matrix covering:
- new APIs
- existing stable APIs
- existing APIs being enhanced
- shared/platform concerns
- cross-cutting concerns
- orchestration-heavy routes
- Added qualitative success measures focused on maintainability outcomes rather than implementation metrics.
- Added explicit non-goals including:
- no migrations
- no implementation
- no route movement
- no route renaming
- no API deletion
- no consolidation
- no contract changes
- no behaviour changes
- Recommended the next architecture planning document only:
- `context/api-maintainer-guidance-v2.md`
Validation:
- Documentation-only planning work; no runtime code changed.
- Non-destructive synthesis only:
- reused the completed architecture programme as the evidence base
- reused the newly completed API grouping plan rather than reopening discovery
- remained at architecture-roadmap level and did not widen into implementation or migration guidance
- Did not perform another API inventory.
- Did not recommend implementation, migration, refactor, or route moves.
- No repo-wide automated analysis performed.
- No Python used.
- Lint/tests not run because this was documentation-only work.
Follow-ups:
- Next architecture planning document only:
- `context/api-maintainer-guidance-v2.md`
---
### CL-2026-06-25-API-GROUPING-PLAN-PHASE-1: future journey-owned API grouping model
date: 2026-06-25
author: Cline
scope: `context/api-grouping-plan.md`, architecture planning for future journey-owned API grouping concepts
type: milestone
rationale: Create a planning-only architecture document that synthesises the completed API platform, route map, journey map, integration map, and architecture findings into a future journey-owned API grouping model focused on maintainability, findability, consistency, and extensibility without reopening discovery or recommending implementation.
impact: Documentation/context only; improves future architecture planning clarity around journey-owned API grouping, shared platform concerns, and API-family classification; no runtime, auth, CRM, storage, queue, notification, i18n, contract, or behaviour change.
status: completed
Summary:
- Confirmed the required planning context was read before drafting:
- `context/api-route-map.md`
- `context/journey-architecture-map.md`
- `context/portal-api-platform-assessment.md`
- `context/architecture.md`
- `context/integration-map.md`
- `memory-bank/change-log.md`
- Added new document: `context/api-grouping-plan.md`.
- Kept the document explicitly scoped to **architecture planning only**.
- Recorded the key evidence-base finding that the main API maintenance problem is:
- findability
- ownership clarity
- consistency
- reuse discipline
- Assessed the proposed future grouping concepts only as documentation guidance:
- `account/`
- `admin/`
- `appeals/`
- `auth/`
- `cases/`
- `documents/`
- `notifications/`
- `platform/`
- `representations/`
- `search/`
- `subscriptions/`
- `shared/`
- For each proposed group, documented:
- purpose
- primary journeys supported
- typical integrations
- typical route types
- representative existing routes
- shared components used
- relationship to other groups
- migration cautions
- Added a **Shared Platform Components** section classifying reusable helpers such as:
- relay helpers
- response helpers
- hash helpers
- signed request helpers
- Azure Storage helpers
- auth/session helpers
- Notify helpers
- logging helpers
- validation helpers
- Added a **Journey-to-Group Mapping** section working at journey/API-family level only and classifying areas as:
- Natural fit
- Likely fit
- Shared / Platform concern
- Cross-cutting concern
- Leave unchanged for now
- Added future guidance principles and explicit non-goals, including:
- no implementation
- no migrations
- no folder restructuring
- no route movement
- no route renaming
- no API deletions
- no API consolidation
- no behaviour change
- no contract change
- Recommended the next architecture planning document only:
- `context/api-rationalisation-planning.md`
Validation:
- Documentation-only planning work; no runtime code changed.
- Non-destructive evidence gathering and synthesis only:
- read required context files
- targeted extraction from existing route/journey/platform architecture documents
- top-level `pages/api` listing only to compare current shape with future grouping concepts without producing a new API inventory
- Did not reopen architectural discovery.
- Did not perform a new route inventory.
- Did not recommend implementation, refactor, migration, or route moves.
- No repo-wide automated analysis performed.
- No Python used.
- Lint/tests not run because this was documentation-only work.
Follow-ups:
- Next architecture planning document only:
- `context/api-rationalisation-planning.md`
---
### CL-2026-06-22-JOURNEY-ARCHITECTURE-MAP-SLICE-8: case-messages-notices and related-published-case-communications lifecycle map
date: 2026-06-22
@@ -0,0 +1,5 @@
import legacyCreateWatchedCaseHandler from "../endpoint/createwatchedcases_api";
export default async function createWatchedCaseFacade(req, res) {
return legacyCreateWatchedCaseHandler(req, res);
}
@@ -0,0 +1,5 @@
import legacyDeleteWatchedCaseHandler from "../endpoint/deletewatchedcases_api";
export default async function deleteWatchedCaseFacade(req, res) {
return legacyDeleteWatchedCaseHandler(req, res);
}
@@ -0,0 +1,5 @@
import legacyGetWatchedCasesProxyHandler from "../endpoint/getwatchedcasesproxy_api";
export default async function getWatchedCasesProxyFacade(req, res) {
return legacyGetWatchedCasesProxyHandler(req, res);
}
@@ -0,0 +1,5 @@
import legacyGetWatchedCasesHandler from "../endpoint/getwatchedcases_api";
export default async function getWatchedCasesFacade(req, res) {
return legacyGetWatchedCasesHandler(req, res);
}
@@ -0,0 +1,193 @@
const assert = require("assert");
const fs = require("fs");
const path = require("path");
const { loadModule, createRes } = require("../phase21/_shared.cjs");
const rootDir = path.resolve(__dirname, "..", "..");
const tests = [];
const test = (name, fn) => tests.push({ name, fn });
const read = (relativePath) =>
fs.readFileSync(path.join(rootDir, relativePath), "utf8");
test("subscriptions get-watched-cases facade delegates to legacy handler", async () => {
const calls = [];
const mod = loadModule("pages/api/subscriptions/get-watched-cases.js", {
legacyGetWatchedCasesHandler: async (req, res) => {
calls.push({ req, res });
return res.status(200).json({ ok: true, route: "get" });
}
});
const req = { method: "GET", query: { loggedInUserId: "user-1" } };
const res = createRes();
await mod.default(req, res);
assert.strictEqual(calls.length, 1);
assert.strictEqual(calls[0].req, req);
assert.strictEqual(calls[0].res, res);
assert.strictEqual(res.state.statusCode, 200);
assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), {
ok: true,
route: "get"
});
});
test("subscriptions create-watched-case facade delegates to legacy handler", async () => {
const calls = [];
const mod = loadModule("pages/api/subscriptions/create-watched-case.js", {
legacyCreateWatchedCaseHandler: async (req, res) => {
calls.push({ req, res });
return res.status(200).json({ ok: true, route: "create" });
}
});
const req = {
method: "POST",
body: {
"pinswg_WatchedCase@odata.bind": "/incidents(inc-1)",
"pinswg_Contact@odata.bind": "/contacts(con-1)"
}
};
const res = createRes();
await mod.default(req, res);
assert.strictEqual(calls.length, 1);
assert.strictEqual(calls[0].req, req);
assert.strictEqual(calls[0].res, res);
assert.strictEqual(res.state.statusCode, 200);
assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), {
ok: true,
route: "create"
});
});
test("subscriptions delete-watched-case facade delegates to legacy handler", async () => {
const calls = [];
const mod = loadModule("pages/api/subscriptions/delete-watched-case.js", {
legacyDeleteWatchedCaseHandler: async (req, res) => {
calls.push({ req, res });
return res.status(200).json({ ok: true, route: "delete" });
}
});
const req = { method: "DELETE", query: { watchedCaseID: "watch-1" } };
const res = createRes();
await mod.default(req, res);
assert.strictEqual(calls.length, 1);
assert.strictEqual(calls[0].req, req);
assert.strictEqual(calls[0].res, res);
assert.strictEqual(res.state.statusCode, 200);
assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), {
ok: true,
route: "delete"
});
});
test("subscriptions get-watched-cases-proxy facade delegates to legacy handler", async () => {
const calls = [];
const mod = loadModule(
"pages/api/subscriptions/get-watched-cases-proxy.js",
{
legacyGetWatchedCasesProxyHandler: async (req, res) => {
calls.push({ req, res });
return res.status(200).json({ ok: true, route: "proxy-get" });
}
}
);
const req = { method: "GET", query: { loggedInUserId: "user-2" } };
const res = createRes();
await mod.default(req, res);
assert.strictEqual(calls.length, 1);
assert.strictEqual(calls[0].req, req);
assert.strictEqual(calls[0].res, res);
assert.strictEqual(res.state.statusCode, 200);
assert.deepStrictEqual(JSON.parse(JSON.stringify(res.state.jsonBody)), {
ok: true,
route: "proxy-get"
});
});
test("legacy watched-case endpoint files remain present", async () => {
const legacyFiles = [
"pages/api/endpoint/getwatchedcases_api.js",
"pages/api/endpoint/getwatchedcasesproxy_api.js",
"pages/api/endpoint/createwatchedcases_api.js",
"pages/api/endpoint/deletewatchedcases_api.js"
];
legacyFiles.forEach((filePath) => {
assert.strictEqual(
fs.existsSync(path.join(rootDir, filePath)),
true,
filePath
);
});
});
test("portalDirectService watched-case methods now target subscriptions facade routes", async () => {
const source = read("actions/services/portalDirectService.js");
assert.match(source, /\/api\/subscriptions\/get-watched-cases/);
assert.match(source, /\/api\/subscriptions\/get-watched-cases-proxy/);
assert.match(source, /\/api\/subscriptions\/create-watched-case/);
assert.match(source, /\/api\/subscriptions\/delete-watched-case/);
});
test("portalDirectService no longer targets legacy watched-case routes for adopted methods", async () => {
const source = read("actions/services/portalDirectService.js");
assert.doesNotMatch(source, /\/api\/endpoint\/getwatchedcases_api/);
assert.doesNotMatch(source, /\/api\/endpoint\/getwatchedcasesproxy_api/);
assert.doesNotMatch(source, /\/api\/endpoint\/createwatchedcases_api/);
assert.doesNotMatch(source, /\/api\/endpoint\/deletewatchedcases_api/);
});
test("portalDirectService still preserves watched-case runtime contracts around inputs", async () => {
const source = read("actions/services/portalDirectService.js");
assert.match(source, /loggedInUserId/);
assert.match(source, /watchedCaseID/);
assert.match(source, /method:\s*"post"/);
});
test("delete watched-case proxy route remains outside the grouped subscriptions pilot scope", async () => {
const source = read("actions/services/portalDirectService.js");
assert.doesNotMatch(source, /deletewatchedcasesproxy_api/);
assert.strictEqual(
fs.existsSync(
path.join(
rootDir,
"pages/api/endpoint/deletewatchedcasesproxy_api.js"
)
),
true
);
});
async function run() {
let failures = 0;
for (const { name, fn } of tests) {
try {
await fn();
console.log(`${name}`);
} catch (error) {
failures += 1;
console.error(`${name}`);
console.error(error);
}
}
if (failures > 0) {
process.exit(1);
}
}
run();