Files
pedwfrontend/memory-bank/progress.md
T

40 KiB
Raw Blame History

Progress — PEDW FrontEnd

Completed / evidenced milestones

  • Bilingual routing structure is established with extensive Welsh rewrites and locale namespace mapping.
  • Next-auth + Prisma SQL Server persistence is integrated for user/session lifecycle.
  • Broad API surface exists for search, case, portal, admin, and file/document operations.
  • CRM/relay hash pattern is implemented across many endpoint handlers.
  • Recent shipped updates focused on:
    • search/case back-navigation and breadcrumb behavior,
    • DNS/view-all navigation logic,
    • preferred-language handling for notify template selection,
    • PDF formatting/hyperlink fixes,
    • upload validation character updates.

Work in progress signals

  • Ongoing iterative fixes in breadcrumb/case-summary flows suggest navigation consistency is still being tuned.
  • Mixed proxy/non-proxy endpoint implementations continue to evolve in parallel.
  • Priority 1 refactor plan execution started for actions/index.js split (Phase 1 foundation complete).

Planned / partially implemented (inferred from code state)

  • Partial migration or coexistence of deployment/runtime patterns (Next runtime plus custom server artifacts).
  • Continued refinement of document/email workflow behavior (template/language and formatting quality).
  • Prioritized structural refactor backlog documented in memory-bank/refactor-backlog.md.

Known technical debt

  • actions/services/legacyActionsService.js still holds broad domain wrappers after Phase 1 extraction (core helpers now separated).
  • Significant duplication of token/hash/relay logic across endpoint files.
  • Inconsistent security/hash guard enforcement in some file routes.
  • Sparse automated test coverage (tests/ currently empty).
  • Verbose logging in sensitive flows (auth/email/actions/file) increases privacy risk.

Latest update (2026-03-12)

  • Branch 0000-update-actions-monolith created from development branch for Priority 1 refactor implementation.
  • actions/index.js reduced to a compatibility barrel.
  • New core helper modules added under actions/core/:
    • env.js
    • logger.js
    • hash.js
    • token.js
    • headers.js
  • Existing action wrappers moved to actions/services/legacyActionsService.js and continue to be exported via the barrel for compatibility.
  • actions/clients/ scaffolded for upcoming client extraction phase.
  • Phase 2 service grouping completed with dedicated service files and actions/services/index.js barrel.
  • Export parity check confirms grouped service modules cover all legacy exported action names.
  • Phase 3 migration started by moving selected high-churn consumers and representative endpoint handlers to direct actions/services/* and actions/core/* imports.
  • Phase 4 hardening baseline added with new guard helpers and redacted logging, adopted in selected notify/login/contact API handlers.
  • Additional Priority 1 consumer migration pass completed for high-use portal/form/representation helpers:
    • Updated direct service/core imports in:
      • components/admin/tabs/documents.js
      • components/admin/tabs/storage.js
      • components/admin/utils/serverside.js
      • components/case/documents.js
      • components/case/representation/representationComplete.js
      • components/case/representation/representationElements.js
      • components/elements/index.js
      • components/myportal/awaitingsubmissionfromblob.js
      • components/myportal/topthree.js
      • components/myportal/topthree_reps.js
      • components/utils/index.js
      • lib/myportal/loadMyPortalAppealPage.js
      • lib/newappeal/loadNewAppealPage.js
  • Additional Priority 1 consumer migration pass completed for view-all/search/unsubscribe flows:
    • Updated direct service/core imports in:
      • components/myportal/viewall.js
      • components/search/addresssearchresults.js
      • pages/unsubscribe/[watchlistid].js
      • pages/unsubscribeall/[watchlistid].js
  • Broad actions barrel import count reduced again; remaining non-comment usages are now concentrated in selected pages/api/endpoint/* and pages/api/file/* handlers.
  • Additional Priority 1 endpoint/file proxy migration chunk completed:
    • Updated imports in:
      • pages/api/endpoint/getmylpacases_api.js
      • pages/api/endpoint/getbasicdnssearchpaged_api.js
      • pages/api/endpoint/getsearchdocumentdetailspaged_api.js
      • pages/api/endpoint/getbasicsearchpaged_api.js
      • pages/api/file/getawaitingsubmissionfromblobproxy.js
      • pages/api/file/getrepsblobproxy.js
      • pages/api/file/getbloblistproxy.js
      • pages/api/file/createappealcompletemessageproxy_api.js
    • Migrated from broad ../../../actions imports to focused actions/core/* + service imports.
    • Removed duplicated local hash helper in getmylpacases_api.js and reused actions/core/hash.
  • Broad actions import scan now reports only comment-only references (no active broad imports in .js files).
  • Lint check re-run outcome unchanged: next lint fails due legacy/unsupported ESLint options in repo tooling config (not introduced by this refactor pass).

Handover update (2026-03-13)

  • Priority 1 import-migration wave has been checked in and completed via pull request.
  • Recent migration commits captured in this wave:
    • f0202bb
    • fa98535
    • bef8f25
  • Active broad .../actions imports are now eliminated from live .js code paths.
  • Next refactor phase will begin on a new branch and focus on splitting actions/services/legacyActionsService.js into smaller direct implementation modules.
  • Recommended decomposition order for the new branch:
    1. reference/search extraction
    2. portal/document extraction
    3. compatibility layer slimming + dead wrapper removal

Latest update (2026-03-13 — Phase 5 kickoff)

  • New branch created from SIPS-Development: TASK21997-phase5-legacyactions-split.
  • Completed first Phase 5 decomposition slice from legacyActionsService:
    • Added actions/services/searchDirectService.js
    • Added actions/services/referenceDataDirectService.js
    • Updated actions/services/searchService.js to source from searchDirectService
    • Updated actions/services/referenceDataService.js to source from referenceDataDirectService
  • Compatibility approach preserved: public grouped service exports and function signatures remain unchanged for callers.
  • Validation status unchanged:
    • npm run lint still fails due pre-existing Next/ESLint option incompatibility in repo tooling configuration.

Latest update (2026-03-13 — Phase 5 document slice)

  • Continued on branch TASK21997-phase5-legacyactions-split.
  • Completed second decomposition slice from legacyActionsService:
    • Added actions/services/documentDirectService.js
    • Updated actions/services/documentService.js to source from documentDirectService
  • Compatibility approach preserved:
    • grouped service export names/signatures unchanged for consumers.
  • Verification:
    • service import scan now shows remaining legacy-backed grouped modules are:
      • portalService, accountService, caseService, adminService, notifyService, integrationService
    • npm run lint passes with warnings only (no blocking errors).

Latest update (2026-03-13 — Phase 5 completion)

  • Continued decomposition and completed all remaining slices on TASK21997-phase5-legacyactions-split:
    • portal direct extraction
    • account + case direct extraction
    • admin + integration + notify direct extraction
    • legacy cleanup/removal
  • New direct modules now in place:
    • portalDirectService.js
    • accountDirectService.js
    • caseDirectService.js
    • adminDirectService.js
    • integrationDirectService.js
    • notifyDirectService.js
  • actions/services/legacyActionsService.js removed after import parity checks.
  • Validation evidence:
    • actions/services import scan: zero ./legacyActionsService references
    • npm run lint: warnings only, no blocking errors
    • npm run build: successful production build

Latest update (2026-03-13 — Phase 6 post-Phase-5 hardening, in progress)

  • Branch created from SIPS-Development: TASK21998-phase6-postphase5-hardening.
  • Added focused parity checks for grouped/direct service stability and service index barrel stability:
    • tests/phase6/service-parity.test.cjs
    • validates grouped service import/export parity across:
      • search, referenceData, document, portal, account, case, admin, integration, notify
    • validates actions/services/index.js export list stability/order.
  • Added shared service error helper:
    • actions/services/httpServiceUtils.js
    • centralizes common consoleLogger + return error.response and ErrResponse shape patterns.
  • Applied low-risk duplication reduction in direct services (no signature/shape changes intended):
    • searchDirectService.js
    • referenceDataDirectService.js
    • caseDirectService.js
    • adminDirectService.js
  • Logging cleanup/redaction-oriented hardening (sensitive-flow noisy logs removed):
    • removed debug console.log statements from:
      • searchDirectService.js
      • documentDirectService.js
      • portalDirectService.js
      • caseDirectService.js
      • adminDirectService.js

Validation snapshot (Phase 6)

  • node tests/phase6/service-parity.test.cjs -> pass
  • node tests/phase6/service-behaviour.test.cjs -> pass (8/8)
  • npm run lint -> warnings only (same pre-existing warnings)

Decision captured (Phase 6)

  • Agreed approach: keep parity guard tests and add focused behavioural unit tests in the current refactor stream (instead of deferring all behavioural checks to long-term roadmap).
  • Implemented now:
    • tests/phase6/service-behaviour.test.cjs
    • mocked-axios behavioural checks for critical success/error contracts across search/reference/case/admin direct services.
  • Wider behavioural expansion remains on roadmap for additional domains/functions.

Targeted smoke snapshot (local dev server)

  • Search flow:
    • GET /searchresults (EN/CY) -> 500 in local env due existing serialization issue (initialState.search.searchString undefined in SSR payload), observed in /tmp/phase6-dev.log.
    • GET /advancedsearch and GET /cy/advancedsearch -> 200
  • Case flow:
    • GET /case and GET /cy/case -> 200
  • My Portal flow (negative-path):
    • GET /myportal and GET /cy/myportal -> 307 redirect to /auth/signin (expected unauthenticated behavior)
  • Document flow (negative-path):
    • GET /api/file/getbloblistproxy?container=test&casefolderID=test -> 400
  • Notify flow (negative-path):
    • POST /api/email/notify with {} -> 400

Latest update (2026-03-13 — Phase 8 hardening slice)

  • New branch created from origin/SIPS-Development with work item prefix:
    • TASK22017-phase8-hardening-slice
  • Hardened four sensitive API handlers with minimal reversible guards:
    • pages/api/file/deleteblobcase.js
    • pages/api/file/deleteblobrep.js
    • pages/api/file/createappealcompletemessage_api.js
    • pages/api/endpoint/getportallogin_api.js
  • Scope delivered:
    • re-enabled/enforced hash checks where bypassed/commented
    • standardized early 400 negative paths for missing/invalid required query inputs
    • reduced noisy sensitive-path logging and routed errors through consoleLogger
    • preserved function signatures and existing response-shape contracts
  • Consumer parity updates (required to preserve behaviour after hash enforcement):
    • actions/services/documentDirectService.js
      • append hash for delete-blob-case/delete-blob-rep calls
    • actions/services/portalDirectService.js
      • append hash for create-appeal-complete-message call (hash path preserved to existing API contract)
  • Added focused tests:
    • tests/phase8/service-behaviour.test.cjs
    • covers negative paths for all 4 handlers (missing/invalid hash and missing key params as applicable)
    • includes one happy-path check for getportallogin_api with valid hash via mocked dependencies

Validation snapshot (Phase 8)

  • node tests/phase6/service-parity.test.cjs -> pass
  • node tests/phase6/service-behaviour.test.cjs -> pass (8/8)
  • node tests/phase7/service-behaviour.test.cjs -> pass (10/10)
  • node tests/phase8/service-behaviour.test.cjs -> pass (5/5)
  • npm run lint -> warnings only (pre-existing react-hooks dependency warnings; no new lint errors)

Manual HTTP checks (Phase 8)

  • Local dev server on http://localhost:3001.
  • Negative-path checks:
    • GET /api/file/deleteblobcase?... missing hash -> 400
    • GET /api/file/deleteblobcase?...&hash=bad -> 400
    • GET /api/file/deleteblobrep?... missing hash -> 400
    • GET /api/file/deleteblobrep?...&hash=bad -> 400
    • GET /api/file/deleteblobrep?... missing repfile -> 400
    • GET /api/file/createappealcompletemessage_api?... missing hash -> 400
    • GET /api/file/createappealcompletemessage_api?...&hash=bad -> 400
    • GET /api/file/createappealcompletemessage_api?... missing tempcaseref -> 400
    • GET /api/endpoint/getportallogin_api?... missing hash -> 400
    • GET /api/endpoint/getportallogin_api?...&hash=bad -> 400
    • GET /api/endpoint/getportallogin_api?... missing emailAddress -> 400
  • Valid-hash spot-check:
    • GET /api/endpoint/getportallogin_api?...&hash=<valid> reached handler with valid hash but returned 400 from upstream relay/CRM call in local environment (expected environmental dependency risk, not hash-guard bypass).

Latest update (2026-03-13 — Phase 9 hardening slice)

  • New branch created from origin/SIPS-Development with work item prefix:
    • TASK22019-phase-9-hardening
  • Hardened four additional sensitive file handlers with minimal reversible changes:
    • pages/api/file/createrepcompletemessage_api.js
    • pages/api/file/upload.js
    • pages/api/file/uploadsinglefile.js
    • pages/api/file/setupcontainer.js
  • Scope delivered:
    • re-enabled/enforced hash validation where bypassed/commented
    • added/standardized early 400 negative paths for missing/invalid hash and missing key parameters
    • reduced noisy logging in sensitive file-upload/message paths
    • preserved handler signatures and external response-shape contracts
  • Consumer parity updates:
    • actions/services/portalDirectService.js
      • append hash for createrepcompletemessage_api call
    • actions/services/documentDirectService.js
      • append hash for upload and uploadsinglefile calls
  • Added focused tests:
    • tests/phase9/service-behaviour.test.cjs
    • covers negative paths across all 4 phase-9 handlers

Validation snapshot (Phase 9)

  • node tests/phase6/service-parity.test.cjs -> pass
  • node tests/phase6/service-behaviour.test.cjs -> pass (8/8)
  • node tests/phase7/service-behaviour.test.cjs -> pass (10/10)
  • node tests/phase8/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase9/service-behaviour.test.cjs -> pass (5/5)
  • npm run lint -> warnings only (pre-existing react-hooks warnings; no new lint errors)

Manual HTTP checks (Phase 9)

  • Negative-path checks on localhost:3000:
    • GET /api/file/createrepcompletemessage_api?... missing hash -> 400
    • GET /api/file/createrepcompletemessage_api?...&hash=bad -> 400
    • POST /api/file/upload missing hash -> 400
    • POST /api/file/upload?hash=bad -> 400
    • POST /api/file/uploadsinglefile missing hash -> 400
    • POST /api/file/uploadsinglefile?hash=bad -> 400
    • GET /api/file/setupcontainer?ident=... missing hash -> 400
    • GET /api/file/setupcontainer?ident=...&hash=bad -> 400
    • GET /api/file/setupcontainer?hash=bad (missing ident) -> 400
  • Valid-hash happy-path spot-check:
    • Completed using .env.local runtime key: POST /api/file/uploadsinglefile?hash=<valid> -> 200

Rollback plan (Phase 9)

  1. Revert the four hardened API handlers.
  2. Revert direct-service hash append changes in documentDirectService and portalDirectService.
  3. Remove tests/phase9/service-behaviour.test.cjs if full slice rollback required.
  4. Re-run phase6/7/8/9 baseline tests + lint after rollback.

Latest update (2026-03-13 — Phase 10 hardening slice)

  • Continued on branch:
    • TASK22019-phase-9-hardening
  • Hardened four additional sensitive file handlers with minimal reversible changes:
    • pages/api/file/getawaitingsubmissionfromblob.js
    • pages/api/file/getprogressobjblob.js
    • pages/api/file/getbloblist.js
    • pages/api/file/getrepsblob.js
  • Scope delivered:
    • added explicit early 400 handling for missing/empty required inputs (container, casefolderID where applicable, hash)
    • standardized hash-mismatch negative-path checks to early return 400
    • removed legacy/noisy commented debug blocks from touched handlers
    • preserved existing handler signatures and response-shape contracts
  • Caller parity impact:
    • no new caller changes required in this slice because direct-service consumers already append hash for these APIs.
  • Added focused tests:
    • tests/phase10/service-behaviour.test.cjs
    • covers negative paths for all 4 selected phase-10 handlers
    • includes one valid-hash contract-preserving happy-path check (getbloblist via mocked dependencies)

Validation snapshot (Phase 10)

  • node tests/phase6/service-parity.test.cjs -> pass
  • node tests/phase6/service-behaviour.test.cjs -> pass (8/8)
  • node tests/phase7/service-behaviour.test.cjs -> pass (10/10)
  • node tests/phase8/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase9/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase10/service-behaviour.test.cjs -> pass (5/5)
  • npm run lint -> warnings only (pre-existing react-hooks warnings; no new lint errors)

Manual HTTP checks (Phase 10)

  • Negative-path checks on localhost:3000:
    • GET /api/file/getawaitingsubmissionfromblob?container=test (missing hash) -> 400
    • GET /api/file/getprogressobjblob?container=test&casefolderID=case-1 (missing hash) -> 400
    • GET /api/file/getbloblist?container=test&casefolderID=case-1 (missing hash) -> 400
    • GET /api/file/getrepsblob?container=test&casefolderID=case-1 (missing hash) -> 400
  • Valid-hash happy-path spot-check:
    • GET /api/file/getbloblist?container=test&casefolderID=case-1&hash=<valid> -> 500
    • expected due local storage/upstream dependency constraints, while confirming hash gate is no longer the failing check.

Rollback plan (Phase 10)

  1. Revert the four hardened API handlers.
  2. Remove tests/phase10/service-behaviour.test.cjs if full phase-10 rollback required.
  3. Re-run phase6/7/8/9/10 baseline tests + lint after rollback.

Latest update (2026-03-13 — Phase 11 hardening slice)

  • Continued on branch:
    • TASK22019-phase-9-hardening
  • Hardened three additional sensitive file handlers with minimal reversible changes:
    • pages/api/file/getbloblist.js
    • pages/api/file/deleteblob.js
    • pages/api/file/deleteawaitingsubmissionfromblob.js
  • Scope delivered:
    • added explicit early 400 handling for missing/empty required query inputs (container, casefolderID, blobname, hash as applicable)
    • standardized hash-mismatch negative-path checks to early return 400
    • removed legacy/noisy commented debug traces in touched handlers
    • preserved existing handler signatures and response-shape contracts
  • Caller parity impact:
    • no new caller changes required in this slice; direct-service consumers already pass expected query/hash data.
  • Added focused tests:
    • tests/phase11/service-behaviour.test.cjs
    • covers negative paths for selected phase-11 handlers
    • includes one valid-hash contract-preserving happy-path check (getbloblist via mocked dependencies)

Validation snapshot (Phase 11)

  • node tests/phase6/service-parity.test.cjs -> pass
  • node tests/phase6/service-behaviour.test.cjs -> pass (8/8)
  • node tests/phase7/service-behaviour.test.cjs -> pass (10/10)
  • node tests/phase8/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase9/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase10/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase11/service-behaviour.test.cjs -> pass (4/4)
  • npm run lint -> warnings only (pre-existing react-hooks warnings; no new lint errors)

Manual HTTP checks (Phase 11)

  • Negative-path checks on localhost:3000:
    • GET /api/file/getbloblist?container=test&casefolderID=case-1 (missing hash) -> 400
    • GET /api/file/deleteblob?container=test&casefolderID=case-1&blobname=file.pdf (missing hash) -> 400
    • GET /api/file/deleteawaitingsubmissionfromblob?container=test&casefolderID=case-1&blobname=file.pdf (missing hash) -> 400
    • GET /api/file/deleteblob?container=test&casefolderID=case-1&hash=bad (missing blobname/invalid hash) -> 400
  • Valid-hash happy-path spot-check:
    • GET /api/file/getbloblist?container=test&casefolderID=case-1&hash=<valid> -> 500
    • expected due local storage/upstream dependency constraints, while confirming hash gate is no longer the failing check.

Rollback plan (Phase 11)

  1. Revert the three hardened API handlers.
  2. Remove tests/phase11/service-behaviour.test.cjs if full phase-11 rollback required.
  3. Re-run phase6/7/8/9/10/11 baseline tests + lint after rollback.

Latest update (2026-03-13 — Phase 12 hardening slice)

  • Continued on branch:
    • TASK22019-phase-9-hardening
  • Hardened four additional sensitive handlers with minimal reversible changes:
    • pages/api/file/downloadblob.js
    • pages/api/file/getbloblistproxy.js
    • pages/api/file/getrepsblobproxy.js
    • pages/api/file/getawaitingsubmissionfromblobproxy.js
  • Scope delivered:
    • added explicit early 400 handling for missing/empty required query inputs (container, casefolderID, blobname, hash as applicable)
    • standardized hash-mismatch negative-path checks for downloadblob
    • preserved existing function signatures and response-shape contracts
  • Added focused tests:
    • tests/phase12/service-behaviour.test.cjs
    • covers negative paths for selected phase-12 handlers
    • includes one valid-hash contract-preserving happy-path check (downloadblob via mocked dependencies)

Validation snapshot (Phase 12)

  • node tests/phase6/service-parity.test.cjs -> pass
  • node tests/phase6/service-behaviour.test.cjs -> pass (8/8)
  • node tests/phase7/service-behaviour.test.cjs -> pass (10/10)
  • node tests/phase8/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase9/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase10/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase11/service-behaviour.test.cjs -> pass (4/4)
  • node tests/phase12/service-behaviour.test.cjs -> pass (4/4)
  • npm run lint -> warnings only (pre-existing react-hooks warnings; no new lint errors)

Manual HTTP checks (Phase 12)

  • Negative-path checks on localhost:3000:
    • GET /api/file/downloadblob?container=test&casefolderID=case-1&blobname=file.pdf (missing hash) -> 400
    • GET /api/file/downloadblob?container=test&casefolderID=case-1&blobname=file.pdf&hash=bad -> 400
    • GET /api/file/getbloblistproxy?casefolderID=case-1 (missing container) -> 400
    • GET /api/file/getrepsblobproxy (missing container) -> 400
    • GET /api/file/getawaitingsubmissionfromblobproxy (missing container) -> 400
  • Valid-hash happy-path spot-check:
    • GET /api/file/downloadblob?container=test&casefolderID=case-1&blobname=file.pdf&hash=<valid> -> 500
    • expected due local storage/upstream dependency constraints, while confirming hash gate is no longer the failing check.

Rollback plan (Phase 12)

  1. Revert the four hardened API handlers.
  2. Remove tests/phase12/service-behaviour.test.cjs if full phase-12 rollback required.
  3. Re-run phase6/7/8/9/10/11/12 baseline tests + lint after rollback.

Latest update (2026-03-13 — Phase 13 hardening slice)

  • Continued on branch:
    • TASK22019-phase-9-hardening
  • Hardened four additional sensitive handlers with minimal reversible changes:
    • pages/api/file/deleteblobcase.js
    • pages/api/file/deleteblobrep.js
    • pages/api/file/createcaseinvolvement_api.js
    • pages/api/file/createrepinvolvement_api.js
  • Scope delivered:
    • added explicit early 400 handling for missing/empty required query/body inputs (hash, contactid, incidentid as applicable)
    • standardized hash-mismatch negative-path checks for delete-blob handlers
    • removed noisy body/query logging in involvement handlers
    • preserved existing function signatures and response-shape contracts
  • Added focused tests:
    • tests/phase13/service-behaviour.test.cjs
    • covers negative paths for selected phase-13 handlers
    • includes valid-hash/valid-body contract-preserving happy-path checks via mocked dependencies

Validation snapshot (Phase 13)

  • node tests/phase6/service-parity.test.cjs -> pass
  • node tests/phase6/service-behaviour.test.cjs -> pass (8/8)
  • node tests/phase7/service-behaviour.test.cjs -> pass (10/10)
  • node tests/phase8/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase9/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase10/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase11/service-behaviour.test.cjs -> pass (4/4)
  • node tests/phase12/service-behaviour.test.cjs -> pass (4/4)
  • node tests/phase13/service-behaviour.test.cjs -> pass (7/7)
  • npm run lint -> warnings only (pre-existing react-hooks warnings; no new lint errors)

Manual HTTP checks (Phase 13)

  • Negative-path checks on localhost:3000:
    • GET /api/file/deleteblobcase?container=test&casefolderID=case-1 (missing hash) -> 400
    • GET /api/file/deleteblobcase?container=test&casefolderID=case-1&hash=bad -> 400
    • GET /api/file/deleteblobrep?container=test&casefolderID=case-1&repfile=r.pdf (missing hash) -> 400
    • POST /api/file/createcaseinvolvement_api with {} -> 400
    • POST /api/file/createrepinvolvement_api with {} -> 400
  • Valid-hash happy-path spot-check:
    • GET /api/file/deleteblobcase?container=test&casefolderID=case-1&hash=<valid> -> 500
    • expected due local storage/upstream dependency constraints, while confirming hash gate is no longer the failing check.

Rollback plan (Phase 13)

  1. Revert the four hardened API handlers.
  2. Remove tests/phase13/service-behaviour.test.cjs if full phase-13 rollback required.
  3. Re-run phase6/7/8/9/10/11/12/13 baseline tests + lint after rollback.

Latest update (2026-03-13 — Phase 14 client-hash signing fix)

  • Continued on branch:
    • TASK22019-phase-9-hardening
  • Fixed authenticated user-journey runtime error during new appeal flow where client-side hashing tried to use server-only HASHKEY.
  • Added authenticated server-side hash signer endpoint:
    • pages/api/endpoint/gethash_api.js
    • requires session (getSession), allow-lists supported API paths, returns { hash }.
  • Updated direct services to request hash from server signer for browser calls, with server-side fallback only when HASHKEY exists:
    • actions/services/documentDirectService.js
    • actions/services/portalDirectService.js
  • Preserved existing API contracts and response shapes in file handlers.
  • Added focused tests:
    • tests/phase14/service-behaviour.test.cjs
    • covers signer endpoint negative paths + authenticated happy path.

Validation snapshot (Phase 14)

  • node tests/phase6/service-parity.test.cjs -> pass
  • node tests/phase6/service-behaviour.test.cjs -> pass (8/8)
  • node tests/phase7/service-behaviour.test.cjs -> pass (10/10)
  • node tests/phase8/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase9/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase10/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase11/service-behaviour.test.cjs -> pass (4/4)
  • node tests/phase12/service-behaviour.test.cjs -> pass (4/4)
  • node tests/phase13/service-behaviour.test.cjs -> pass (7/7)
  • node tests/phase14/service-behaviour.test.cjs -> pass (4/4)
  • npm run lint -> warnings only (pre-existing hook dependency warnings)

Rollback plan (Phase 14)

  1. Revert pages/api/endpoint/gethash_api.js.
  2. Revert direct-service hash signer usage in documentDirectService.js and portalDirectService.js.
  3. Remove tests/phase14/service-behaviour.test.cjs if rolling back full phase-14 slice.
  4. Re-run phase6phase14 tests + lint.

Latest update (2026-03-13 — Phase 14 closeout follow-up)

  • Continued on branch:
    • TASK22019-phase-9-hardening
  • Completed follow-up hardening and contract-alignment after runtime verification:
    • actions/services/accountDirectService.js
      • getPortalLogin now uses authenticated signer endpoint (/api/endpoint/gethash_api) for browser-safe hash generation
      • retains server-only fallback to local hashAPIPath when HASHKEY is available
    • pages/api/endpoint/gethash_api.js
      • allow-list expanded for /api/endpoint/getportallogin_api
    • pages/api/file/getrepsblob.js
      • removed enforced casefolderID guard and argument pass-through to align with route contract (/api/file/getrepsblob?container=...)
    • components/elements/index.js
      • added missing updateLinks import from components/utils to resolve Quill runtime error
  • Tests updated:
    • tests/phase7/service-behaviour.test.cjs
      • updated getPortalLogin expectations for signer endpoint behavior
    • tests/phase14/service-behaviour.test.cjs
      • added allow-list coverage for signer path /api/endpoint/getportallogin_api

Validation snapshot (Phase 14 follow-up)

  • node tests/phase6/service-parity.test.cjs -> pass
  • node tests/phase6/service-behaviour.test.cjs -> pass (8/8)
  • node tests/phase7/service-behaviour.test.cjs -> pass (10/10)
  • node tests/phase8/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase9/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase10/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase11/service-behaviour.test.cjs -> pass (4/4)
  • node tests/phase12/service-behaviour.test.cjs -> pass (4/4)
  • node tests/phase13/service-behaviour.test.cjs -> pass (7/7)
  • node tests/phase14/service-behaviour.test.cjs -> pass (5/5)
  • npm run lint -> warnings only (pre-existing hook dependency warnings)

Risks + mitigations (follow-up)

  • Risk: signer endpoint over-expansion could broaden hash issuance.
    • Mitigation: strict allow-list retained; only required getportallogin_api path added.
  • Risk: tightened/changed guards could break existing caller contracts.
    • Mitigation: getrepsblob guard aligned back to actual route contract; response shape unchanged.
  • Risk: UI runtime dependency regressions during hardening verification.
    • Mitigation: missing updateLinks import restored with minimal diff.

Rollback plan (follow-up)

  1. Revert signer-path migration commit 6094874 (or files: accountDirectService.js, gethash_api.js, tests/phase7, tests/phase14).
  2. Revert contract/import alignment commit b8fa514 (or files: getrepsblob.js, components/elements/index.js).
  3. Re-run phase6phase14 tests and lint to confirm rollback parity.

Rollback plan (Phase 8)

  1. Revert the four hardened API handlers.
  2. Revert direct-service hash append changes in documentDirectService and portalDirectService.
  3. Remove tests/phase8/service-behaviour.test.cjs if full slice rollback required.
  4. Re-run phase6/7 baseline tests + lint after rollback.

Latest update (2026-03-13 — Phase 15 hardening slice)

  • New branch created from origin/SIPS-Development with confirmed work item prefix:
    • TASK22028-phase15-hardening-slice
  • Delivered a small consistency-only hardening slice across 4 additional sensitive file handlers:
    • pages/api/file/upload.js
    • pages/api/file/uploadsinglefile.js
    • pages/api/file/createappealcompletemessage_api.js
    • pages/api/file/setupcontainer.js
  • Scope delivered:
    • standardized explicit early 400 handling for missing hash in handlers where hash validation was present but missing-hash guard was inconsistent
    • standardized guard style in setupcontainer to early-return on hash mismatch (same status/contract)
    • standardized missing required hash handling in createappealcompletemessage_api
    • preserved response shapes and signatures (no contract changes)
  • Added focused phase-15 tests:
    • tests/phase15/service-behaviour.test.cjs
    • negative-path coverage for missing hash across all 4 handlers
    • additional required-input checks where applicable
    • one valid-hash happy-path contract check (setupcontainer -> 200 with existing response shape)

Validation snapshot (Phase 15)

  • node tests/phase6/service-parity.test.cjs -> pass
  • node tests/phase6/service-behaviour.test.cjs -> pass (8/8)
  • node tests/phase7/service-behaviour.test.cjs -> pass (10/10)
  • node tests/phase8/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase9/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase10/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase11/service-behaviour.test.cjs -> pass (4/4)
  • node tests/phase12/service-behaviour.test.cjs -> pass (4/4)
  • node tests/phase13/service-behaviour.test.cjs -> pass (7/7)
  • node tests/phase14/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase15/service-behaviour.test.cjs -> pass (5/5)
  • npm run lint -> warnings only (pre-existing react-hooks/exhaustive-deps warnings)

Manual HTTP snapshot (Phase 15)

  • Dev server run on http://localhost:3002.
  • Negative-path checks:
    • POST /api/file/upload missing hash -> 400
    • POST /api/file/upload?hash=wrong -> 400
    • POST /api/file/uploadsinglefile missing hash -> 400
    • POST /api/file/uploadsinglefile?hash=wrong -> 400
    • GET /api/file/createappealcompletemessage_api?container=c1&tempcaseref=t1 missing hash -> 400
    • GET /api/file/createappealcompletemessage_api?container=c1&tempcaseref=t1&hash=wrong -> 400
    • GET /api/file/createappealcompletemessage_api?container=c1 missing required params/hash -> 400
    • GET /api/file/setupcontainer?ident=c1 missing hash -> 400
    • GET /api/file/setupcontainer?ident=c1&hash=wrong -> 400
    • GET /api/file/setupcontainer?hash=<valid> missing required ident -> 400
  • Valid-hash spot-check:
    • GET /api/file/setupcontainer?ident=c1&hash=<valid> -> 200

Rollback plan (Phase 15)

  1. Revert these files:
    • pages/api/file/upload.js
    • pages/api/file/uploadsinglefile.js
    • pages/api/file/createappealcompletemessage_api.js
    • pages/api/file/setupcontainer.js
    • tests/phase15/service-behaviour.test.cjs
  2. Re-run phase6phase15 tests and lint to confirm parity.

Latest update (2026-03-13 — Phase 16 file-proxy consistency slice)

  • Continued on branch:
    • TASK22028-phase15-hardening-slice
  • Delivered a small consistency-only hardening slice across 3 sensitive file proxy handlers:
    • pages/api/file/getbloblistproxy.js
    • pages/api/file/getrepsblobproxy.js
    • pages/api/file/getawaitingsubmissionfromblobproxy.js
  • Scope delivered:
    • removed unused imports/constants in touched handlers to reduce noisy/unsafe dead code
    • standardized required input checks using shared local hasValue pattern
    • preserved response shape/signature/status behavior contracts
  • Added focused tests:
    • tests/phase16/service-behaviour.test.cjs
    • negative-path checks for missing required container/casefolder inputs
    • one valid-input happy-path contract check for getbloblistproxy (200 + passthrough shape)

Validation snapshot (Phase 16)

  • node tests/phase6/service-parity.test.cjs -> pass
  • node tests/phase6/service-behaviour.test.cjs -> pass (8/8)
  • node tests/phase7/service-behaviour.test.cjs -> pass (10/10)
  • node tests/phase8/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase9/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase10/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase11/service-behaviour.test.cjs -> pass (4/4)
  • node tests/phase12/service-behaviour.test.cjs -> pass (4/4)
  • node tests/phase13/service-behaviour.test.cjs -> pass (7/7)
  • node tests/phase14/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase15/service-behaviour.test.cjs -> pass (5/5)
  • node tests/phase16/service-behaviour.test.cjs -> pass (4/4)
  • npm run lint -> warnings only (pre-existing react-hooks/exhaustive-deps warnings)

Manual HTTP checks (Phase 16)

  • Dev server on http://localhost:3002.
  • Negative-path checks:
    • /api/file/getbloblistproxy?casefolderID=case-1 -> 400
    • /api/file/getbloblistproxy?container=c1 -> 400
    • /api/file/getrepsblobproxy -> 400
    • /api/file/getawaitingsubmissionfromblobproxy -> 400
  • Feasible valid-input spot-check:
    • /api/file/getbloblistproxy?container=c1&casefolderID=case-1 -> 400 (expected downstream/local dependency behavior; input guard passed)

Rollback plan (Phase 16)

  1. Revert commit c196edb or files:
    • pages/api/file/getbloblistproxy.js
    • pages/api/file/getrepsblobproxy.js
    • pages/api/file/getawaitingsubmissionfromblobproxy.js
    • tests/phase16/service-behaviour.test.cjs
  2. Re-run phase6phase16 tests and lint.

Latest update (2026-03-13 — signer allow-list follow-up)

  • Branch: TASK22028-phase15-hardening-slice
  • Fix applied:
    • added /api/file/deleteblobcase to signer endpoint allow-list in pages/api/endpoint/gethash_api.js
  • Test update:
    • extended tests/phase14/service-behaviour.test.cjs with deleteblobcase allow-list coverage

Validation snapshot (follow-up)

  • node tests/phase14/service-behaviour.test.cjs -> pass (6/6)
  • node tests/phase7/service-behaviour.test.cjs -> pass (10/10)
  • npm run lint -> warnings only (pre-existing)

Outstanding risks / gaps

  • Navigation regressions across EN/CY + route query combinations.
  • Drift between rewrite config and component-level locale path logic.
  • Deployment ambiguity due to multiple CI/CD artifacts (Azure pipeline, Jenkins, Docker) with unclear active source of truth.
  • Security posture variability where hash checks are bypassed/commented in selected handlers.

Latest update (2026-03-13 — Phase 7 post-Phase-6 hardening)

  • New branch created from origin/SIPS-Development with required work item prefix:
    • TASK21988a-phase7-postphase6-hardening
  • Fixed known pre-existing SSR serialization issue on search results route:
    • pages/searchresults.js
    • updated SSR dispatch fallback from setSearch(query.q) to setSearch(query?.q || "")
    • result: /searchresults and /cy/searchresults now return 200 in local smoke checks (no 500 observed in this run).
  • Added expanded behavioural coverage for remaining direct-service domains:
    • new test file: tests/phase7/service-behaviour.test.cjs
    • includes document, portal, account, notify, integration behavioural checks
    • includes negative-path assertions for relay/hash/token-sensitive behaviors where feasible:
      • hashed URL append checks (hashAPIPath)
      • error handling contracts (undefined/error string/rethrow depending on existing function contract)

Validation snapshot (Phase 7)

  • node tests/phase6/service-parity.test.cjs -> pass
  • node tests/phase6/service-behaviour.test.cjs -> pass (8/8)
  • node tests/phase7/service-behaviour.test.cjs -> pass (10/10)
  • npm run lint -> warnings only (pre-existing hook dependency warnings; no new lint errors)

Targeted smoke snapshot (local dev server)

  • Note: dev server auto-started on http://localhost:3001 because port 3000 was in use.
  • Search flow:
    • GET /searchresults and GET /cy/searchresults -> 200
  • Case flow:
    • GET /case and GET /cy/case -> 200
  • My Portal flow (negative-path):
    • GET /myportal and GET /cy/myportal -> 307 redirect to /auth/signin
  • Document flow (negative-path):
    • GET /api/file/getbloblistproxy?container=test&casefolderID=test -> 400
  • Notify flow (negative-path):
    • POST /api/email/notify with {} -> 400