# Refactor Plan — Priority 1 (`actions/index.js` split) Last updated: 2026-03-13 ## Handover note (2026-03-13) - Import-migration wave from `actions` barrel to focused modules has been checked in and completed via PR. - Next chunk will be delivered from a **new branch** and should start at legacy decomposition. ### Next branch kickoff scope (Phase 5) Primary objective: split `actions/services/legacyActionsService.js` into smaller direct implementations while preserving function signatures. Recommended first slice: 1. Extract reference/search internals from `legacyActionsService.js` into dedicated modules. 2. Keep `actions/services/*` exports stable and route through new direct implementations. 3. Add focused parity checks per extracted function group (inputs, headers, hash behavior, return shapes). Then continue with: 4. Portal/document extraction in small batches. 5. Remove dead wrappers from `legacyActionsService.js` once call paths are fully migrated. ### Phase 5 slice roadmap (completed) Status key: `[x] done`, `[ ] pending` 1. `[x]` Search + reference direct extraction - `searchDirectService.js`, `referenceDataDirectService.js` - `searchService.js` / `referenceDataService.js` re-pointed 2. `[x]` Document direct extraction - create `documentDirectService.js` - re-point `documentService.js` - parity checks: blob paths/hash behavior/return shapes 3. `[x]` Portal direct extraction - create `portalDirectService.js` - re-point `portalService.js` - parity checks: watched-case and completion-message flows 4. `[x]` Account + case direct extraction - create `accountDirectService.js`, `caseDirectService.js` - re-point grouped services 5. `[x]` Notify + integration + admin direct extraction - create `notifyDirectService.js`, `integrationDirectService.js`, `adminDirectService.js` 6. `[x]` Legacy slim-down pass - remove dead wrappers from `legacyActionsService.js` - keep only temporary compatibility exports still required 7. `[x]` Final cleanup + validation pass - grep checks for remaining `./legacyActionsService` imports - lint/manual smoke checks ### Phase 5 completion snapshot (2026-03-13) - All grouped service modules now route through focused direct modules under `actions/services/*DirectService.js`. - `actions/services/legacyActionsService.js` has been removed. - Verification completed: - `actions/services` scan returns zero `./legacyActionsService` imports. - `npm run lint` completes with warnings only. - `npm run build` completes successfully. ### Next phase kickoff recommendation Focus on post-split hardening and cleanup: 1. Add parity-focused tests for extracted direct services and `actions/services/index.js` export stability. 2. Consolidate repeated axios/error-handling patterns into shared clients/utilities where safe. 3. Reduce verbose debug logging in direct services (especially account/case/document paths) with redaction discipline. 4. Run targeted manual smoke matrix for search/case/myportal/document/notify with EN/CY parity checks. ### Phase 6 completion snapshot (2026-03-13) Status key: `[x] done`, `[ ] pending` 1. `[x]` Add parity-focused tests for extracted services and barrel stability - `tests/phase6/service-parity.test.cjs` - validates grouped/direct service export parity - validates `actions/services/index.js` export stability 2. `[x]` Reduce repeated axios/error-handling patterns safely - added shared helper: `actions/services/httpServiceUtils.js` - adopted in selected direct modules without signature/return-shape changes 3. `[x]` Logging cleanup in sensitive direct-service flows - removed noisy debug logs from search/document/portal/case/admin direct services 4. `[x]` Add focused behavioural contract tests in current phase - `tests/phase6/service-behaviour.test.cjs` - success/error contract checks with mocked axios/logger (8/8 passing) 5. `[x]` Run targeted validation/smoke checks - parity test: pass - behavioural test: pass - manual smoke matrix executed (search/case/myportal/document/notify, EN/CY + negative paths) Notes: - Known pre-existing caveat during smoke checks: - `/searchresults` and `/cy/searchresults` return 500 in local dev due SSR serialization issue (`initialState.search.searchString` undefined). - treated as existing issue, not introduced by this refactor phase. ### Future requirements / next-phase backlog (post-Phase-6) 1. Investigate and fix `/searchresults` SSR serialization issue (EN/CY parity). 2. Expand behavioural service tests to remaining domains: - document - portal - account - notify - integration 3. Add focused negative-path tests for token/hash/relay-sensitive handlers. 4. Continue small-batch hardening with reversible commits and parity checks per batch. 5. Prepare PR evidence bundle for each increment: - lint + test commands - behavioural/parity test outputs - manual EN/CY + negative-path smoke matrix ### Phase 7 completion snapshot (2026-03-13) Status key: `[x] done`, `[ ] pending` 1. `[x]` Create new branch from `origin/SIPS-Development` with required work item prefix - branch: `TASK21988a-phase7-postphase6-hardening` 2. `[x]` Fix pre-existing `/searchresults` SSR serialization issue with EN/CY parity - updated `pages/searchresults.js`: - `setSearch(query.q)` -> `setSearch(query?.q || "")` 3. `[x]` Expand behavioural tests to remaining service domains - added `tests/phase7/service-behaviour.test.cjs` - coverage includes: document, portal, account, notify, integration 4. `[x]` Add feasible negative-path tests for token/hash/relay-sensitive flows - validated hashed path composition (e.g., `hashAPIPath` usage) - validated existing function error contracts (undefined/error string/rethrow) 5. `[x]` Execute validation bundle - `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 (no new errors) 6. `[x]` Execute targeted manual smoke matrix (EN/CY + negative paths) - local server on `localhost:3001` (3000 occupied) - `/searchresults`, `/cy/searchresults` -> 200 - `/case`, `/cy/case` -> 200 - `/myportal`, `/cy/myportal` -> 307 -> `/auth/signin` - `/api/file/getbloblistproxy?container=test&casefolderID=test` -> 400 - `POST /api/email/notify` with `{}` -> 400 ### Phase 7 rollback notes - Revert `pages/searchresults.js` fallback change if search behaviour regresses unexpectedly. - Remove `tests/phase7/service-behaviour.test.cjs` if test scope needs to be rolled back. - Reset branch to pre-Phase-7 commit if full rollback required. ### Phase 8 completion snapshot (2026-03-13) Status key: `[x] done`, `[ ] pending` 1. `[x]` Create new branch from `origin/SIPS-Development` with required work item prefix - branch: `TASK22017-phase8-hardening-slice` 2. `[x]` Re-enable/enforce hash validation in 4 sensitive target handlers - `pages/api/file/deleteblobcase.js` - `pages/api/file/deleteblobrep.js` - `pages/api/file/createappealcompletemessage_api.js` - `pages/api/endpoint/getportallogin_api.js` 3. `[x]` Standardize negative-path behavior for invalid/missing hash and required keys - added early 400 guards for missing required query params where applicable - preserved response-shape contracts/signatures 4. `[x]` Improve logging discipline in sensitive flow - removed noisy direct console output in `createappealcompletemessage_api` - routed updated error path logging via `consoleLogger` 5. `[x]` Keep caller behavior compatible after hash re-enforcement - `actions/services/documentDirectService.js` now appends hash for: - `deleteblobcase` - `deleteblobrep` - `actions/services/portalDirectService.js` now appends hash for: - `createappealcompletemessage_api` (existing hash-path contract retained) 6. `[x]` Add focused Phase 8 tests - added `tests/phase8/service-behaviour.test.cjs` - includes negative-path coverage for all 4 target handlers - includes one valid-hash happy-path contract check (`getportallogin_api`) via mocks 7. `[x]` Execute validation bundle - `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) 8. `[x]` Execute manual HTTP negative-path matrix + feasible happy-path spot-check - invalid/missing hash across 4 target handlers -> 400 - missing required params where tested -> 400 - valid-hash `getportallogin_api` spot-check returned 400 in local env due upstream relay/CRM dependency ### Phase 8 rollback notes - Revert these files to rollback the full hardening slice: - `pages/api/file/deleteblobcase.js` - `pages/api/file/deleteblobrep.js` - `pages/api/file/createappealcompletemessage_api.js` - `pages/api/endpoint/getportallogin_api.js` - `actions/services/documentDirectService.js` - `actions/services/portalDirectService.js` - `tests/phase8/service-behaviour.test.cjs` - Re-run phase6/phase7 baseline tests and lint after rollback to confirm parity. ### Phase 9 completion snapshot (2026-03-13) Status key: `[x] done`, `[ ] pending` 1. `[x]` Create new branch from `origin/SIPS-Development` with required work item prefix - branch: `TASK22019-phase-9-hardening` 2. `[x]` Re-enable/enforce hash validation in 4 additional sensitive file handlers - `pages/api/file/createrepcompletemessage_api.js` - `pages/api/file/upload.js` - `pages/api/file/uploadsinglefile.js` - `pages/api/file/setupcontainer.js` 3. `[x]` Standardize negative-path behavior for invalid/missing hash and key params - added early 400 handling for missing required query/body values where applicable 4. `[x]` Improve logging discipline in sensitive paths - removed noisy direct console logging in touched handlers 5. `[x]` Keep caller behavior compatible after hash re-enforcement - `actions/services/portalDirectService.js` - `sendRepCompleteMessage` now appends hash - `actions/services/documentDirectService.js` - upload-related calls now append hash 6. `[x]` Add focused Phase 9 tests - added `tests/phase9/service-behaviour.test.cjs` - negative-path tests for all 4 selected handlers 7. `[x]` Execute validation bundle - `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 (no new lint errors) 8. `[x]` Execute manual HTTP negative-path matrix - missing/invalid hash checks across selected handlers -> 400 - missing key params where tested -> 400 9. `[x]` Valid-hash HTTP happy-path spot-check - `POST /api/file/uploadsinglefile?hash=` -> 200 (hash generated from `.env.local` key) ### Phase 9 rollback notes - Revert these files to rollback the full hardening slice: - `pages/api/file/createrepcompletemessage_api.js` - `pages/api/file/upload.js` - `pages/api/file/uploadsinglefile.js` - `pages/api/file/setupcontainer.js` - `actions/services/portalDirectService.js` - `actions/services/documentDirectService.js` - `tests/phase9/service-behaviour.test.cjs` - Re-run phase6/phase7/phase8/phase9 baseline tests and lint after rollback to confirm parity. ### Phase 10 completion snapshot (2026-03-13) Status key: `[x] done`, `[ ] pending` 1. `[x]` Continue connected hardening slices on same branch - branch: `TASK22019-phase-9-hardening` 2. `[x]` Re-enable/standardize hash + param guard handling in 4 additional file retrieval handlers - `pages/api/file/getawaitingsubmissionfromblob.js` - `pages/api/file/getprogressobjblob.js` - `pages/api/file/getbloblist.js` - `pages/api/file/getrepsblob.js` 3. `[x]` Standardize negative-path behavior - added explicit early 400 for missing required query/hash values - standardized early 400 for hash mismatch 4. `[x]` Improve logging discipline in touched handlers - removed old commented debug traces 5. `[x]` Add focused Phase 10 tests - added `tests/phase10/service-behaviour.test.cjs` - includes negative-path tests for all 4 handlers 6. `[x]` Execute validation bundle - `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 (no new lint errors) 7. `[x]` Execute manual HTTP negative-path matrix + valid-hash spot-check - missing hash across selected handlers -> 400 - valid hash `getbloblist` spot-check -> 500 (downstream/local dependency) ### Phase 10 rollback notes - Revert these files to rollback the full hardening slice: - `pages/api/file/getawaitingsubmissionfromblob.js` - `pages/api/file/getprogressobjblob.js` - `pages/api/file/getbloblist.js` - `pages/api/file/getrepsblob.js` - `tests/phase10/service-behaviour.test.cjs` - Re-run phase6/phase7/phase8/phase9/phase10 baseline tests and lint after rollback to confirm parity. ### Phase 11 completion snapshot (2026-03-13) Status key: `[x] done`, `[ ] pending` 1. `[x]` Continue connected hardening slices on same branch - branch: `TASK22019-phase-9-hardening` 2. `[x]` Re-enable/standardize hash + param guard handling in additional sensitive handlers - `pages/api/file/getbloblist.js` - `pages/api/file/deleteblob.js` - `pages/api/file/deleteawaitingsubmissionfromblob.js` 3. `[x]` Standardize negative-path behavior - added explicit early 400 for missing required query/hash values - standardized early 400 for hash mismatch 4. `[x]` Improve logging discipline in touched handlers - removed old commented debug traces 5. `[x]` Add focused Phase 11 tests - added `tests/phase11/service-behaviour.test.cjs` - includes negative-path tests for selected handlers 6. `[x]` Execute validation bundle - `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 (no new lint errors) 7. `[x]` Execute manual HTTP negative-path matrix + valid-hash spot-check - missing/invalid hash across selected handlers -> 400 - valid hash `getbloblist` spot-check -> 500 (downstream/local dependency) ### Phase 11 rollback notes - Revert these files to rollback the full hardening slice: - `pages/api/file/getbloblist.js` - `pages/api/file/deleteblob.js` - `pages/api/file/deleteawaitingsubmissionfromblob.js` - `tests/phase11/service-behaviour.test.cjs` - Re-run phase6/phase7/phase8/phase9/phase10/phase11 baseline tests and lint after rollback to confirm parity. ### Phase 12 completion snapshot (2026-03-13) Status key: `[x] done`, `[ ] pending` 1. `[x]` Continue connected hardening slices on same branch - branch: `TASK22019-phase-9-hardening` 2. `[x]` Re-enable/standardize hash + param guard handling in additional sensitive handlers - `pages/api/file/downloadblob.js` - `pages/api/file/getbloblistproxy.js` - `pages/api/file/getrepsblobproxy.js` - `pages/api/file/getawaitingsubmissionfromblobproxy.js` 3. `[x]` Standardize negative-path behavior - added explicit early 400 for missing required query/hash values - standardized early 400 for hash mismatch in `downloadblob` 4. `[x]` Add focused Phase 12 tests - added `tests/phase12/service-behaviour.test.cjs` - includes negative-path tests for selected handlers 5. `[x]` Execute validation bundle - `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 (no new lint errors) 6. `[x]` Execute manual HTTP negative-path matrix + valid-hash spot-check - missing/invalid inputs across selected handlers -> 400 - valid hash `downloadblob` spot-check -> 500 (downstream/local dependency) ### Phase 12 rollback notes - Revert these files to rollback the full hardening slice: - `pages/api/file/downloadblob.js` - `pages/api/file/getbloblistproxy.js` - `pages/api/file/getrepsblobproxy.js` - `pages/api/file/getawaitingsubmissionfromblobproxy.js` - `tests/phase12/service-behaviour.test.cjs` - Re-run phase6/phase7/phase8/phase9/phase10/phase11/phase12 baseline tests and lint after rollback to confirm parity. ### Phase 13 completion snapshot (2026-03-13) Status key: `[x] done`, `[ ] pending` 1. `[x]` Continue connected hardening slices on same branch - branch: `TASK22019-phase-9-hardening` 2. `[x]` Re-enable/standardize hash + param guard handling in additional sensitive handlers - `pages/api/file/deleteblobcase.js` - `pages/api/file/deleteblobrep.js` - `pages/api/file/createcaseinvolvement_api.js` - `pages/api/file/createrepinvolvement_api.js` 3. `[x]` Standardize negative-path behavior - added explicit early 400 for missing required query/hash/body values - standardized early 400 for hash mismatch in delete handlers 4. `[x]` Improve logging discipline in touched handlers - removed noisy body/query logging in involvement handlers 5. `[x]` Add focused Phase 13 tests - added `tests/phase13/service-behaviour.test.cjs` - includes negative-path tests and valid-input mocked happy paths 6. `[x]` Execute validation bundle - `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 (no new lint errors) 7. `[x]` Execute manual HTTP negative-path matrix + valid-hash spot-check - missing/invalid inputs across selected handlers -> 400 - valid hash `deleteblobcase` spot-check -> 500 (downstream/local dependency) ### Phase 13 rollback notes - Revert these files to rollback the full hardening slice: - `pages/api/file/deleteblobcase.js` - `pages/api/file/deleteblobrep.js` - `pages/api/file/createcaseinvolvement_api.js` - `pages/api/file/createrepinvolvement_api.js` - `tests/phase13/service-behaviour.test.cjs` - Re-run phase6/phase7/phase8/phase9/phase10/phase11/phase12/phase13 baseline tests and lint after rollback to confirm parity. ### Phase 14 completion snapshot (2026-03-13) Status key: `[x] done`, `[ ] pending` 1. `[x]` Diagnose authenticated browser journey runtime error - traced to client-side `hashAPIPath` usage reading server-only `HASHKEY` 2. `[x]` Implement minimal reversible signing bridge - added `pages/api/endpoint/gethash_api.js` - session-gated with allow-listed API path prefixes 3. `[x]` Keep client/service contracts stable - updated `documentDirectService` and `portalDirectService` to request hash from signer endpoint - kept server-side fallback hashing only when env key exists 4. `[x]` Add focused phase-14 tests - added `tests/phase14/service-behaviour.test.cjs` - covers 400/401 negative paths and authenticated happy path 5. `[x]` Execute validation bundle - phase6–phase14 test set all pass - lint warnings only (pre-existing) ### Phase 14 rollback notes - Revert these files to rollback the fix slice: - `pages/api/endpoint/gethash_api.js` - `actions/services/documentDirectService.js` - `actions/services/portalDirectService.js` - `tests/phase14/service-behaviour.test.cjs` - Re-run phase6–phase14 tests + lint after rollback. ### Phase 14 closeout follow-up snapshot (2026-03-13) Status key: `[x] done`, `[ ] pending` 1. `[x]` Expand signer usage to remaining browser-sensitive hashed call in account domain - `actions/services/accountDirectService.js` - `getPortalLogin` now requests hash from authenticated signer endpoint 2. `[x]` Extend signer allow-list minimally for required route - `pages/api/endpoint/gethash_api.js` - added `/api/endpoint/getportallogin_api` only 3. `[x]` Preserve and verify behavioural contract coverage - `tests/phase7/service-behaviour.test.cjs` updated for signer flow - `tests/phase14/service-behaviour.test.cjs` extended with allow-list path test 4. `[x]` Apply runtime-discovered contract alignment fixes (minimal/reversible) - `pages/api/file/getrepsblob.js` - removed unnecessary `casefolderID` requirement to match endpoint contract - `components/elements/index.js` - restored missing `updateLinks` import for Quill path 5. `[x]` Re-run required validation - phase6 parity + behaviour -> pass - phase7/8/9/10/11/12/13/14 behaviour -> pass - lint -> warnings only (pre-existing) 6. `[x]` Push branch for review continuity - `TASK22019-phase-9-hardening` pushed to origin ### Phase 14 closeout follow-up rollback notes - Revert `6094874` to remove portal-login signer migration and tests. - Revert `b8fa514` to remove getrepsblob contract-alignment + Quill import fix. - Re-run phase6–phase14 tests and lint after rollback. ### Phase 15 completion snapshot (2026-03-13) Status key: `[x] done`, `[ ] pending` 1. `[x]` Create new branch from `origin/SIPS-Development` with required work item prefix - branch: `TASK22028-phase15-hardening-slice` 2. `[x]` Apply minimal consistency-only hardening in 4 additional sensitive handlers - `pages/api/file/upload.js` - `pages/api/file/uploadsinglefile.js` - `pages/api/file/createappealcompletemessage_api.js` - `pages/api/file/setupcontainer.js` 3. `[x]` Standardize negative-path behavior - explicit early 400 for missing/invalid hash in selected handlers - explicit missing required-input checks where route contract requires them - preserved response-shape contracts and function signatures 4. `[x]` Add focused Phase 15 tests - added `tests/phase15/service-behaviour.test.cjs` - includes negative-path tests for missing/invalid hash + required-input checks - includes one valid-hash mocked happy-path response-shape check 5. `[x]` Execute required validation bundle - phase6 parity + phase6–phase14 behaviour tests -> pass - phase15 behaviour tests -> pass - lint -> warnings only (pre-existing) 6. `[x]` Execute targeted manual checks - missing/invalid hash across selected handlers -> 400 - missing required params where applicable -> 400 - valid-hash `setupcontainer` spot-check -> 200 ### Phase 15 rollback notes - Revert these files to rollback the full hardening slice: - `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` - Re-run phase6–phase15 baseline tests and lint after rollback to confirm parity. ### Phase 16 completion snapshot (2026-03-13) Status key: `[x] done`, `[ ] pending` 1. `[x]` Continue on current branch with separate commit for additional small slice - branch: `TASK22028-phase15-hardening-slice` 2. `[x]` Apply minimal consistency hardening in 3 file proxy handlers - `pages/api/file/getbloblistproxy.js` - `pages/api/file/getrepsblobproxy.js` - `pages/api/file/getawaitingsubmissionfromblobproxy.js` 3. `[x]` Standardize required-input guard pattern - added local `hasValue` checks for required params - removed unused/dead imports/constants in touched files 4. `[x]` Add focused Phase 16 tests - added `tests/phase16/service-behaviour.test.cjs` - missing-input negative-path checks + one valid-input contract check 5. `[x]` Execute validation bundle - phase6 parity + phase6–phase16 behaviour tests pass - lint warnings only (pre-existing) 6. `[x]` Execute manual checks - missing required-input proxy calls -> 400 ### Phase 16 rollback notes - 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` - Re-run phase6–phase16 baseline tests and lint. ### Follow-up completion snapshot (2026-03-13) 1. `[x]` Address browser signer failure for delete-awaiting-submission path - added signer allow-list entry: `/api/file/deleteblobcase` 2. `[x]` Add focused behavioural test coverage - extended `tests/phase14/service-behaviour.test.cjs` 3. `[x]` Validate - phase14 behaviour tests pass (6/6) - phase7 behaviour tests pass (10/10) - lint warnings only (pre-existing) ### Follow-up rollback notes - Revert commit `49dd990` to undo allow-list/test follow-up. ### Follow-up completion snapshot (2026-03-13 — additional delete flows) 1. `[x]` Expand signer allow-list for required browser delete paths 2. `[x]` Move remaining delete service calls to signer-based hash retrieval 3. `[x]` Extend focused service/signer tests 4. `[x]` Validate - phase7 behaviour tests pass (12/12) - phase14 behaviour tests pass (9/9) - lint warnings only (pre-existing) ### Follow-up rollback notes (additional delete flows) - Revert the follow-up commit for this slice to restore prior hashing behavior. ### Follow-up completion snapshot (2026-03-13 — myportal + i18n alignment) 1. `[x]` Align myportal delete-representation calls to use `caseRef` 2. `[x]` Add missing i18n namespace mapping for `/newappeal/[appealtypes]` 3. `[x]` Validate - phase7 behaviour tests pass (12/12) - lint warnings only (pre-existing) ### Follow-up rollback notes (myportal + i18n alignment) - Revert commit `d32d7d0` to restore prior myportal/i18n state. ### Phase 17 closeout snapshot (2026-03-13) Status key: `[x] done`, `[ ] pending` 1. `[x]` Create new branch from `origin/SIPS-Development` with required work item prefix - branch: `TASK22057-phase17-hardening-closeout` 2. `[x]` Complete remaining consistency-only hardening targets in `pages/api/file/**` - `pages/api/file/generatepdf.js` - `pages/api/file/generateappealpdf.js` - `pages/api/file/createappealcompletemessageproxy_api.js` 3. `[x]` Standardize negative-path behavior and logging discipline - explicit early 400 guards for missing/invalid hash where applicable - explicit early 400 guards for missing required params where applicable - noisy direct logs removed from touched handlers - response-shape/signature contracts preserved 4. `[x]` Add focused Phase 17 tests - added `tests/phase17/service-behaviour.test.cjs` - includes missing/invalid hash negative-path checks - includes missing required-param checks - includes valid-input happy-path check for proxy contract 5. `[x]` Execute required validation bundle - phase6 parity + phase6–phase17 behaviour tests -> pass - lint -> warnings only (pre-existing) 6. `[x]` Consistency scan for remaining `pages/api/**` - no additional broad hash/400 consistency gaps identified in `pages/api/endpoint/**` during this pass ### Phase 17 rollback notes - Revert these files to rollback the full closeout slice: - `pages/api/file/generatepdf.js` - `pages/api/file/generateappealpdf.js` - `pages/api/file/createappealcompletemessageproxy_api.js` - `tests/phase17/service-behaviour.test.cjs` - Re-run phase6–phase17 baseline tests and lint after rollback to confirm parity. ### Phase 18 additional consolidation slices snapshot (2026-03-14) Status key: `[x] done`, `[ ] pending` 1. `[x]` Confirm requested scope expansion to implement all 3 additional slices 2. `[x]` Apply endpoint logging/input hygiene slice - `pages/api/endpoint/deletewatchedcases_api.js` - `pages/api/endpoint/getaccounts_api.js` - `pages/api/endpoint/getbasicsearchpaged_api.js` - `pages/api/endpoint/getappealpdfdocuments_api.js` 3. `[x]` Apply file hash-guard flow consistency slice - `pages/api/file/deleteblob.js` - `pages/api/file/deleteawaitingsubmissionfromblob.js` - `pages/api/file/getprogressobjblob.js` - `pages/api/file/getbloblist.js` 4. `[x]` Apply create/update input-guard + logging hygiene slice - `pages/api/file/createcase_api.js` - `pages/api/file/updatecase_api.js` - `pages/api/file/editRepJson.js` 5. `[x]` Add focused phase-18 behavioural tests - added `tests/phase18/service-behaviour.test.cjs` - negative-path coverage for required inputs/hash - contract-preserving happy-path checks on selected handlers 6. `[x]` Execute validation bundle - phase6 parity + phase6–phase18 behavioural tests all pass - lint warnings only (pre-existing `react-hooks/exhaustive-deps` set) ### Phase 18 rollback notes - Revert files in this slice: - `pages/api/endpoint/deletewatchedcases_api.js` - `pages/api/endpoint/getaccounts_api.js` - `pages/api/endpoint/getbasicsearchpaged_api.js` - `pages/api/endpoint/getappealpdfdocuments_api.js` - `pages/api/file/deleteblob.js` - `pages/api/file/deleteawaitingsubmissionfromblob.js` - `pages/api/file/getprogressobjblob.js` - `pages/api/file/getbloblist.js` - `pages/api/file/createcase_api.js` - `pages/api/file/updatecase_api.js` - `pages/api/file/editRepJson.js` - `tests/phase18/service-behaviour.test.cjs` - Re-run phase6–phase18 baseline tests and lint after rollback to confirm parity. ### Phase 19 endpoint consistency slice snapshot (2026-03-14) Status key: `[x] done`, `[ ] pending` 1. `[x]` Apply small consistency-only endpoint hardening in selected handlers - `pages/api/endpoint/createwatchedcases_api.js` - `pages/api/endpoint/getappealtypes_api.js` - `pages/api/endpoint/getdnslist_api.js` 2. `[x]` Standardize negative-path required input handling - early 400 on missing/malformed required `@odata.bind` values in `createwatchedcases_api` 3. `[x]` Remove noisy sensitive-path logging - removed direct query logging in appeal-types and dns-list handlers 4. `[x]` Add focused tests - `tests/phase19/service-behaviour.test.cjs` (5/5) 5. `[x]` Execute validation bundle - phase6 parity + phase6–phase19 behavioural suites pass - lint warnings only (pre-existing) ### Phase 19 rollback notes - Revert files in this slice: - `pages/api/endpoint/createwatchedcases_api.js` - `pages/api/endpoint/getappealtypes_api.js` - `pages/api/endpoint/getdnslist_api.js` - `tests/phase19/service-behaviour.test.cjs` - Re-run phase6–phase19 baseline tests and lint after rollback. ### Phase 20 endpoint consistency slice snapshot (2026-03-14) Status key: `[x] done`, `[ ] pending` 1. `[x]` Apply small consistency-only endpoint hardening in selected handlers - `pages/api/endpoint/getbasicdnssearch_api.js` - `pages/api/endpoint/getbasicdnsurlsearch_api.js` - `pages/api/endpoint/getbasicsearchdetailspaged_api.js` 2. `[x]` Standardize negative-path required input handling - early 400 for missing/empty `searchString` in `getbasicdnsurlsearch_api` - early 400 for missing required params in `getbasicsearchdetailspaged_api` 3. `[x]` Remove noisy sensitive-path logging - removed direct query logging in `getbasicdnssearch_api` 4. `[x]` Add focused tests - `tests/phase20/service-behaviour.test.cjs` (5/5) 5. `[x]` Execute validation bundle - phase6 parity + phase6–phase20 behavioural suites pass - lint warnings only (pre-existing) ### Phase 20 rollback notes - Revert files in this slice: - `pages/api/endpoint/getbasicdnssearch_api.js` - `pages/api/endpoint/getbasicdnsurlsearch_api.js` - `pages/api/endpoint/getbasicsearchdetailspaged_api.js` - `tests/phase20/service-behaviour.test.cjs` - Re-run phase6–phase20 baseline tests and lint after rollback. ## Safe execution mode for migration chunks (required) To reduce terminal hangs during bulk migration work, run refactor chunks in **safe stepwise mode** instead of long chained commands. Required command pattern: 1. Read/inspect target files. 2. Apply edits only. 3. Verify with targeted grep for remaining broad imports. 4. Check `git status`. 5. Stage files. 6. Commit. 7. Re-run verification and then continue to the next chunk. Rules: - Do **not** combine edit + verify + add + commit + log in one long chained command. - Keep each terminal call short and single-purpose. - If a command is interrupted, re-check `git status` and resume from the next incomplete step. - Preserve smallest viable diff and behavior parity. ## Implementation status snapshot (2026-03-12) - Phase 1 completed: - Extracted core helpers into `actions/core/{env,logger,hash,token,headers}.js`. - Moved wrapper functions into `actions/services/legacyActionsService.js`. - Reduced `actions/index.js` to compatibility barrel re-exports. - Added `actions/clients/README.md` scaffold for upcoming client extraction. - Validation status: - `npm run lint` currently fails at framework/tooling option level (legacy ESLint options), not due to this refactor logic. - Manual test matrix is required next (search/case/myportal/auth/notify/file). ## Implementation status snapshot (Phase 2 update — 2026-03-12) - Phase 2 completed: - Added grouped service modules under `actions/services/`: - `searchService.js` - `caseService.js` - `accountService.js` - `portalService.js` - `documentService.js` - `referenceDataService.js` - `notifyService.js` - `adminService.js` - `integrationService.js` - Added `actions/services/index.js` barrel. - Updated `actions/index.js` to export from `./services` and `./core/*`. - Verified export parity: all `legacyActionsService` exports are represented by grouped service modules. - Current compatibility model: - Consumers can continue importing from `../actions` with unchanged function names/signatures. - `legacyActionsService` remains an internal compatibility implementation module until Phase 3 consumer migration. ## Implementation status snapshot (Phase 3 update — 2026-03-12) - Phase 3 started with targeted consumer migration to focused imports. - Updated high-churn consumers: - `components/case/summary.js` - `createWatchedCases`, `deleteWatchedCases`, `getWatchedCasesProxy`, `setCaseInvolvment` -> `actions/services/portalService` - `getLinkedCases` -> `actions/services/searchService` - `getPortalModuleDetailsProxy` -> `actions/services/caseService` - `pages/api/email/notify.js` - `consoleLogger` -> `actions/core/logger` - `getPreferredLanguage` -> `actions/services/accountService` - Updated selected endpoint handlers to core imports: - `pages/api/endpoint/getwatchedcases_api.js` - `pages/api/endpoint/getadvancedsearchpaged_api.js` - `pages/api/endpoint/getpreferredlanguage_api.js` - `pages/api/endpoint/createcrmtask_api.js` - Compatibility remains preserved via `actions/index.js` barrel while migration proceeds incrementally. ## Implementation status snapshot (Phase 4 update — 2026-03-12) - Phase 4 started with targeted hardening helpers and sensitive-path adoption. - Added `actions/core/guards.js` with: - `isNonEmptyString` - `sanitizeString` - `escapeODataString` - Expanded `actions/core/logger.js` with redaction support: - `redactSensitive` - masking for likely email/token/secret patterns in logged content - Updated `actions/index.js` compatibility barrel to export `./core/guards`. - Applied hardening in selected sensitive/high-churn handlers: - `pages/api/email/notify.js` - email input sanitization + required-field guard - redacted logging for outbound payload diagnostics - `pages/api/endpoint/getpreferredlanguage_api.js` - sanitized/validated `emailAddress` - OData string escaping for query construction - redacted query logging - `pages/api/endpoint/createcrmtask_api.js` - sanitized/validated request inputs for subject/email/body - centralized structured error logging via `consoleLogger` ## Implementation status snapshot (Priority 1 execution pass — 2026-03-12) - Completed another targeted consumer migration pass from broad `actions` barrel imports to focused service/core imports in these files: - `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` - Kept compatibility behavior via existing `actions/index.js` barrel. - Validation note: `npm run lint` remains blocked by repository ESLint/Next option incompatibility (pre-existing tooling configuration). ## Goal Reduce coupling and regression risk by splitting `actions/index.js` into focused modules while preserving existing behavior and call signatures during migration. ## Why this is first `actions/index.js` is currently a high-risk hotspot: API wrappers, relay/hash helpers, token acquisition, logging, file helpers, and notification helpers are mixed in one module. This increases blast radius for every change. ## Scope (planned) - In scope: - Module extraction and internal architecture cleanup. - Backward-compatible export strategy. - Migration plan for consumers under `components/**`, `pages/**`, and `pages/api/**`. - Out of scope (for this refactor phase): - Functional changes to business logic. - Contract changes to API handlers. - Dependency swaps. ## Proposed target structure ```text actions/ index.js # compatibility barrel (temporary) core/ env.js # BASE_URL/API_ROOT/relay roots logger.js # consoleLogger/conLog with redaction helpers hash.js # hashAPIPath/hashString/dehashString token.js # getToken + token request config headers.js # azureHeaders* helpers clients/ relayClient.js # signed relay calls + shared axios behavior endpointClient.js # endpoint route wrappers fileClient.js # file route wrappers notifyClient.js # email/notify wrappers services/ caseService.js searchService.js portalService.js accountService.js documentService.js ``` Notes: - Keep `actions/index.js` as a façade initially to avoid breaking imports. - Move internals first, then update call sites incrementally. ## Migration strategy (phased) ### Phase 1 — Safe extraction with no consumer changes 1. Create new modules under `actions/core/**` and `actions/clients/**`. 2. Move utility functions (`hash`, `headers`, `token`, `logger`, env helpers). 3. Re-export all existing functions from `actions/index.js` unchanged. 4. Verify parity with lint + smoke checks. ### Phase 2 — Service grouping 1. Group route wrapper functions into service modules by domain (case/search/portal/account/document). 2. Keep identical function names/signatures. 3. Add thin unit tests for pure helpers first (`hash`, `env`, route builder helpers). ### Phase 3 — Consumer migration 1. Replace broad imports from `actions/index.js` with targeted imports from new modules. 2. Migrate high-churn areas first: - `components/breadcrumbs.js` - `components/case/summary.js` - `pages/api/email/notify.js` - selected `pages/api/endpoint/**` handlers 3. Keep index barrel until migration completion. ### Phase 4 — Harden + slim 1. Introduce typed/validated request helper boundaries (JS doc + runtime guard checks). 2. Remove dead exports and duplicate wrappers. 3. Finalize redacted logging policy in sensitive flows. ## Backward compatibility rules - Do not change public function names/signatures during Phases 1–2. - Keep return shapes identical unless explicitly planned and validated. - Preserve existing hash and relay behavior contract. - Preserve EN/CY behavior where helper functions influence locale-sensitive flows. ## Validation plan - `npm run lint` - Manual smoke paths: - search -> results -> case summary -> back nav - myportal viewall -> case summary -> breadcrumb return path - auth email sign-in flow - notify new case reference language selection path - file/document fetch paths touched by moved wrappers - Negative-path checks: - invalid hash or malformed query for sensitive handlers - token acquisition failures and relay timeout handling ## Regression tests and coverage plan (to add during implementation) ### Test tooling recommendation Current repo has no active automated test runner configured in `package.json`. For this refactor, introduce a minimal unit test setup (recommended: Jest) focused on pure logic first. Suggested scripts: - `test`: run all unit tests - `test:watch`: local watch mode - `test:coverage`: coverage output for CI and PR evidence ### Minimum tests for Priority 1 1. `actions/core/hash.js` - deterministic hash for known input - query string handling (`?hash=` vs `&hash=`) - malformed/edge inputs 2. `actions/core/headers.js` - expected OData/auth headers produced for each helper 3. `actions/core/token.js` - token request config generation - success and error mapping behavior (mock axios) 4. `actions/core/env.js` - server vs browser base URL resolution 5. compatibility barrel (`actions/index.js`) - exports parity test to ensure existing function names remain available during migration ### Integration-style safeguards (mocked external calls) - Relay client request assembly test: - signed URL includes hash - token is attached - timeout/error behavior is consistent - Notify client wrapper test: - language/template routing remains unchanged for PEDW-NEW-CASEREF path ### Coverage targets for this refactor - `actions/core/**`: >= 90% lines/functions - `actions/clients/**`: >= 80% lines/functions - Global coverage gate for this phase: >= 70% (new tests only; avoid blocking unrelated legacy code) ### Regression gate in PR Required evidence for each phase: 1. `npm run lint` 2. `npm run test` 3. `npm run test:coverage` (attach summary) 4. Manual smoke matrix from this plan (search/case/myportal/auth/notify/file) ## Risks and mitigations - Risk: import breakage due to broad existing usage. - Mitigation: keep compatibility barrel and migrate in small batches. - Risk: hidden behavior differences from refactor-only moves. - Mitigation: freeze signatures + add helper tests + run route smoke matrix each phase. - Risk: sensitive logging leakage while touching shared helpers. - Mitigation: centralize logger early and enforce redaction helper. ## Definition of done (for this priority) 1. `actions/index.js` reduced to compatibility exports only (minimal logic). 2. Core helper modules and service modules exist and are used by migrated consumers. 3. Lint and manual validation matrix pass. 4. Memory docs updated (`activeContext`, `progress`, `change-log`).