45 KiB
45 KiB
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.jssplit (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.jsstill 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-monolithcreated from development branch for Priority 1 refactor implementation. actions/index.jsreduced to a compatibility barrel.- New core helper modules added under
actions/core/:env.jslogger.jshash.jstoken.jsheaders.js
- Existing action wrappers moved to
actions/services/legacyActionsService.jsand 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.jsbarrel. - 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/*andactions/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.jscomponents/admin/tabs/storage.jscomponents/admin/utils/serverside.jscomponents/case/documents.jscomponents/case/representation/representationComplete.jscomponents/case/representation/representationElements.jscomponents/elements/index.jscomponents/myportal/awaitingsubmissionfromblob.jscomponents/myportal/topthree.jscomponents/myportal/topthree_reps.jscomponents/utils/index.jslib/myportal/loadMyPortalAppealPage.jslib/newappeal/loadNewAppealPage.js
- Updated direct service/core imports in:
- Additional Priority 1 consumer migration pass completed for view-all/search/unsubscribe flows:
- Updated direct service/core imports in:
components/myportal/viewall.jscomponents/search/addresssearchresults.jspages/unsubscribe/[watchlistid].jspages/unsubscribeall/[watchlistid].js
- Updated direct service/core imports in:
- Broad
actionsbarrel import count reduced again; remaining non-comment usages are now concentrated in selectedpages/api/endpoint/*andpages/api/file/*handlers. - Additional Priority 1 endpoint/file proxy migration chunk completed:
- Updated imports in:
pages/api/endpoint/getmylpacases_api.jspages/api/endpoint/getbasicdnssearchpaged_api.jspages/api/endpoint/getsearchdocumentdetailspaged_api.jspages/api/endpoint/getbasicsearchpaged_api.jspages/api/file/getawaitingsubmissionfromblobproxy.jspages/api/file/getrepsblobproxy.jspages/api/file/getbloblistproxy.jspages/api/file/createappealcompletemessageproxy_api.js
- Migrated from broad
../../../actionsimports to focusedactions/core/*+ service imports. - Removed duplicated local hash helper in
getmylpacases_api.jsand reusedactions/core/hash.
- Updated imports in:
- Broad
actionsimport scan now reports only comment-only references (no active broad imports in.jsfiles). - Lint check re-run outcome unchanged:
next lintfails 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:
f0202bbfa98535bef8f25
- Active broad
.../actionsimports are now eliminated from live.jscode paths. - Next refactor phase will begin on a new branch and focus on splitting
actions/services/legacyActionsService.jsinto smaller direct implementation modules. - Recommended decomposition order for the new branch:
- reference/search extraction
- portal/document extraction
- 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.jsto source fromsearchDirectService - Updated
actions/services/referenceDataService.jsto source fromreferenceDataDirectService
- Added
- Compatibility approach preserved: public grouped service exports and function signatures remain unchanged for callers.
- Validation status unchanged:
npm run lintstill 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.jsto source fromdocumentDirectService
- Added
- 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 lintpasses with warnings only (no blocking errors).
- service import scan now shows remaining legacy-backed grouped modules are:
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.jsaccountDirectService.jscaseDirectService.jsadminDirectService.jsintegrationDirectService.jsnotifyDirectService.js
actions/services/legacyActionsService.jsremoved after import parity checks.- Validation evidence:
actions/servicesimport scan: zero./legacyActionsServicereferencesnpm run lint: warnings only, no blocking errorsnpm 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.jsexport list stability/order.
- Added shared service error helper:
actions/services/httpServiceUtils.js- centralizes common
consoleLogger + return error.responseandErrResponseshape patterns.
- Applied low-risk duplication reduction in direct services (no signature/shape changes intended):
searchDirectService.jsreferenceDataDirectService.jscaseDirectService.jsadminDirectService.js
- Logging cleanup/redaction-oriented hardening (sensitive-flow noisy logs removed):
- removed debug
console.logstatements from:searchDirectService.jsdocumentDirectService.jsportalDirectService.jscaseDirectService.jsadminDirectService.js
- removed debug
Validation snapshot (Phase 6)
node tests/phase6/service-parity.test.cjs-> passnode 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.searchStringundefined in SSR payload), observed in/tmp/phase6-dev.log.GET /advancedsearchandGET /cy/advancedsearch-> 200
- Case flow:
GET /caseandGET /cy/case-> 200
- My Portal flow (negative-path):
GET /myportalandGET /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/notifywith{}-> 400
Latest update (2026-03-13 — Phase 8 hardening slice)
- New branch created from
origin/SIPS-Developmentwith work item prefix:TASK22017-phase8-hardening-slice
- Hardened four sensitive API handlers with minimal reversible guards:
pages/api/file/deleteblobcase.jspages/api/file/deleteblobrep.jspages/api/file/createappealcompletemessage_api.jspages/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_apiwith valid hash via mocked dependencies
Validation snapshot (Phase 8)
node tests/phase6/service-parity.test.cjs-> passnode 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 -> 400GET /api/file/deleteblobcase?...&hash=bad-> 400GET /api/file/deleteblobrep?...missing hash -> 400GET /api/file/deleteblobrep?...&hash=bad-> 400GET /api/file/deleteblobrep?...missingrepfile-> 400GET /api/file/createappealcompletemessage_api?...missing hash -> 400GET /api/file/createappealcompletemessage_api?...&hash=bad-> 400GET /api/file/createappealcompletemessage_api?...missingtempcaseref-> 400GET /api/endpoint/getportallogin_api?...missing hash -> 400GET /api/endpoint/getportallogin_api?...&hash=bad-> 400GET /api/endpoint/getportallogin_api?...missingemailAddress-> 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-Developmentwith work item prefix:TASK22019-phase-9-hardening
- Hardened four additional sensitive file handlers with minimal reversible changes:
pages/api/file/createrepcompletemessage_api.jspages/api/file/upload.jspages/api/file/uploadsinglefile.jspages/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_apicall
- append hash for
actions/services/documentDirectService.js- append hash for
uploadanduploadsinglefilecalls
- append hash for
- 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-> passnode 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 -> 400GET /api/file/createrepcompletemessage_api?...&hash=bad-> 400POST /api/file/uploadmissing hash -> 400POST /api/file/upload?hash=bad-> 400POST /api/file/uploadsinglefilemissing hash -> 400POST /api/file/uploadsinglefile?hash=bad-> 400GET /api/file/setupcontainer?ident=...missing hash -> 400GET /api/file/setupcontainer?ident=...&hash=bad-> 400GET /api/file/setupcontainer?hash=bad(missing ident) -> 400
- Valid-hash happy-path spot-check:
- Completed using
.env.localruntime key:POST /api/file/uploadsinglefile?hash=<valid>-> 200
- Completed using
Rollback plan (Phase 9)
- Revert the four hardened API handlers.
- Revert direct-service hash append changes in
documentDirectServiceandportalDirectService. - Remove
tests/phase9/service-behaviour.test.cjsif full slice rollback required. - 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.jspages/api/file/getprogressobjblob.jspages/api/file/getbloblist.jspages/api/file/getrepsblob.js
- Scope delivered:
- added explicit early 400 handling for missing/empty required inputs (
container,casefolderIDwhere 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
- added explicit early 400 handling for missing/empty required inputs (
- 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 (
getbloblistvia mocked dependencies)
Validation snapshot (Phase 10)
node tests/phase6/service-parity.test.cjs-> passnode 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) -> 400GET /api/file/getprogressobjblob?container=test&casefolderID=case-1(missing hash) -> 400GET /api/file/getbloblist?container=test&casefolderID=case-1(missing hash) -> 400GET /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)
- Revert the four hardened API handlers.
- Remove
tests/phase10/service-behaviour.test.cjsif full phase-10 rollback required. - 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.jspages/api/file/deleteblob.jspages/api/file/deleteawaitingsubmissionfromblob.js
- Scope delivered:
- added explicit early 400 handling for missing/empty required query inputs (
container,casefolderID,blobname,hashas 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
- added explicit early 400 handling for missing/empty required query inputs (
- 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 (
getbloblistvia mocked dependencies)
Validation snapshot (Phase 11)
node tests/phase6/service-parity.test.cjs-> passnode 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) -> 400GET /api/file/deleteblob?container=test&casefolderID=case-1&blobname=file.pdf(missing hash) -> 400GET /api/file/deleteawaitingsubmissionfromblob?container=test&casefolderID=case-1&blobname=file.pdf(missing hash) -> 400GET /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)
- Revert the three hardened API handlers.
- Remove
tests/phase11/service-behaviour.test.cjsif full phase-11 rollback required. - 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.jspages/api/file/getbloblistproxy.jspages/api/file/getrepsblobproxy.jspages/api/file/getawaitingsubmissionfromblobproxy.js
- Scope delivered:
- added explicit early 400 handling for missing/empty required query inputs (
container,casefolderID,blobname,hashas applicable) - standardized hash-mismatch negative-path checks for
downloadblob - preserved existing function signatures and response-shape contracts
- added explicit early 400 handling for missing/empty required query inputs (
- 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 (
downloadblobvia mocked dependencies)
Validation snapshot (Phase 12)
node tests/phase6/service-parity.test.cjs-> passnode 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) -> 400GET /api/file/downloadblob?container=test&casefolderID=case-1&blobname=file.pdf&hash=bad-> 400GET /api/file/getbloblistproxy?casefolderID=case-1(missing container) -> 400GET /api/file/getrepsblobproxy(missing container) -> 400GET /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)
- Revert the four hardened API handlers.
- Remove
tests/phase12/service-behaviour.test.cjsif full phase-12 rollback required. - 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.jspages/api/file/deleteblobrep.jspages/api/file/createcaseinvolvement_api.jspages/api/file/createrepinvolvement_api.js
- Scope delivered:
- added explicit early 400 handling for missing/empty required query/body inputs (
hash,contactid,incidentidas 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 explicit early 400 handling for missing/empty required query/body inputs (
- 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-> passnode 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) -> 400GET /api/file/deleteblobcase?container=test&casefolderID=case-1&hash=bad-> 400GET /api/file/deleteblobrep?container=test&casefolderID=case-1&repfile=r.pdf(missing hash) -> 400POST /api/file/createcaseinvolvement_apiwith{}-> 400POST /api/file/createrepinvolvement_apiwith{}-> 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)
- Revert the four hardened API handlers.
- Remove
tests/phase13/service-behaviour.test.cjsif full phase-13 rollback required. - 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
HASHKEYexists:actions/services/documentDirectService.jsactions/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-> passnode 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)
- Revert
pages/api/endpoint/gethash_api.js. - Revert direct-service hash signer usage in
documentDirectService.jsandportalDirectService.js. - Remove
tests/phase14/service-behaviour.test.cjsif rolling back full phase-14 slice. - Re-run phase6–phase14 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.jsgetPortalLoginnow uses authenticated signer endpoint (/api/endpoint/gethash_api) for browser-safe hash generation- retains server-only fallback to local
hashAPIPathwhenHASHKEYis available
pages/api/endpoint/gethash_api.js- allow-list expanded for
/api/endpoint/getportallogin_api
- allow-list expanded for
pages/api/file/getrepsblob.js- removed enforced
casefolderIDguard and argument pass-through to align with route contract (/api/file/getrepsblob?container=...)
- removed enforced
components/elements/index.js- added missing
updateLinksimport fromcomponents/utilsto resolve Quill runtime error
- added missing
- Tests updated:
tests/phase7/service-behaviour.test.cjs- updated
getPortalLoginexpectations for signer endpoint behavior
- updated
tests/phase14/service-behaviour.test.cjs- added allow-list coverage for signer path
/api/endpoint/getportallogin_api
- added allow-list coverage for signer path
Validation snapshot (Phase 14 follow-up)
node tests/phase6/service-parity.test.cjs-> passnode 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_apipath added.
- Mitigation: strict allow-list retained; only required
- Risk: tightened/changed guards could break existing caller contracts.
- Mitigation:
getrepsblobguard aligned back to actual route contract; response shape unchanged.
- Mitigation:
- Risk: UI runtime dependency regressions during hardening verification.
- Mitigation: missing
updateLinksimport restored with minimal diff.
- Mitigation: missing
Rollback plan (follow-up)
- Revert signer-path migration commit
6094874(or files:accountDirectService.js,gethash_api.js,tests/phase7,tests/phase14). - Revert contract/import alignment commit
b8fa514(or files:getrepsblob.js,components/elements/index.js). - Re-run phase6–phase14 tests and lint to confirm rollback parity.
Rollback plan (Phase 8)
- Revert the four hardened API handlers.
- Revert direct-service hash append changes in
documentDirectServiceandportalDirectService. - Remove
tests/phase8/service-behaviour.test.cjsif full slice rollback required. - Re-run phase6/7 baseline tests + lint after rollback.
Latest update (2026-03-13 — Phase 15 hardening slice)
- New branch created from
origin/SIPS-Developmentwith 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.jspages/api/file/uploadsinglefile.jspages/api/file/createappealcompletemessage_api.jspages/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
setupcontainerto 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-> passnode 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-existingreact-hooks/exhaustive-depswarnings)
Latest update (2026-03-14 — Phase 19 endpoint consistency slice)
- Continued on branch:
TASK22057-phase17-hardening-closeout
- Delivered a small additional consistency-only endpoint slice across:
pages/api/endpoint/createwatchedcases_api.jspages/api/endpoint/getappealtypes_api.jspages/api/endpoint/getdnslist_api.js
- Scope delivered:
- added required early 400 handling for malformed/missing
@odata.bindvalues increatewatchedcases_api - removed noisy query logging in
getappealtypes_apiandgetdnslist_api - preserved response-shape/signature contracts
- added required early 400 handling for malformed/missing
- Added focused tests:
tests/phase19/service-behaviour.test.cjs(5/5 passing)
Validation snapshot (Phase 19)
node tests/phase6/service-parity.test.cjs-> passnode tests/phase6/service-behaviour.test.cjs-> pass (8/8)node tests/phase7/service-behaviour.test.cjs-> pass (12/12)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 (9/9)node tests/phase15/service-behaviour.test.cjs-> pass (5/5)node tests/phase16/service-behaviour.test.cjs-> pass (4/4)node tests/phase17/service-behaviour.test.cjs-> pass (6/6)node tests/phase18/service-behaviour.test.cjs-> pass (8/8)node tests/phase19/service-behaviour.test.cjs-> pass (5/5)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-depswarnings)
Latest update (2026-03-14 — Phase 20 endpoint consistency slice)
- Continued on branch:
TASK22057-phase17-hardening-closeout
- Delivered a small additional consistency-only endpoint slice across:
pages/api/endpoint/getbasicdnssearch_api.jspages/api/endpoint/getbasicdnsurlsearch_api.jspages/api/endpoint/getbasicsearchdetailspaged_api.js
- Scope delivered:
- removed noisy query logging in
getbasicdnssearch_api - standardized missing/empty
searchStringhandling ingetbasicdnsurlsearch_apiwith early 400 - standardized missing required input handling in
getbasicsearchdetailspaged_api(appealTypeName,primaryIdAttribute,incidentID) with early 400 - preserved response-shape/signature contracts
- removed noisy query logging in
- Added focused tests:
tests/phase20/service-behaviour.test.cjs(5/5 passing)
Validation snapshot (Phase 20)
node tests/phase6/service-parity.test.cjs-> passnode tests/phase6/service-behaviour.test.cjs-> pass (8/8)node tests/phase7/service-behaviour.test.cjs-> pass (12/12)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 (9/9)node tests/phase15/service-behaviour.test.cjs-> pass (5/5)node tests/phase16/service-behaviour.test.cjs-> pass (4/4)node tests/phase17/service-behaviour.test.cjs-> pass (6/6)node tests/phase18/service-behaviour.test.cjs-> pass (8/8)node tests/phase19/service-behaviour.test.cjs-> pass (5/5)node tests/phase20/service-behaviour.test.cjs-> pass (5/5)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-depswarnings)
Manual HTTP snapshot (Phase 15)
- Dev server run on
http://localhost:3002. - Negative-path checks:
POST /api/file/uploadmissing hash -> 400POST /api/file/upload?hash=wrong-> 400POST /api/file/uploadsinglefilemissing hash -> 400POST /api/file/uploadsinglefile?hash=wrong-> 400GET /api/file/createappealcompletemessage_api?container=c1&tempcaseref=t1missing hash -> 400GET /api/file/createappealcompletemessage_api?container=c1&tempcaseref=t1&hash=wrong-> 400GET /api/file/createappealcompletemessage_api?container=c1missing required params/hash -> 400GET /api/file/setupcontainer?ident=c1missing hash -> 400GET /api/file/setupcontainer?ident=c1&hash=wrong-> 400GET /api/file/setupcontainer?hash=<valid>missing requiredident-> 400
- Valid-hash spot-check:
GET /api/file/setupcontainer?ident=c1&hash=<valid>-> 200
Rollback plan (Phase 15)
- Revert these files:
pages/api/file/upload.jspages/api/file/uploadsinglefile.jspages/api/file/createappealcompletemessage_api.jspages/api/file/setupcontainer.jstests/phase15/service-behaviour.test.cjs
- Re-run phase6–phase15 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.jspages/api/file/getrepsblobproxy.jspages/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
hasValuepattern - 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-> passnode 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-existingreact-hooks/exhaustive-depswarnings)
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)
- Revert commit
c196edbor files:pages/api/file/getbloblistproxy.jspages/api/file/getrepsblobproxy.jspages/api/file/getawaitingsubmissionfromblobproxy.jstests/phase16/service-behaviour.test.cjs
- Re-run phase6–phase16 tests and lint.
Latest update (2026-03-13 — signer allow-list follow-up)
- Branch:
TASK22028-phase15-hardening-slice - Fix applied:
- added
/api/file/deleteblobcaseto signer endpoint allow-list inpages/api/endpoint/gethash_api.js
- added
- Test update:
- extended
tests/phase14/service-behaviour.test.cjswith deleteblobcase allow-list coverage
- extended
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)
Latest update (2026-03-13 — signer delete-flow follow-up)
- Branch:
TASK22028-phase15-hardening-slice - Extended signer allow-list and browser signer usage for additional delete flows:
deleteWatchedCasesdeleteMyRepresentationsdeleteAwaitingSubmissionsFromBlobdeleteMyRepresentationsFromBlob
Validation snapshot (delete-flow follow-up)
node tests/phase7/service-behaviour.test.cjs-> pass (12/12)node tests/phase14/service-behaviour.test.cjs-> pass (9/9)npm run lint-> warnings only (pre-existing)
Latest update (2026-03-13 — myportal + i18n follow-up)
- Branch:
TASK22028-phase15-hardening-slice - Delivered follow-up fixes:
- myportal representation delete calls now use
caseRefin top-three and view-all flows - missing
myportalnamespace added for/newappeal/[appealtypes]ini18n.js
- myportal representation delete calls now use
Validation snapshot (myportal + i18n follow-up)
node tests/phase7/service-behaviour.test.cjs-> pass (12/12)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-Developmentwith 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)tosetSearch(query?.q || "") - result:
/searchresultsand/cy/searchresultsnow 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)
- hashed URL append checks (
- new test file:
Validation snapshot (Phase 7)
node tests/phase6/service-parity.test.cjs-> passnode 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:3001because port3000was in use. - Search flow:
GET /searchresultsandGET /cy/searchresults-> 200
- Case flow:
GET /caseandGET /cy/case-> 200
- My Portal flow (negative-path):
GET /myportalandGET /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/notifywith{}-> 400