98 KiB
Change Log (AI/Human Curated)
Entry Template
date: YYYY-MM-DD
author: <agent|name>
scope: <files/routes/features>
type: change
rationale: <why change was made>
impact: <user/system/security/i18n/a11y>
status: completed|rolled-back|partial
Summary:
Validation:
Follow-ups:
CL-001: TASK22211 endpoint search-document contract consistency slice
date: 2026-03-23
author: Cline
scope: pages/api/endpoint/{getsearchdocumenthistory_api,getsearchdocumenthistorypaged_api,getsearchdocumentdetails_api,getsearchdocumentdetailspaged_api,getsearchdocumentTypes_api}.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Continue the endpoint contract-consistency stream by normalizing a coherent search-document handler cluster that still used raw error passthrough and noisy legacy logging patterns.
impact: Improved negative-path consistency and safer error contract handling in search-document endpoints while preserving success payload behavior.
status: completed
Summary:
- Branch created from
SIPS-Development:TASK22211-endpoint-search-document-contract-consistency. - Standardized five search-document handlers to
respondError/respondSuccessusage. - Added explicit required-input guards:
DOCUMENT_ID_REQUIREDfor history/historypagedINCIDENT_ID_REQUIREDfor details/detailspaged/typesORDER_BY_REQUIRED,FIELD_SORT_REQUIRED,SHOW_NUMBER_OF_RECORDS_REQUIREDfor details-paged query requirements
- Removed noisy direct logging in paged/details code paths.
- Preserved success contract patterns (pass-through or transformed payloads where already established).
- Expanded phase21 endpoint tests with missing-input, catch-path, and success parity assertions for this cluster.
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 11/11
- email-handler: 12/12
- endpoint-handler: 53/53
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-depswarnings; no new lint errors)
Follow-ups:
- Continue the next endpoint cluster using the same pattern (bounded slice + phase21 test expansion).
- Keep response success payloads contract-stable and avoid broad relay/auth refactors in this stream.
CL-002: TASK22211 endpoint token handler contract consistency slice
date: 2026-03-23
author: Cline
scope: pages/api/endpoint/getToken.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Close out remaining non-standard endpoint contract handling by normalizing the legacy token endpoint to shared API response helpers and explicit error coding.
impact: Improved endpoint error consistency and test coverage for token acquisition failures while preserving successful token payload passthrough.
status: completed
Summary:
- Refactored
getToken.jsto userespondSuccessandrespondErrorfrompages/api/middleware/apiResponse. - Removed legacy raw
res.status(...).json(...)/bare status assignment pattern and dead logging artifacts. - Added explicit catch-path contract:
TOKEN_FETCH_FAILEDwith 400 status. - Added endpoint phase21 tests for:
- success token payload passthrough
- catch-path error contract assertion
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 11/11
- email-handler: 12/12
- endpoint-handler: 147/147
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-depswarnings; no new lint errors)
Follow-ups:
- Remaining outlier API handler for this consistency stream is
pages/api/file/generateappealpdfcopy.js(not yet on shared response helpers).
CL-003: TASK22211 endpoint contract-hardening stream backfill (all known slices)
date: 2026-03-23
author: Cline
scope: pages/api/endpoint/*_api.js, pages/api/endpoint/getToken.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Backfill memory-bank traceability so the complete known TASK22211 contract-consistency stream is documented in one place now that memory-bank is being versioned.
impact: Improves governance/auditability of API contract hardening, makes rollout and rollback analysis easier, and records exactly which endpoint clusters were normalized.
status: completed
Summary:
- Backfilled all known TASK22211 slices currently on branch (in commit order):
b57f3desearch-document endpoint contracts + phase21 coverage9af541amy-portal retrieval endpoint contractsb880364basic search endpoint contractsa106deaDNS basic search endpoint contractsb5a3a62portal module + LPA case endpoint contracts4601d7ccase detail endpoint contracts2959c7ddelete/watched-case endpoint contractsb59f13ametadata + linked-case endpoint contractsbcf03a6form + publication endpoint contractse0e91c8DNS + representation endpoint contracts98e159dcase creation + media endpoint contracts88e4586advanced-search-paged endpoint contractcb69bbecase update + CRM task endpoint contracts722ef98hash + metadata endpoint contracts134f99caddress-search endpoint contract8b6ed73new-appeal appeal-types endpoint contracteec59e8token endpoint contract handling
- Across the stream, handlers were standardized toward
respondSuccess/respondError, required-input guards, and explicit negative-path error codes while preserving success payload compatibility. - Phase21 endpoint contract suite was expanded incrementally alongside each slice.
Validation:
- Stream validation baseline (latest known run):
node tests/phase21/api-contract-slice1.test.cjs-> pass (endpoint-handler 147/147)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Continue with remaining non-standard API outlier(s), notably
pages/api/file/generateappealpdfcopy.js. - Keep future slices logged in this file at commit-time now that memory-bank is versioned.
CL-004: TASK22224 file + static endpoint contract hardening bundle (phase21)
date: 2026-03-23
author: Cline
scope: pages/api/file/{downloadblob,generateappealpdfcopy}.js, pages/api/endpoint/{getsipsmedia_api,getappealtypesfornewappeal_api}.js, tests/phase21/{file-handler-contract,endpoint-handler-contract}.test.cjs
type: change
rationale: Deliver the agreed larger bounded slice for remaining non-standard file/static handlers, improving negative-path consistency while preserving current success payload behavior.
impact: Standardized error envelopes/codes for download and generated PDF copy flows, method guard parity for static endpoints, and expanded phase21 contract coverage for both file and endpoint handlers.
status: completed
Summary:
downloadblob.js:- added explicit catch-path response via
respondErrorwithDOWNLOAD_BLOB_FAILED - kept success behavior intact (attachment header + raw file body)
- removed dead internal helper (
streamToBuffer) and tightened local declarations
- added explicit catch-path response via
generateappealpdfcopy.js:- removed unused imports/noisy console warnings
- standardized required-input and negative-path contracts:
INCIDENT_ID_REQUIRED(400)CASE_NOT_FOUND(404)FORM_COLLECTION_NOT_FOUND(400)APPEAL_PDF_COPY_GENERATION_FAILED(400)
- preserved success output contract (PDF content headers + buffer body)
getsipsmedia_api.jsandgetappealtypesfornewappeal_api.js:- added method guard for non-GET requests using
METHOD_NOT_ALLOWED(405) - preserved existing GET success payloads
- added method guard for non-GET requests using
- Expanded phase21 tests:
file-handler-contract.test.cjs: added coverage for download failure + full generated PDF copy contract/negative pathsendpoint-handler-contract.test.cjs: added method guard tests for both static endpoints
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 17/17
- email-handler: 12/12
- endpoint-handler: 149/149
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- If desired, next slice can target remaining file-route parity candidates outside this bundle, but this closes the planned TASK22224 scope.
CL-005: TASK22224 downloadblob hotfix closure (path normalization + hash compatibility)
date: 2026-03-23
author: Cline
scope: pages/api/file/downloadblob.js
type: change
rationale: Close post-merge runtime regressions reported on live links where download URLs alternated between filename-only/full-path blob names and mixed encoded/raw hash input variants.
impact: Restored reliable blob downloads without relaxing hash security guarantees (still HMAC validated), and preserved existing caller compatibility across legacy/new URL encodings.
status: completed
Summary:
- Hotfix 1 (
f09f3b7): normalized blob path resolution- accepts both forms of
blobnameinput:- filename only (legacy)
- full prefixed path (already includes
casefolderID/...)
- prevents double-prefix lookup failures
- sets attachment filename from final path segment only
- accepts both forms of
- Hotfix 2 (
bd3bf68): hash compatibility validation- validates against a bounded set of canonical query-path variants (raw/encoded combinations for
casefolderIDandblobname) - fixes
INVALID_HASHfalse negatives for legitimate caller-generated links - keeps strict HMAC requirement in place (no unauthenticated bypass)
- validates against a bounded set of canonical query-path variants (raw/encoded combinations for
Validation:
node tests/phase21/file-handler-contract.test.cjs-> pass (17/17)node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 17/17
- email-handler: 12/12
- endpoint-handler: 149/149
- User confirmation: "downloadblob now works"
Follow-ups:
- Next recommended slice on this branch: complete file-route guard parity for
deleteblob.js,deleteblobcase.js, anddeleteblobrep.jsby aligning hash validation canonicalization and explicitrespondErrorcontracts (MISSING_REQUIRED_QUERY,INVALID_HASH, operation-specific*_FAILED). - Extend
tests/phase21/file-handler-contract.test.cjsfor the above routes with mixed encoded/raw hash cases to lock compatibility.
CL-006: TASK22224 file delete-route guard parity slice
date: 2026-03-23
author: Cline
scope: pages/api/file/{deleteblob,deleteblobcase,deleteblobrep}.js, tests/phase21/file-handler-contract.test.cjs
type: change
rationale: Execute the next planned slice to align hash/canonicalization behavior and negative-path contracts across high-risk file delete routes, matching the compatibility posture established for downloadblob.
impact: Reduces false INVALID_HASH failures for legitimate encoded/raw caller variants while preserving strict hash enforcement and improving resilience via explicit catch-path contracts.
status: completed
Summary:
deleteblob.js- added bounded hash candidate validation for encoded/raw combinations of
casefolderIDandblobname - normalized delete path handling for both filename-only and already-prefixed blob paths
- added explicit catch-path contract:
DELETE_BLOB_FAILED
- added bounded hash candidate validation for encoded/raw combinations of
deleteblobcase.js- added hash candidate validation for raw/encoded
casefolderID - added explicit catch-path contract:
DELETE_BLOB_CASE_FAILED
- added hash candidate validation for raw/encoded
deleteblobrep.js- added hash candidate validation for encoded/raw
casefolderID+repfile - added explicit catch-path contract:
DELETE_BLOB_REP_FAILED
- added hash candidate validation for encoded/raw
- Phase21 tests expanded (
file-handler-contract.test.cjs):- encoded hash-variant acceptance cases for all three delete routes
- explicit dependency-failure contract assertions for all three delete routes
Validation:
node tests/phase21/file-handler-contract.test.cjs-> pass (23/23)node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 23/23
- email-handler: 12/12
- endpoint-handler: 149/149
Follow-ups:
- Optional next slice: apply same bounded hash-canonicalization parity to remaining high-sensitivity file routes where mixed encoded/raw callers may exist (
getbloblist,getprogressobjblob) and add regression cases to phase21.
CL-007: TASK22224 getrepsblob stability hotfix after delete representation flow
date: 2026-03-23
author: Cline
scope: actions/azurestorage.js (getRepsBlobs), tests/phase21/file-handler-contract.test.cjs
type: change
rationale: Resolve reported runtime 400 (GET_REPS_BLOB_FAILED) after delete representation actions, caused by stale soft-deleted blob tag hits during representation blob enumeration.
impact: Prevents transient/stale Azure tag index entries from breaking representation retrieval, improving reliability of post-delete refresh without relaxing route security contracts.
status: completed
Summary:
- Hardened
getRepsBlobs(containerName)inactions/azurestorage.js:- fixed async misuse (
blobClient.getProperties().contentLengthwithout await) - added existence/property guard with explicit
await blobClient.getProperties() - skips 404s (soft-deleted/stale tag index results) instead of throwing
- preserves behavior for non-404 failures (rethrow for proper error visibility)
- kept existing
_rep.json/undefinedname filtering intact
- fixed async misuse (
- Added phase21 contract coverage for
getrepsblobroute:- success payload contract test
- dependency failure contract test (
GET_REPS_BLOB_FAILED)
Validation:
node tests/phase21/file-handler-contract.test.cjs-> pass (25/25)node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 25/25
- email-handler: 12/12
- endpoint-handler: 149/149
Follow-ups:
- Optional: add the same stale-tag existence guard pattern to any remaining Azure tag-list readers that still consume
findBlobsByTagsresults without property existence verification.
CL-008: TASK22224 awaiting-submission route resilience parity hardening
date: 2026-03-23
author: Cline
scope: pages/api/file/getawaitingsubmissionfromblob.js, tests/phase21/file-handler-contract.test.cjs
type: change
rationale: Add explicit catch-path contract parity for awaiting-submission blob retrieval route so unexpected dependency failures return consistent, actionable error envelopes.
impact: Improves reliability/diagnostics for post-delete case refresh and aligns file-route error handling style without changing success payload contract or hash verification behavior.
status: completed
Summary:
- Refactored
getawaitingsubmissionfromblobhandler to structuredtry/catchflow. - Preserved existing guard behavior:
MISSING_REQUIRED_QUERYfor missing container/hashINVALID_HASHfor signature mismatch
- Added explicit dependency failure contract:
GET_AWAITING_SUBMISSION_BLOB_FAILED(400)- message:
Failed to retrieve awaiting submission blobs
- Added phase21 coverage for this route:
- success payload pass-through contract
- dependency failure contract assertion
Validation:
node tests/phase21/file-handler-contract.test.cjs-> pass (27/27)node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 27/27
- email-handler: 12/12
- endpoint-handler: 149/149
Follow-ups:
- Optional parity sweep: apply the same explicit catch-path contract pattern to remaining file routes that still rely on implicit promise-chain errors.
CL-009: TASK22224 proxy-route resilience and encoding parity bundle
date: 2026-03-23
author: Cline
scope: pages/api/file/{getbloblistproxy,getrepsblobproxy,getawaitingsubmissionfromblobproxy,createappealcompletemessageproxy_api}.js, tests/phase21/file-handler-contract.test.cjs
type: change
rationale: Continue larger-slice hardening by aligning proxy handlers with explicit async error handling and safer encoded upstream query forwarding for hash-based downstream calls.
impact: Improves proxy reliability and compatibility for encoded query values while preserving existing proxy error contracts and response behavior.
status: completed
Summary:
getbloblistproxy.js- converted
.then/.catchchain to explicittry/catch - encoded forwarded
containerandcasefolderIDquery values - preserved error contract:
GET_BLOB_LIST_PROXY_FAILED
- converted
getrepsblobproxy.js- converted
.then/.catchchain to explicittry/catch - encoded forwarded
container - preserved error contract:
GET_REPS_BLOB_PROXY_FAILED
- converted
getawaitingsubmissionfromblobproxy.js- converted
.then/.catchchain to explicittry/catch - preserved error contract:
GET_AWAITING_SUBMISSION_PROXY_FAILED
- converted
createappealcompletemessageproxy_api.js- converted
.then/.catchchain to explicittry/catch - encoded forwarded
containerandtempcaseref - preserved error contract:
CREATE_APPEAL_COMPLETE_MESSAGE_PROXY_FAILED
- converted
- Phase21 tests expanded for proxy paths:
- getbloblistproxy success + dependency failure
- getrepsblobproxy success
- getawaitingsubmissionfromblobproxy dependency failure
- createappealcompletemessageproxy dependency failure
Validation:
node tests/phase21/file-handler-contract.test.cjs-> pass (46/46)node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 46/46
- email-handler: 12/12
- endpoint-handler: 149/149
Follow-ups:
- Optional next big slice: bring remaining proxy/message routes using raw axios promise chains (
createcaseinvolvement_api.js,createrepinvolvement_api.js,updatecase_api.js) onto the same async/await + explicit contract pattern.
CL-010: TASK22224 involvement/update route async contract hardening bundle
date: 2026-03-23
author: Cline
scope: pages/api/file/{createcaseinvolvement_api,createrepinvolvement_api,updatecase_api}.js, tests/phase21/file-handler-contract.test.cjs
type: change
rationale: Execute the next requested slice by modernizing remaining relay-backed involvement/update handlers that still used axios promise chains and legacy dead imports.
impact: Improves reliability/readability and preserves existing response contracts, including 412 "record exists" semantics for involvement creation flows.
status: completed
Summary:
createcaseinvolvement_api.js- removed unused
CryptoJSimport - refactored axios
.then/.catchto explicittry/catch - preserved conflict behavior: status 412 -> success
{ record: "exists" } - preserved failure contract:
CREATE_CASE_INVOLVEMENT_FAILED
- removed unused
createrepinvolvement_api.js- removed unused
CryptoJSimport - refactored axios
.then/.catchto explicittry/catch - preserved conflict behavior: status 412 -> success
{ record: "exists" } - preserved failure contract:
CREATE_REP_INVOLVEMENT_FAILED
- removed unused
updatecase_api.js- removed unused
CryptoJSimport - refactored axios
.then/.catchto explicittry/catch - preserved failure contract:
UPDATE_CASE_FAILED
- removed unused
- Phase21 tests expanded:
- createcaseinvolvement 412 conflict success contract
- createrepinvolvement dependency failure contract
- updatecase dependency failure contract
Validation:
node tests/phase21/file-handler-contract.test.cjs-> pass (49/49)node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 49/49
- email-handler: 12/12
- endpoint-handler: 149/149
Follow-ups:
- Optional: apply equivalent modernization to any remaining relay-backed handlers outside
pages/api/file/that still use raw axios promise chains and have no explicit phase21 contract assertions.
CL-011: TASK22224 aggressive non-file bundle (email/admin/endpoint parity)
date: 2026-03-23
author: Cline
scope: pages/api/email/{getmailinglist,getcaseref,notify}.js, pages/api/admin/{getnewappeals_api,getlatestdocuments_api}.js, pages/api/endpoint/getportallogin_api.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Execute requested aggressive bundling for remaining non-file modernization/parity candidates: remove legacy promise chains and improve hash compatibility on login endpoint while preserving existing contracts.
impact: Improves consistency and resilience across email/admin/endpoint routes with no contract regressions; adds encoded hash-variant compatibility for portal login hash checks.
status: completed
Summary:
pages/api/email/getmailinglist.js- converted axios
.then/.catchtotry/catch - preserved flattening behavior and error contract
MAILING_LIST_FETCH_FAILED
- converted axios
pages/api/email/getcaseref.js- converted axios
.then/.catchtotry/catch - preserved flattening behavior and error contract
CASE_REF_FETCH_FAILED
- converted axios
pages/api/email/notify.js- converted notify client
.then/.catchtotry/catch - preserved success payload and error contract
EMAIL_NOTIFY_FAILED
- converted notify client
pages/api/admin/getnewappeals_api.js- removed unused
CryptoJSimport - converted axios
.then/.catchtotry/catch - preserved
@odata.nextLinknormalization and error contractADMIN_NEW_APPEALS_FETCH_FAILED
- removed unused
pages/api/admin/getlatestdocuments_api.js- converted axios
.then/.catchtotry/catch - preserved flatten/enrich behavior and error contract
ADMIN_LATEST_DOCS_FETCH_FAILED
- converted axios
pages/api/endpoint/getportallogin_api.js- retained required query/hash guards
- expanded hash validation to accept raw + encoded
emailAddressquery-path candidates - preserved error contract
PORTAL_LOGIN_FETCH_FAILED
- phase21 endpoint tests expanded:
getportalloginencoded hash variant success pathgetnewappeals_apicatch contractgetlatestdocuments_apicatch contract
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 49/49
- email-handler: 12/12
- endpoint-handler: 152/152
Follow-ups:
- Remaining major modernization candidate is
pages/api/file/generateappealpdf.js(+ optionalpages/api/file/generatepdf.js) if we continue final closure slices.
CL-012: TASK22224 generatepdf/generateappealpdf async hardening slice
date: 2026-03-23
author: Cline
scope: pages/api/file/{generateappealpdf,generatepdf}.js, tests/phase21/file-handler-contract.test.cjs
type: change
rationale: Execute next requested slice to modernize remaining file PDF-generation handlers still using promise chains, while preserving existing hash/response behavior.
impact: Improves maintainability and error-path consistency for PDF generation routes; phase21 coverage now includes explicit failure contracts for both handlers.
status: completed
Summary:
pages/api/file/generateappealpdf.js- converted mixed promise-chain flow to
async/await+try/catch - preserved existing guard contracts:
MISSING_REQUIRED_QUERY,INVALID_HASH - preserved generation failure contract:
GENERATE_APPEAL_PDF_FAILED - replaced JSX render call with
React.createElement(...)compatibility form used by test loader
- converted mixed promise-chain flow to
pages/api/file/generatepdf.js- converted create/upload promise-chain to
async/await+try/catch - preserved existing guard contracts:
HASH_REQUIRED,INVALID_HASH - preserved generation failure contract:
GENERATE_PDF_FAILED - replaced JSX render call with
React.createElement(...)compatibility form used by test loader
- converted create/upload promise-chain to
- phase21 file tests expanded:
generatepdfcatch-path contract (GENERATE_PDF_FAILED)generateappealpdfcatch-path contract (GENERATE_APPEAL_PDF_FAILED)
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 51/51
- email-handler: 12/12
- endpoint-handler: 152/152
Follow-ups:
- Remaining optional cleanup in these handlers is dead import/unused local pruning (non-behavioral) if we want a final low-risk tidy pass.
CL-013: TASK22224 completion-message route parity closure slice
date: 2026-03-24
author: Cline
scope: pages/api/file/createappealcompletemessage_api.js, tests/phase21/file-handler-contract.test.cjs
type: change
rationale: Continue next requested slice by closing the final promise-chain parity outlier in file completion-message flow and strengthening phase21 contract coverage.
impact: Improves maintainability and async error hygiene while preserving route behavior and existing error contracts.
status: completed
Summary:
pages/api/file/createappealcompletemessage_api.js- replaced inline
.catch(...)on fire-and-forgetupdateAccount(...)with explicit async IIFE +try/catchandvoidinvocation - preserved non-blocking behavior and logging semantics for account-update failure path
- preserved primary route contracts and success payload (
{ status: "success" })
- replaced inline
- phase21 file contract tests expanded:
- success path for encoded hash candidate on
createappealcompletemessage_api - dependency-failure contract assertion for
CREATE_APPEAL_COMPLETE_MESSAGE_FAILED
- success path for encoded hash candidate on
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 53/53
- email-handler: 12/12
- endpoint-handler: 152/152
Follow-ups:
- Optional final low-risk tidy sweep: remove dead imports/unused locals in legacy file handlers now that contract hardening stream is functionally complete.
CL-014: TASK22224 pdf render compatibility tidy slice
date: 2026-03-24
author: Cline
scope: pages/api/file/{generatepdf,generateappealpdf}.js, tests/phase21/file-handler-contract.test.cjs
type: change
rationale: Apply a low-risk compatibility tidy so PDF render invocation remains stable across runtime and contract-test VM contexts.
impact: Keeps functional behavior unchanged while reducing test/runtime mismatch risk in render path setup.
status: completed
Summary:
pages/api/file/generatepdf.js- switched render call input from
React.createElement(MyDocument, ...)to directMyDocument(...)invocation inReactPDF.renderToStream(...)
- switched render call input from
pages/api/file/generateappealpdf.js- switched render call input from
React.createElement(MyDocument, ...)to directMyDocument(...)invocation inReactPDF.renderToStream(...)
- switched render call input from
tests/phase21/file-handler-contract.test.cjs- added
Bufferinjection forgeneratepdfcatch-path test harness to align VM context expectations
- added
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 53/53
- email-handler: 12/12
- endpoint-handler: 152/152
Follow-ups:
- Optional: dead import cleanup (
Document/Page/Text/View/StyleSheet/PDFViewer,middleware,nextConnect,fs, etc.) can be done in a dedicated non-behavioral hygiene PR.
CL-015: TASK22224 pdf handler dead-code hygiene slice
date: 2026-03-24
author: Cline
scope: pages/api/file/{generatepdf,generateappealpdf}.js
type: change
rationale: Execute the requested next low-risk slice by removing dead imports and unused locals in recently hardened PDF handlers.
impact: Non-behavioral maintainability cleanup; reduces lint noise and future edit risk while preserving existing contracts.
status: completed
Summary:
pages/api/file/generatepdf.js- pruned unused Azure storage imports, leaving only
createRepPDFBlob - pruned unused
@react-pdf/renderernamed imports - removed unused imports (
middleware,nextConnect,fs) - removed unused locals (
casefolderID,representationType,repRaiser,localeSelect,repCapacity,repType)
- pruned unused Azure storage imports, leaving only
pages/api/file/generateappealpdf.js- pruned unused Azure storage imports to only required functions
- pruned unused
@react-pdf/renderernamed imports - removed unused imports (
middleware,nextConnect,fs,path, unused pdf templates) - removed unused local (
caseRef)
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 53/53
- email-handler: 12/12
- endpoint-handler: 152/152
Follow-ups:
- Optional: run full repo lint in a separate pass for broader non-slice hygiene now that targeted contract suite is stable.
CL-016: TASK22224 documents download contract slice
date: 2026-03-24
author: Cline
scope: pages/api/documents/download/[id].js, tests/phase21/{documents-handler-contract,api-contract-slice1}.test.cjs
type: change
rationale: Execute next aggressive slice by standardizing document download guard behavior and bringing the route under phase21 contract coverage.
impact: Improves reliability on invalid input and relay-failure paths while preserving existing user-visible fallback behavior (/filenotavailable) for download failures.
status: completed
Summary:
pages/api/documents/download/[id].js- added explicit required-query guard for
idandhash - unified fallback redirect path via constant (
/filenotavailable) - preserved streaming download behavior and retry flow
- added explicit required-query guard for
- added
tests/phase21/documents-handler-contract.test.cjscovering:- missing query -> redirect contract
- success -> attachment/content-type headers + stream pipe contract
- relay failure -> redirect contract
- updated combined runner (
tests/phase21/api-contract-slice1.test.cjs) to include documents handler contract suite
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 53/53
- email-handler: 12/12
- endpoint-handler: 152/152
- documents-handler: 3/3
Follow-ups:
- Optional future hardening: migrate documents route onto shared
respondError/respondSuccessenvelope if product requirements allow replacing redirect-style fallback.
CL-017: TASK22224 endpoint legacy-comment hygiene slice
date: 2026-03-24
author: Cline
scope: pages/api/endpoint/{createwatchedcases_api,getadvancedsearchpaged_api}.js
type: change
rationale: Complete second requested slice with low-risk maintainability cleanup by removing large obsolete commented legacy handler blocks.
impact: Non-behavioral cleanup only; improves readability and reduces maintenance noise with no runtime contract changes.
status: completed
Summary:
createwatchedcases_api.js- removed obsolete commented promise-chain implementation block
getadvancedsearchpaged_api.js- removed obsolete commented legacy implementation block retained below active handler
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 53/53
- email-handler: 12/12
- endpoint-handler: 152/152
- documents-handler: 3/3
Follow-ups:
- Optional further hygiene pass can target remaining oversized commented historical sections in non-sensitive handlers.
CL-018: TASK22224 nextauth notify micro-refactor
date: 2026-03-24
author: Cline
scope: pages/api/auth/[...nextauth].js
type: change
rationale: Execute the explicitly approved auth micro-slice by replacing inline promise .catch(...) with explicit try/catch while preserving existing auth behavior.
impact: Auth-sensitive non-functional refactor only; keeps current sign-in flow, template/locale routing, and error-handling semantics unchanged.
status: completed
Summary:
pages/api/auth/[...nextauth].js- replaced:
await notifyClient.sendEmail(...).catch((error) => consoleLogger(error))
- with explicit:
try { await notifyClient.sendEmail(...) } catch (error) { consoleLogger(error) }
- replaced:
- preserved behavior contracts:
- Notify failures are still logged and do not throw through auth handler
- no changes to callback URL construction, locale/template selection, NextAuth options, session/cookies/pages config
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 53/53
- email-handler: 12/12
- endpoint-handler: 152/152
- documents-handler: 3/3
Follow-ups:
- Optional future auth hygiene (separate guarded slice): replace verbose auth
console.logdiagnostics with structured logger usage once production logging requirements are confirmed.
CL-019: TASK22229 P2-S1 relay forwarding pilot (proxy endpoint cluster)
date: 2026-03-24
author: Cline
scope: pages/api/middleware/relayForwarding.js, pages/api/endpoint/{getwatchedcasesproxy_api,getmyrepresentationsproxy_api,getrepresentationsproxy_api,getawaitingsubmissionproxy_api}.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Start Priority-2 by piloting a shared relay forwarding helper on a bounded proxy endpoint cluster to reduce duplicated token/hash/header/axios boilerplate while preserving endpoint contracts.
impact: Maintainability and consistency improvement with no intended behavioral contract changes; error code/status/message and success payload contracts remain unchanged for migrated endpoints.
status: completed
Summary:
- Added shared relay helper:
pages/api/middleware/relayForwarding.js- exports
relayGet({ queryUrl, res, errorResponse, transformData }) - centralizes token fetch, relay URL + hash composition,
azureHeaders, GET execution, success/error response handling, and logging
- Migrated pilot endpoint cluster to
relayGet:getwatchedcasesproxy_api.js(with existing payload transform preserved)getmyrepresentationsproxy_api.jsgetrepresentationsproxy_api.jsgetawaitingsubmissionproxy_api.js(with existing payload transform preserved)
- Updated endpoint contract tests to mock
relayGetfor migrated routes while preserving existing assertions.
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 53/53
- email-handler: 12/12
- endpoint-handler: 152/152
- documents-handler: 3/3
Follow-ups:
- P2-S2 rollout: migrate the next relay-heavy endpoint batch onto
relayGet/shared forwarding utility pattern. - P2-S3 hardening: add shared timeout/retry config and redacted structured relay error logging policy.
CL-020: TASK22229 P2-S2 Batch 1 (account/login relay GET cluster)
date: 2026-03-24
author: Cline
scope: pages/api/middleware/relayForwarding.js, pages/api/endpoint/{getaccounts_api,getemailaccountcheck_api,getpreferredlanguage_api,getlogin_api,getpersonalaccount_api,getportalloginproxy_api}.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Deliver first P2-S2 batch as a dedicated commit by migrating a bounded account/login endpoint cluster onto shared relayGet while preserving response contracts.
impact: Reduced relay boilerplate and improved consistency with no intended endpoint contract changes.
status: completed
Summary:
- Extended
relayGetto support optionalrequestOptionsBuilderfor handlers requiring paged header variants. - Migrated Batch 1 endpoints to
relayGet:getaccounts_api.jsgetemailaccountcheck_api.jsgetpreferredlanguage_api.jsgetlogin_api.js(usesazureHeadersPagedviarequestOptionsBuilder)getpersonalaccount_api.jsgetportalloginproxy_api.js(usesazureHeadersPagedviarequestOptionsBuilder)
- Updated phase21 endpoint contract tests to mock
relayGetfor migrated handlers, preserving existing guard/catch/success assertions.
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 53/53
- email-handler: 12/12
- endpoint-handler: 152/152
- documents-handler: 3/3
Follow-ups:
- Continue P2-S2 with Batch 2 as next dedicated commit on this same branch.
CL-021: TASK22229 P2-S2 Batch 2 (my-portal + representation relay GET cluster)
date: 2026-03-24
author: Cline
scope: pages/api/endpoint/{getmycases_api,getmyrepresentations_api,getwatchedcases_api,getawaitingsubmission_api,getrepresentations_api}.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Deliver second P2-S2 commit by migrating the next bounded portal/representation GET endpoint cluster onto shared relayGet while preserving route contracts.
impact: Reduced duplicated relay boilerplate and aligned forwarding behavior with no intended response contract changes.
status: completed
Summary:
- Migrated Batch 2 endpoints to
relayGet:getmycases_api.js(preserved title mapping transform)getmyrepresentations_api.jsgetwatchedcases_api.js(preserved watched-case projection transform)getawaitingsubmission_api.js(preserved title mapping transform)getrepresentations_api.js
- Updated phase21 endpoint contract tests for migrated handlers by mocking
relayGetin guard/catch test paths.
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 53/53
- email-handler: 12/12
- endpoint-handler: 152/152
- documents-handler: 3/3
Follow-ups:
- Continue P2-S2 with Batch 3 as the next dedicated commit on this branch.
CL-022: TASK22229 P2-S2 Batch 3 (case/event relay GET cluster)
date: 2026-03-24
author: Cline
scope: pages/api/endpoint/{getcase_api,getcasebyid_api,getincidentbyid_api,getsipsevents_api}.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Deliver third P2-S2 commit by migrating an additional bounded case/event endpoint cluster onto shared relayGet while preserving route contracts.
impact: Further relay boilerplate reduction and consistent forwarding behavior with no intended contract changes.
status: completed
Summary:
- Migrated Batch 3 endpoints to
relayGet:getcase_api.js(preserved@odata.nextLinknormalization)getcasebyid_api.js(preserved@odata.nextLinknormalization and array-wrapped success payload)getincidentbyid_api.jsgetsipsevents_api.js
- Updated phase21 endpoint contract tests to mock
relayGetfor migrated handlers in guard/catch paths.
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 53/53
- email-handler: 12/12
- endpoint-handler: 152/152
- documents-handler: 3/3
Follow-ups:
- Continue P2-S2 with next bounded batch (e.g. search/listing cluster) as a separate commit if required.
CL-023: TASK22229 P2-S2 Batch 6 (profile/form/document-history/portal-module relay GET cluster)
date: 2026-03-24
author: Cline
scope: pages/api/endpoint/{getpersonalaccount_api,getformdata_api,getsearchdocumenthistory_api,getsearchdocumenthistorypaged_api,getportalmoduledetails_api}.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Execute requested Batch 6 by migrating the next bounded set of read-only endpoint handlers to shared relayGet while preserving existing request validation and response/error contracts.
impact: Reduced endpoint relay boilerplate and improved consistency; no intended behavior contract changes.
status: completed
Summary:
- Migrated Batch 6 endpoints to shared
relayGet:getpersonalaccount_api.jsgetformdata_api.jsgetsearchdocumenthistory_api.js(usesrequestOptionsBuilderwithazureHeadersPaged)getsearchdocumenthistorypaged_api.js(usesrequestOptionsBuilderwithazureHeadersPaged)getportalmoduledetails_api.js
- Preserved all existing required-query validation guards and existing error codes/messages.
- Updated Phase 21 endpoint contract tests to inject
relayGetmocks for migrated handlers (validation path, catch path, and success path where applicable).
Validation:
node tests/phase21/endpoint-handler-contract.test.cjs-> pass (152/152)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded batch: migrate remaining legacy relay GET handlers in advanced/basic search-document/detail clusters that still use direct axios relay patterns.
CL-024: TASK22229 P2-S2 Batch 7 (search-document + portal-proxy relay GET cluster)
date: 2026-03-24
author: Cline
scope: pages/api/endpoint/{getportalmoduledetailsproxy_api,getsearchdocumentTypes_api,getsearchdocumentdetails_api,getsearchdocumentdetailspaged_api,getappealpdfdocuments_api}.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Continue P2-S2 in bounded commits by migrating a coherent search-document/portal-proxy GET cluster onto shared relay forwarding while preserving existing validation, transforms, and error contracts.
impact: Reduced duplicate relay plumbing and improved consistency in search-document handlers; no intended API contract changes.
status: completed
Summary:
- Migrated Batch 7 endpoints to shared
relayGet:getportalmoduledetailsproxy_api.jsgetsearchdocumentTypes_api.jsgetsearchdocumentdetails_api.jsgetsearchdocumentdetailspaged_api.jsgetappealpdfdocuments_api.js
- Preserved existing guard behavior and error response contracts.
- Preserved endpoint-specific transform behavior via
transformData, including:- grouped search-document type payloads
- document hashlink enrichment and published-date normalization
@odata.nextLinknormalization where present- appeal PDF document name projection
- Updated phase21 endpoint tests to mock
relayGetfor migrated handlers in validation/catch/success paths as applicable.
Validation:
node tests/phase21/endpoint-handler-contract.test.cjs-> pass (152/152)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Continue with next bounded P2-S2 batch from remaining legacy GET endpoints (e.g., advanced/basic paged search-detail clusters and related non-migrated proxies).
CL-025: TASK22229 P2-S2 Batch 8 (basic search details + DNS details relay GET cluster)
date: 2026-03-24
author: Cline
scope: pages/api/endpoint/{getbasicsearchpaged_api,getbasicsearchdetails_api,getbasicsearchdetailspaged_api,getbasicdnssearchdetails_api,getbasicdnssearchdetailspaged_api}.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Continue the P2-S2 relay migration using bounded commits by moving the remaining basic-search-details and DNS-details GET handlers to shared relayGet, preserving existing guards and response contracts.
impact: Reduced duplicated relay plumbing and more consistent forwarding behavior across search-detail handlers; no intended API contract changes.
status: completed
Summary:
- Migrated Batch 8 endpoints to shared
relayGet:getbasicsearchpaged_api.jsgetbasicsearchdetails_api.jsgetbasicsearchdetailspaged_api.jsgetbasicdnssearchdetails_api.jsgetbasicdnssearchdetailspaged_api.js
- Preserved existing validation guards and error contracts.
- Preserved existing endpoint-specific transforms:
@odata.nextLinknormalization in paged responses- flattened ticketnumber enrichment for search detail handlers
- Updated phase21 endpoint contract tests to inject
relayGetmocks for migrated handlers in validation and catch-path tests.
Validation:
node tests/phase21/endpoint-handler-contract.test.cjs-> pass (152/152)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Continue P2-S2 with next bounded batch from remaining legacy GET endpoints (currently:
createwatchedcases_api,deletewatchedcasesproxy_api,getadvancedsearch_api,getadvancedsearchpaged_api,getappealid_api,getbasicdnssearchpaged_api,getbasicpartsaveddetails_api,getbasicsearch_by_address_api,getbasicsearch_by_lparref_api,getdnscoords_api,getdnslist_api,getmylpacases_api,getportallogin_api).
CL-026: TASK22229 P2-S2 Batch 9 (appeal-id + DNS list/paged + part-saved relay GET cluster)
date: 2026-03-24
author: Cline
scope: pages/api/endpoint/{getappealid_api,getbasicdnssearchpaged_api,getbasicpartsaveddetails_api,getdnslist_api}.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Continue bounded P2-S2 relay migration by moving another coherent set of read-only handlers to shared relayGet, preserving existing guards, transforms, and error contracts.
impact: Reduced duplicated relay plumbing and improved consistency for DNS list/paged and appeal detail lookup endpoints; no intended API contract changes.
status: completed
Summary:
- Migrated Batch 9 endpoints to shared
relayGet:getappealid_api.jsgetbasicdnssearchpaged_api.jsgetbasicpartsaveddetails_api.jsgetdnslist_api.js
- Preserved existing input validation guards and endpoint-specific error contracts.
- Preserved endpoint-specific transform behavior (
@odata.nextLinknormalization in DNS list/paged handlers). - Updated phase21 endpoint contract tests to inject
relayGetmocks for these migrated handlers in guard and catch-path assertions.
Validation:
node tests/phase21/endpoint-handler-contract.test.cjs-> pass (152/152)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Continue P2-S2 with next bounded batch from remaining legacy relay GET endpoints (
createwatchedcases_api,deletewatchedcasesproxy_api,getadvancedsearch_api,getadvancedsearchpaged_api,getbasicsearch_by_address_api,getbasicsearch_by_lparref_api,getdnscoords_api,getmylpacases_api,getportallogin_api).
CL-027: TASK22229 P2-S2 Batch 10 (portal login + my LPA cases relay GET pair)
date: 2026-03-24
author: Cline
scope: pages/api/endpoint/{getportallogin_api,getmylpacases_api}.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Continue bounded relay migration by moving two remaining high-use portal retrieval endpoints to shared relayGet while preserving existing hash/lookup guards and response contracts.
impact: Further relay boilerplate reduction and consistent forwarding behavior in portal login/LPA case retrieval flows; no intended API contract changes.
status: completed
Summary:
- Migrated Batch 10 endpoints to shared
relayGet:getportallogin_api.js(preserved hash validation guard and error contract)getmylpacases_api.js(preserved LPA lookup/404 guard and title transform)
- Preserved endpoint-specific behavior:
getportallogin_api: raw + encoded hash candidate validation before relay callgetmylpacases_api: JSONPath LPA lookup withLPA_NOT_FOUNDhandling andpinswg_titleenrichment transform
- Updated phase21 endpoint contract tests to inject
relayGetmocks for migrated handlers in validation/catch/success paths.
Validation:
node tests/phase21/endpoint-handler-contract.test.cjs-> pass (152/152)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Continue P2-S2 with the remaining legacy relay GET candidates (
createwatchedcases_api,deletewatchedcasesproxy_api,getadvancedsearch_api,getadvancedsearchpaged_api,getbasicsearch_by_address_api,getbasicsearch_by_lparref_api,getdnscoords_api).
CL-028: TASK22229 P2-S2 Batch 11 (advanced-search-paged relay GET)
date: 2026-03-24
author: Cline
scope: pages/api/endpoint/getadvancedsearchpaged_api.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Continue bounded relay migration by moving the remaining advanced-search paged GET handler to shared relayGet while preserving query validation and response contracts.
impact: Reduced duplicated relay plumbing and aligned advanced paged search route with shared forwarding; no intended API contract changes.
status: completed
Summary:
- Migrated
getadvancedsearchpaged_api.jsto sharedrelayGet. - Preserved existing guard behavior and error contracts:
SEARCH_STRING_REQUIREDORDER_BY_REQUIREDFIELD_SORT_REQUIREDSHOW_NUMBER_OF_RECORDS_REQUIREDINVALID_SEARCH_STRINGADVANCED_SEARCH_PAGED_FETCH_FAILED
- Preserved endpoint-specific transform behavior (
@odata.nextLinknormalization viatransformData). - Updated phase21 endpoint contract tests to inject
relayGetmocks forgetadvancedsearchpaged_apiguard/catch assertions.
Validation:
node tests/phase21/endpoint-handler-contract.test.cjs-> pass (152/152)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Continue P2-S2 with remaining legacy relay GET candidates (
createwatchedcases_api,deletewatchedcasesproxy_api,getadvancedsearch_api,getbasicsearch_by_address_api,getbasicsearch_by_lparref_api,getdnscoords_api).
CL-029: TASK22229 P2-S2 Batch 12 (remaining relay GET candidates)
date: 2026-03-24
author: Cline
scope: pages/api/middleware/relayForwarding.js, pages/api/endpoint/{createwatchedcases_api,deletewatchedcasesproxy_api,getadvancedsearch_api,getbasicsearch_by_address_api,getbasicsearch_by_lparref_api,getdnscoords_api}.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Complete Batch 12 by migrating the remaining listed legacy relay GET candidates to shared forwarding helpers while preserving endpoint-specific validation, transforms, and error contracts.
impact: Consolidated relay GET behavior and reduced endpoint-level relay boilerplate; no intended API contract changes.
status: completed
Summary:
- Extended relay middleware with reusable helpers:
relayGetDatanow supports token reuse viatransformDatapath- Added
forwardGetDatato support custom base URLs (used by proxy-to-local endpoint) while preserving hash behavior
- Migrated remaining Batch 12 candidates:
getadvancedsearch_api.js->relayGet+relayGetDatafor project-type enrichment loopgetdnscoords_api.js->relayGetDatafor both DNS + SIPS source pullsgetbasicsearch_by_lparref_api.js->relayGetDatagetbasicsearch_by_address_api.js->relayGetDatafor appeal-type and incident fetchesdeletewatchedcasesproxy_api.js->forwardGetDatawithBASE_URLcreatewatchedcases_api.js->relayGetDatafor record-exists pre-check (POST/PATCH upsert flow preserved)
- Preserved endpoint-specific guard and error contracts (including status codes such as 500 for
BASIC_SEARCH_BY_ADDRESS_FETCH_FAILED). - Updated phase21 endpoint contract tests for migrated handlers to mock
relayGetData/forwardGetDatawhere appropriate.
Validation:
node tests/phase21/endpoint-handler-contract.test.cjs-> pass (152/152)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Batch 12 completes the previously listed remaining P2-S2 relay GET candidates.
CL-030: TASK22236 P2-S3 relay forwarding hardening (timeouts, retries, structured redacted logs)
date: 2026-03-24
author: Cline
scope: pages/api/middleware/relayForwarding.js, tests/phase21/relay-forwarding-hardening.test.cjs
type: change
rationale: Begin P2-S3 by hardening shared relay forwarding behavior with bounded timeout/retry controls and structured redacted operational logging, reducing transient failure impact while preserving endpoint contracts.
impact: Improves resilience/observability for relay GET traffic; endpoint success/error contracts remain unchanged because caller handlers still manage response envelopes.
status: completed
Summary:
- Hardened
forwardGetDatainrelayForwarding.jswith:- configurable timeout (
RELAY_TIMEOUT_MS, default 8000ms) - bounded retries (
RELAY_RETRY_MAX, default 2) - exponential backoff with cap (
RELAY_RETRY_BASE_DELAY_MS,RELAY_RETRY_MAX_DELAY_MS) - retry eligibility for transient statuses/codes (
408/429/5xx, selected network timeout/reset codes)
- configurable timeout (
- Added structured, redacted operational relay logs:
relay_request_retryingrelay_request_failed
- Preserved compatibility behaviors:
- existing token/header/hash handling
- optional
appendHashand customrequestOptionsBuilder - endpoint-level
relayGeterror response semantics
- Added focused Phase 21 hardening tests:
- retries on retryable status and succeeds
- does not retry non-retryable status
- applies timeout and respects
appendHash=false
Validation:
node tests/phase21/relay-forwarding-hardening.test.cjs-> pass (3/3)node tests/phase21/endpoint-handler-contract.test.cjs-> pass (152/152)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next hardening increment: introduce endpoint-specific retry overrides for write paths (if future non-GET use is introduced) to keep retry policy conservative by operation type.
CL-031: TASK22236 P2-S3 Batch 2A policy tightening (retry classification, config clamping, log de-dup)
date: 2026-03-24
author: Cline
scope: pages/api/middleware/relayForwarding.js, tests/phase21/relay-forwarding-hardening.test.cjs
type: change
rationale: Execute P2-S3 Batch 2A by tightening relay retry policy and operational safety bounds while preventing duplicate error noise between relay-layer and endpoint-layer logging.
impact: Stronger resilience and cleaner observability with no endpoint contract changes; retry behavior is now explicitly conservative for deterministic client/auth failures.
status: completed
Summary:
- Updated relay retry policy:
- explicitly non-retryable statuses:
400,401,403,404,422 - retries still allowed for transient classes (
408,429,5xx) and selected transport error codes - any other explicit numeric HTTP status now treated as non-retryable by default
- explicitly non-retryable statuses:
- Added runtime-safe config clamping for relay knobs:
- timeout clamped to
100..30000ms - retries clamped to
0..4 - retry delays clamped to
0..5000ms - both env-derived and per-call numeric overrides are sanitized
- timeout clamped to
- Reduced duplicate logging noise:
- non-retry terminal relay failures are marked as already logged in middleware
relayGetcatch now skipsconsoleLoggerwhen relay layer has already emitted a structured log
- Expanded relay hardening tests:
- no retry on
401 - duplicate logging suppression path through
relayGet - env-value clamping behavior for timeout bounds
- no retry on
Validation:
node tests/phase21/relay-forwarding-hardening.test.cjs-> pass (6/6)node tests/phase21/endpoint-handler-contract.test.cjs-> pass (152/152)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Batch 2B: update memory/context docs with canonical relay hardening policy, env knobs, and rollback/tuning guidance.
CL-032: TASK22239 governance + operational rollout playbook bundle (relay hardening)
date: 2026-03-24
author: Cline
scope: context/runbook.md, context/integration-map.md, memory-bank/{change-log,decisions,patterns}.md
type: change
rationale: Deliver a combined governance and operational rollout slice after P2-S3 code hardening so relay policy changes have explicit merge gates, smoke matrix coverage, and rollback/monitoring discipline.
impact: Improves release safety and auditability for relay policy updates without changing runtime endpoint behavior.
status: completed
Summary:
- Added a dedicated Relay Hardening Rollout Playbook section to
context/runbook.mdcovering:- pre-merge governance gate checklist
- non-prod smoke matrix for deterministic and transient failure classes
- progressive rollout guidance
- Day 1/Day 3 monitoring checks
- fast mitigation/rollback sequence
- Added relay policy governance references in architecture/integration context docs to make rollout checks discoverable for future contributors.
- Recorded governance baseline updates in memory-bank:
- decision entry for relay policy-change governance gate
- reusable pattern entry for required rollout/smoke/rollback workflow
Validation:
- Documentation consistency review across
context/runbook.md,context/integration-map.md, and memory-bank entries.
Follow-ups:
- Optional next iteration: add a PR template block in Azure DevOps mirroring the runbook governance gate checklist.
CL-033: TASK22242 relay telemetry enrichment (lifecycle events + correlation fields)
date: 2026-03-24
author: Cline
scope: pages/api/middleware/relayForwarding.js, tests/phase21/relay-forwarding-hardening.test.cjs
type: change
rationale: Add richer relay observability so operations can correlate retries and outcomes per request and track latency/status patterns without changing endpoint contracts.
impact: Improves operational diagnostics and trend analysis for relay traffic while preserving existing API behavior.
status: completed
Summary:
- Enriched relay middleware telemetry with request lifecycle events:
relay_request_startedrelay_request_retryingrelay_request_succeededrelay_request_failed
- Added shared telemetry fields for correlation and analysis:
relayRequestId(per request correlation id)attemptsMade,retryCountUsed,remainingRetrieselapsedMsstatusClass(2xx/4xx/5xxstyle buckets)- resolved runtime knobs included at start event
- Kept existing retry policy and endpoint response contracts unchanged.
- Expanded phase21 relay hardening tests to assert telemetry behavior:
- started/retrying/succeeded event presence
- failed event telemetry fields
- stable
relayRequestIdacross lifecycle events for one request
Validation:
node tests/phase21/relay-forwarding-hardening.test.cjs-> pass (7/7)node tests/phase21/endpoint-handler-contract.test.cjs-> pass (152/152)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next step: map these lifecycle fields into central dashboards/alerts (retry rate, status-class distribution, p95 elapsedMs).
CL-034: TASK22242 per-endpoint relay overrides + idempotency-aware retry gating
date: 2026-03-24
author: Cline
scope: pages/api/middleware/relayForwarding.js, tests/phase21/relay-forwarding-hardening.test.cjs
type: change
rationale: Deliver the next functional relay enhancement by enabling route-level retry tuning while adding safe-by-default retry gating for non-idempotent methods.
impact: Improves control and safety of relay retries without breaking existing endpoint contracts.
status: completed
Summary:
- Added relay policy override support (
relayPolicy) to shared relay helpers (relayGet,relayGetData,forwardGetData):- per-call override of
timeoutMs,maxRetries,retryBaseDelayMs,retryMaxDelayMs - optional method override via
relayPolicy.method
- per-call override of
- Added idempotency-aware retry gating scaffolding:
- retries allowed by default only for idempotent methods (
GET,HEAD,OPTIONS) - non-idempotent retry behavior controlled by:
- env flag
RELAY_ALLOW_NON_IDEMPOTENT_RETRIES(default false) - per-call override
relayPolicy.allowNonIdempotentRetries
- env flag
- retries allowed by default only for idempotent methods (
- Extended relay telemetry fields to include method and non-idempotent policy posture in start/failure/retry events.
- Preserved existing route behavior:
- existing GET endpoint flows continue to use retries per configured bounds
- no endpoint response contract changes
Validation:
node tests/phase21/relay-forwarding-hardening.test.cjs-> pass (10/10)node tests/phase21/endpoint-handler-contract.test.cjs-> pass (152/152)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Future non-GET relay adoption should explicitly opt in/out per route using
relayPolicyand include targeted negative-path tests.
CL-035: TASK22242 apply relayPolicy overrides across broader endpoint cluster
date: 2026-03-24
author: Cline
scope: pages/api/endpoint/{getaccounts_api,getemailaccountcheck_api,getpreferredlanguage_api,getpersonalaccount_api,getlogin_api,getbasicsearch_api,getbasicsearchpaged_api,getadvancedsearch_api,getadvancedsearchpaged_api}.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Expand practical adoption of per-endpoint relay policy tuning so high-traffic account/login/search handlers explicitly declare timeout/retry posture rather than relying only on global defaults.
impact: Better operational control and predictable retry behavior per endpoint cluster, with no API contract changes.
status: completed
Summary:
- Added explicit
relayPolicyusage to a broader endpoint set:- account/login:
getaccounts,getemailaccountcheck,getpreferredlanguage,getpersonalaccount,getlogin - search:
getbasicsearch,getbasicsearchpaged,getadvancedsearch,getadvancedsearchpaged
- account/login:
- Applied conservative policy profiles by flow:
- login endpoint (
getlogin): no retries (maxRetries: 0) and tighter timeout - account lookup endpoints: low retry posture (
maxRetries: 1) - search endpoints: bounded retry posture (
maxRetries: 2) for transient resilience
- login endpoint (
- Kept method explicit as
GETin policy for clarity and future-proofing. - Extended phase21 endpoint tests with relayPolicy propagation assertions:
getaccountsrelayPolicy pass-throughgetloginstrict relayPolicy pass-throughgetbasicsearchpagedrelayPolicy pass-through
Validation:
node tests/phase21/endpoint-handler-contract.test.cjs-> pass (155/155)node tests/phase21/relay-forwarding-hardening.test.cjs-> pass (10/10)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next slice: apply relayPolicy declarations to remaining relayGet endpoints in coherent batches (portal module/documents/DNS groups) and standardize policy presets in one shared constants module.
CL-036: TASK22242 portal-facing relayPolicy parity (login + module endpoints)
date: 2026-03-24
author: Cline
scope: pages/api/endpoint/{getportallogin_api,getportalloginproxy_api,getportalmoduledetails_api,getportalmoduledetailsproxy_api}.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Complete the next practical relay policy rollout slice by bringing portal-facing login/module endpoints onto explicit per-endpoint timeout/retry posture.
impact: Improves predictability and operational tuning for portal-facing relay GET flows without changing API contracts.
status: completed
Summary:
- Added explicit
relayPolicyfor four portal-facing endpoints:getportallogin_api-> strict/no-retry profile (maxRetries: 0, tighter timeout)getportalloginproxy_api-> low-retry account lookup profile (maxRetries: 1)getportalmoduledetails_api-> bounded read profile (maxRetries: 2)getportalmoduledetailsproxy_api-> bounded read profile (maxRetries: 2)
- Kept method explicit (
GET) in each endpoint policy object. - Extended phase21 endpoint tests with relayPolicy propagation assertions for all four endpoints.
Validation:
node tests/phase21/endpoint-handler-contract.test.cjs-> pass (159/159)node tests/phase21/relay-forwarding-hardening.test.cjs-> pass (10/10)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next slice: extract shared relay policy presets into constants to reduce duplication and enforce profile consistency across remaining relayGet endpoints.
CL-037: TASK22242 portal/my-cases relayPolicy parity (my portal + representations)
date: 2026-03-24
author: Cline
scope: pages/api/endpoint/{getmycases_api,getmyrepresentations_api,getwatchedcases_api,getawaitingsubmission_api,getrepresentations_api}.js, tests/phase21/endpoint-handler-contract.test.cjs
type: change
rationale: Continue the branch-by-branch relay policy rollout by applying explicit policy posture to core my-portal retrieval endpoints.
impact: Improves consistency and operational predictability of relay behavior for portal case/representation listing flows without changing endpoint contracts.
status: completed
Summary:
- Added explicit
relayPolicydeclarations to:getmycases_apigetmyrepresentations_apigetwatchedcases_apigetawaitingsubmission_apigetrepresentations_api
- Applied bounded read profile across the batch:
method: "GET"timeoutMs: 8000maxRetries: 2retryBaseDelayMs: 150retryMaxDelayMs: 800
- Extended phase21 endpoint contract tests with relayPolicy pass-through assertions for each endpoint.
Validation:
node tests/phase21/endpoint-handler-contract.test.cjs-> pass (164/164)node tests/phase21/relay-forwarding-hardening.test.cjs-> pass (10/10)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next slice: extract shared relay policy presets into a constants module and reference them from all relayGet endpoints to reduce duplication.
CL-038: TASK22242 P2-S3 closure slice — shared relay policy presets extraction
date: 2026-03-24
author: Cline
scope: pages/api/middleware/relayPolicyPresets.js, pages/api/endpoint/{getaccounts_api,getemailaccountcheck_api,getpreferredlanguage_api,getpersonalaccount_api,getlogin_api,getportallogin_api,getportalloginproxy_api,getbasicsearch_api,getbasicsearchpaged_api,getadvancedsearch_api,getadvancedsearchpaged_api,getportalmoduledetails_api,getportalmoduledetailsproxy_api,getmycases_api,getmyrepresentations_api,getawaitingsubmission_api,getrepresentations_api,getwatchedcases_api}.js, tests/phase21/_shared.cjs
type: change
rationale: Complete the planned P2-S3 final maintainability slice by centralizing repeated relay timeout/retry policy objects into shared presets used consistently across all targeted relayGet endpoints.
impact: Eliminates duplicated policy literals, reduces drift risk, and preserves endpoint contracts/behavior by reusing equivalent policy values.
status: completed
Summary:
- Added new middleware constants module:
pages/api/middleware/relayPolicyPresets.jsRELAY_POLICY_STRICT_LOGINRELAY_POLICY_LOOKUPRELAY_POLICY_BOUNDED_READRELAY_POLICY_SEARCH_PAGED
- Refactored 18 relayGet endpoints to import and use shared presets instead of inline
relayPolicyobject literals:- lookup profile:
getaccounts,getemailaccountcheck,getpreferredlanguage,getpersonalaccount,getportalloginproxy - strict login profile:
getlogin,getportallogin - bounded read profile:
getbasicsearch,getportalmoduledetails,getportalmoduledetailsproxy,getmycases,getmyrepresentations,getawaitingsubmission,getrepresentations,getwatchedcases - search paged profile:
getbasicsearchpaged,getadvancedsearch,getadvancedsearchpaged
- lookup profile:
- Updated phase21 VM test harness (
tests/phase21/_shared.cjs) to inject preset constants so endpoint contract tests continue to execute with import-stripped modules.
Validation:
node tests/phase21/endpoint-handler-contract.test.cjs-> pass (164/164)node tests/phase21/relay-forwarding-hardening.test.cjs-> pass (10/10)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- P2-S3 planned slices are now complete; no further mandatory relay policy rollout slices remain for this stream.
CL-039: TASK22260 actions façade increment — shared relay client extraction
date: 2026-03-25
author: Cline
scope: actions/clients/{relayClient,index}.js, actions/services/{accountDirectService,portalDirectService,documentDirectService}.js, actions/index.js, actions/clients/README.md
type: change
rationale: Continue Priority 1 façade decomposition by extracting duplicated hash-signing relay helper logic into a dedicated client module while preserving existing service/public export contracts.
impact: Reduces duplication and drift risk in security-sensitive relay signing helper logic without changing call-site behavior.
status: completed
Summary:
- Added a new shared client wrapper:
actions/clients/relayClient.jsexportingbuildHashedQueryUrl
- Added
actions/clients/index.jsbarrel and exposed client exports viaactions/index.js. - Updated direct services to consume shared relay client helper instead of duplicating local helper implementations:
actions/services/accountDirectService.jsactions/services/portalDirectService.jsactions/services/documentDirectService.js
- Updated
actions/clients/README.mdto reflect the now-implemented relay client extraction and future incremental client split path.
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)- Verified no remaining duplicated local
buildHashedQueryUrldefinitions acrossactions/services/*DirectService.js
Follow-ups:
- Optional next TASK22260 increment: extract common axios invocation helpers into dedicated clients (
endpointClient,fileClient,notifyClient) while keepingactions/index.jsAPI stable.
Addendum (same TASK22260 slice):
- Added shared
endpointClientwithgetJsonandrequestJsonhelpers (actions/clients/endpointClient.js) and exported it viaactions/clients/index.js. - Migrated additional direct services to consume shared endpoint client helpers:
actions/services/notifyDirectService.js(POST viarequestJson)actions/services/integrationDirectService.js(POST viarequestJson)actions/services/adminDirectService.js(GET flows viagetJson)
- Updated
actions/clients/README.mdto includeendpointClientin current extracted clients.
CL-040: TASK22260 next slice — reference-data direct service endpointClient adoption
date: 2026-03-25
author: Cline
scope: actions/services/referenceDataDirectService.js, actions/clients/README.md
type: change
rationale: Continue the incremental façade/client adoption stream by migrating another bounded direct-service module to shared endpoint request helpers.
impact: Reduces axios boilerplate and centralizes JSON extraction behavior for reference-data requests without changing public call signatures.
status: completed
Summary:
- Migrated
actions/services/referenceDataDirectService.jsfrom directaxios.get(...).then(res => res.data)patterns to sharedgetJson(...)helper fromactions/clients/endpointClient. - Preserved existing error behavior:
logAndReturnEmptyValueErrorResponsefor appeals/project/LPA fetchesconsoleLoggercatch handling for form/mandatory/picklist/notice fetches
- Updated
actions/clients/README.mdusage notes to include reference-data service reuse.
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Next optional bounded slice: adopt
getJson/requestJsonfor selected low-risk read paths insearchDirectServiceorcaseDirectServicewhile preserving per-function error semantics.
CL-041: TASK22260 next slice — account direct service endpointClient adoption
date: 2026-03-25
author: Cline
scope: actions/services/accountDirectService.js
type: change
rationale: Continue incremental façade migration by moving account direct-service request plumbing onto shared endpoint client helpers while preserving existing error-return behavior contracts.
impact: Reduces duplicated axios response extraction boilerplate and aligns account service request handling with the emerging client-layer pattern.
status: completed
Summary:
- Refactored
actions/services/accountDirectService.jsto consume shared endpoint client helpers:getJson(...)for GET requestsrequestJson(...)for config-based POST requests
- Kept existing relay hash-signing behavior unchanged via
buildHashedQueryUrlfromrelayClient. - Preserved existing catch-path semantics, including:
- logging with
consoleLogger - returning
JSON.stringify(error)in portal login functions - returning
error.responsein preferred-language failure path
- logging with
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: adopt endpoint client helpers in selected
portalDirectServiceGET/POST helper paths while preserving delete/hash flow semantics.
CL-042: TASK22260 next slice — portal direct service partial endpointClient adoption
date: 2026-03-25
author: Cline
scope: actions/services/portalDirectService.js
type: change
rationale: Continue phased client-layer adoption by migrating low-risk portal direct-service read/create paths to shared endpoint request helpers while leaving hash-sensitive delete/message flows unchanged.
impact: Reduces duplicated axios response extraction on high-traffic portal retrieval paths and keeps hashed delete/message semantics stable.
status: completed
Summary:
- Refactored selected
portalDirectServicefunctions to use shared endpoint client helpers:getJson(...)for read/listing routes (getMyCases,getMyInvolvements,getMyLPACases, representations, watched, awaiting submission variants)requestJson(...)forcreateWatchedCases
- Preserved existing hash/delete/message flow implementations (
deleteMyRepresentations,deleteWatchedCases, completion message functions) using existing axios + relay signing behavior. - Preserved existing catch-path logging behavior for all migrated functions.
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: migrate remaining non-hash POST helpers in
portalDirectService(setRepInvolvment,setCaseInvolvment) torequestJsonfor full internal consistency.
CL-043: TASK22260 next slice — portal involvement helper endpointClient completion
date: 2026-03-25
author: Cline
scope: actions/services/portalDirectService.js
type: change
rationale: Complete the next bounded internal-consistency slice by migrating remaining non-hash portal involvement POST helpers to shared endpoint client request plumbing.
impact: Aligns portal service POST helper internals with established requestJson usage while preserving route semantics and error handling.
status: completed
Summary:
- Migrated remaining portal involvement helper POST functions to shared endpoint client:
setRepInvolvmentsetCaseInvolvment
- Both now use
requestJson(config)while preserving existing payload shape, endpoint URLs, and catch-path logging behavior. - No changes made to hash-sensitive delete/message pathways.
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: begin selective
requestJsonadoption for remaining config-based calls indocumentDirectServicewhere hash flow is already centralized.
CL-044: TASK22260 next slice — document direct service low-risk getJson adoption
date: 2026-03-25
author: Cline
scope: actions/services/documentDirectService.js
type: change
rationale: Continue incremental façade/client rollout by migrating low-risk document service GET wrappers that already return JSON and do not alter hash-signing semantics.
impact: Reduces duplicated axios .get(...).then(res => res.data) boilerplate and aligns document retrieval helpers with shared endpoint client usage.
status: completed
Summary:
- Added
getJsonusage in selected document service helpers:getRepsFromBlobProxygetAwaitingSubmissionFromBlobProxygetFilesFromBlobproxygetFilesFromBlobHashedgetProgressFromBlobcreateContainerProxy
- Preserved existing behavior contracts:
- same query composition and hash query fragments
- same catch-path logging and return conventions (including JSON string return in
createContainerProxyerror path)
- Left hash-sensitive delete/upload/generation flows unchanged in this slice.
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: migrate selected
requestJson-eligible upload/generation helpers indocumentDirectService(non-download paths) while preserving multipart/blob behavior.
CL-045: TASK22260 next slice — document direct service requestJson adoption (uploads + PDF generation)
date: 2026-03-25
author: Cline
scope: actions/services/documentDirectService.js
type: change
rationale: Continue bounded client migration by moving config-based multipart/PDF POST helpers in document service to shared requestJson while preserving hashed URL generation and responseType behavior.
impact: Reduces repeated axios config execution boilerplate and aligns document POST helper internals with shared endpoint client conventions.
status: completed
Summary:
- Migrated selected config-based document helper flows from
axios(config)+res.datatorequestJson(config):uploadFilesuploadSingleFileuploadRepFilesgenerateRepPDFgenerateAppealPDF
- Preserved behavior-critical aspects:
- hashed URL creation via
buildHashedQueryUrl(...) - multipart headers for upload flows
- conditional
responseType: "blob"for download PDF option paths - existing catch-path logging semantics
- hashed URL creation via
- Left delete/download/hash-sensitive GET helpers unchanged in this slice.
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: evaluate remaining legacy direct
axios.get(...).then(res.data)helpers indocumentDirectService(getAwaitingSubmissionFromBlob,getRepsFromBlob,getFilesFromBlob) for safe migration while preserving signed hash path behavior.
CL-046: TASK22260 next slice — document direct service remaining signed GET helper migration
date: 2026-03-25
author: Cline
scope: actions/services/documentDirectService.js
type: change
rationale: Complete the remaining low-risk read helper migration in document service by replacing final direct axios.get(...).then(res.data) patterns with shared getJson while retaining hash/signature query construction.
impact: Finishes consistency pass for JSON-returning document read helpers and reduces duplicated response extraction logic.
status: completed
Summary:
- Migrated the remaining signed document read helpers to
getJson(...):getAwaitingSubmissionFromBlobgetRepsFromBlobgetFilesFromBlob
- Preserved existing behavior:
- same BASE_URL and hash query composition via
hashAPIPath(...) - same catch-path logging behavior (
consoleLogger) - no changes to delete/download flows or hash-signing helper usage in mutation paths
- same BASE_URL and hash query composition via
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: targeted hygiene in
documentDirectServiceto isolate remaining non-migrated special-case flows (downloadBlob, delete helpers) and assess if any shared client abstraction is beneficial without altering behavior.
CL-047: TASK22260 next slice — case direct service low-risk getJson adoption
date: 2026-03-25
author: Cline
scope: actions/services/caseDirectService.js
type: change
rationale: Continue incremental endpoint client rollout with a bounded low-risk set of case service GET helpers that already return direct JSON payloads and have simple logging-only catch paths.
impact: Reduces repeated axios GET/response extraction boilerplate and aligns additional case retrieval helpers with shared client conventions.
status: completed
Summary:
- Added
getJsonusage in selectedcaseDirectServicehelper functions:getAppealPDFDocsgetPortalModuleDetailsgetPortalModuleDetailsProxy
- Preserved existing behavior contracts:
- same request URL/query construction
- same catch-path logging via
consoleLogger - no change to handlers with bespoke error-return contracts (
getAppealPDFDocument) or other non-targeted flows.
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: migrate additional safe case service GET helpers that currently use
axios.get(...).then(res.data)togetJsonwhere custom catch behavior is compatible.
CL-048: TASK22260 next slice — case direct service GET cluster expansion
date: 2026-03-25
author: Cline
scope: actions/services/caseDirectService.js
type: change
rationale: Continue phased endpoint client adoption by migrating another bounded set of case service GET helpers that already use shared catch handling (logAndReturnResponse).
impact: Further reduces duplicated axios GET/response extraction boilerplate while preserving existing error-handling contracts for migrated paths.
status: completed
Summary:
- Migrated additional case retrieval helpers from
axios.get(...).then(res.data)togetJson(...):getCaseMessagegetIncidentbyIDgetIsPublishedbyIDgetPartSavedAppealgetSIPSEventsgetSIPSMedia
- Preserved behavior contracts:
- unchanged URLs/query parameter composition
- unchanged catch behavior via
logAndReturnResponse - left non-targeted/bespoke flows untouched (
getAppealID, create/update/patch operations, and error-response-specialized helpers)
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: evaluate remaining GET helpers in
caseDirectServicewith custom catches (getCase,getCaseByID,getAppealPDFDocument) for selective migration where return-shape contracts remain stable.
CL-049: TASK22260 next slice — case direct service remaining GET helper migration
date: 2026-03-25
author: Cline
scope: actions/services/caseDirectService.js
type: change
rationale: Complete the remaining safe GET-helper client migration in case service by moving custom-catch read functions to getJson while preserving their existing return-shape/error handling behavior.
impact: Removes remaining direct axios GET response-extraction boilerplate in case read helpers and completes endpointClient read-path consistency for this service subset.
status: completed
Summary:
- Migrated remaining targeted case read helpers from direct
axios.get(...).then(res.data)togetJson(...):getCasegetCaseByIDgetAppealPDFDocument
- Preserved behavior contracts:
- unchanged request URL/query construction
- unchanged catch semantics:
getCase/getCaseByIDstill log viaconsoleLoggergetAppealPDFDocumentstill logs and returnserror.responseon failure
- left non-targeted POST/update/create/patch flows unchanged.
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: evaluate config-based POST helpers in
caseDirectService(createNewCase,createNewCaseBlob,updateCase,updateCaseBlob) for selectiverequestJson(...)adoption while preserving existing side effects and error contracts.
CL-050: TASK22260 next slice — case direct service POST helper requestJson adoption
date: 2026-03-25
author: Cline
scope: actions/services/caseDirectService.js
type: change
rationale: Continue bounded client-layer migration by moving config-based case service POST helpers from direct axios(config) usage to shared requestJson(...) while preserving current behavior and error semantics.
impact: Reduces duplicated config-execution/response-extraction boilerplate and aligns case service write-helper internals with existing endpoint client conventions.
status: completed
Summary:
- Migrated selected case service POST helpers to
requestJson(config):createNewCasecreateNewCaseBlobupdateCaseupdateCaseBlob
- Preserved behavior contracts:
- unchanged payload/query construction and URLs
- unchanged catch-path logging via
consoleLogger - no changes to non-targeted helper logic (
getAppealID,patchCase, and already-migrated GET helpers)
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: assess
patchCaseandgetAppealIDfor migration opportunities (if/when preserving their specific behavior contracts remains straightforward).
CL-051: TASK22260 next slice — case direct service final axios dependency removal
date: 2026-03-25
author: Cline
scope: actions/services/caseDirectService.js
type: change
rationale: Complete the bounded case service migration by replacing the remaining direct axios usage (getAppealID, patchCase) with shared endpoint client reads, enabling removal of the direct axios import.
impact: Finalizes endpoint client consistency in case service and removes remaining direct axios dependency from this module without changing helper contracts.
status: completed
Summary:
- Migrated remaining direct axios-based read helpers to
getJson(...):getAppealIDpatchCase
- Preserved behavior contracts:
getAppealIDstill extracts first non-underscore key value from returned entity and logs on failurepatchCasestill swallows failure (no explicit returned error contract introduced)
- Removed now-unused
axiosimport fromcaseDirectService.
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: review other direct service modules for any remaining legacy
axiosimport usage now that case service migration is complete.
CL-052: TASK22260 next slice — portal direct service requestJson parity for config-based reads/deletes
date: 2026-03-25
author: Cline
scope: actions/services/portalDirectService.js
type: change
rationale: Continue bounded direct-service consistency by migrating remaining config-based portal helper calls from axios(config) to shared requestJson(...) where no signed-delete/header-specific behavior is required.
impact: Reduces repeated config execution/response extraction boilerplate and improves request helper consistency in portal service while preserving behavior.
status: completed
Summary:
- Migrated selected config-based helpers to
requestJson(config):deleteAwaitingSubmissionssendCaseCompleteMessagesendCaseCompleteMessageProxysendRepCompleteMessage
- Preserved behavior contracts:
- unchanged query/hash composition and request methods
- unchanged catch-path logging via
consoleLogger - left signed delete helpers with bespoke axios/header behavior unchanged (
deleteMyRepresentations,deleteWatchedCases)
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: assess whether signed-delete helpers in
portalDirectServiceshould remain explicit axios calls (for clarity on headers/hash semantics) or move to a dedicated signed-request client helper.
CL-053: Architecture documentation update — current-state assessment + prioritised roadmap
date: 2026-03-25
author: Cline
scope: context/architecture.md
type: change
rationale: User requested the architectural assessment be documented in-project so current state, residual risks, and recommended sequencing are explicitly captured for team planning.
impact: Improves documentation clarity and planning alignment; no runtime behavior changes.
status: completed
Summary:
- Added a new section to
context/architecture.md:- Current State Assessment and Prioritised Next Steps (2026-03-25)
- Documented:
- strengths (governance maturity, API/relay hardening progress, façade decomposition progress)
- residual risks/gaps (remaining direct-service inconsistency, coverage concentration, logging variance, i18n parity automation gap)
- prioritised next steps with rationale
- recommended execution sequencing (immediate/next/after)
Validation:
- Manual coherence check against existing guardrails/runbook/integration-map and memory-bank context.
Follow-ups:
- Optional: convert the prioritised steps into a sprint-ready plan (tasks, acceptance criteria, validation matrix, rollback notes).
CL-054: Branch correction — include residual duplication/axios risk slices (search + signed-delete portal flows)
date: 2026-03-25
author: Cline
scope: actions/services/{portalDirectService,searchDirectService}.js, context/architecture.md
type: change
rationale: User requested the previously identified primary remaining technical risk slices be explicitly included on this branch, specifically residual axios/duplication in search direct service and signed-delete portal helper flows.
impact: Further reduces direct-service axios boilerplate/duplication and aligns additional high-use service paths to shared endpoint client patterns while preserving existing behavior contracts.
status: completed
Summary:
- Implemented the requested risk slices on branch:
- Portal signed-delete flow parity (
portalDirectService)- migrated signed delete helpers from direct
axios({...}).then(res.data)torequestJson({...}):deleteMyRepresentationsdeleteWatchedCases
- removed now-unused
axiosimport from module - preserved hash-signing flow and custom headers semantics
- migrated signed delete helpers from direct
- Search direct service axios reduction (
searchDirectService)- migrated service GET helpers from direct
axios.get(...).then(res.data)andaxios(config)togetJson(...) - preserved existing catch semantics (
logAndReturnResponse,logAndReturnEmptyValueErrorResponse, and explicit throw path ingetSearchDocumentDetails) - removed direct
axiosimport from module
- migrated service GET helpers from direct
- Portal signed-delete flow parity (
- Documentation alignment:
- retained architecture assessment section in
context/architecture.mdthat calls out these residual-risk slices and prioritisation.
- retained architecture assessment section in
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: assess whether a dedicated signed-request client helper should encapsulate hash + headers + method conventions to prevent future drift in remaining signed flows.
CL-055: TASK22260 next slice — document direct service signed/delete axios reduction
date: 2026-03-25
author: Cline
scope: actions/services/documentDirectService.js
type: change
rationale: Execute next bounded risk-reduction slice by migrating remaining non-download document-service delete and signed-get helper calls away from direct axios response extraction to shared endpoint clients.
impact: Further reduces duplicated axios boilerplate and aligns document service internals with shared request-client conventions while preserving existing hash/query and catch-path behavior.
status: completed
Summary:
- Migrated signed hashed delete-helper flows from direct
axios({...}).then(res.data)torequestJson({...}):deleteAwaitingSubmissionsFromBlobdeleteMyRepresentationsFromBlob
- Migrated delete helper GET calls from
axios.get(...).then(res.data)togetJson(...):deleteBlobdeleteRepBlob
- Preserved behavior contracts:
- unchanged query/hash composition and endpoint URLs
- unchanged catch-path logging with
consoleLogger
- Left
downloadBlobunchanged in this slice (special-case behavior path retained for separate focused handling).
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: isolate and correct
downloadBlobbehavior indocumentDirectService(including legacyresusage) behind an explicit, tested contract.
CL-056: TASK22260 next slice — document direct service download helper contract fix
date: 2026-03-25
author: Cline
scope: actions/services/documentDirectService.js
type: change
rationale: Execute the next bounded follow-up by correcting the legacy downloadBlob service helper path that still relied on invalid res references and direct axios usage, aligning it to shared request client behavior.
impact: Fixes a service-layer contract defect risk in document download helper and improves consistency by using shared request client patterns; no endpoint contract change.
status: completed
Summary:
- Refactored
downloadBlob(containerName, blobName)indocumentDirectService:- removed legacy direct
axios.get(...).then(response => res.status(...))pattern that referenced undefinedresin service layer - now returns blob response data via
requestJson({ method: "get", url, responseType: "blob" }) - preserved catch-path logging (
consoleLogger)
- removed legacy direct
- Removed now-unused module-level
axiosimport fromdocumentDirectService.
Validation:
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded slice: add a focused test (or integration harness assertion) around
downloadBlobservice return contract to prevent regression to response-object assumptions.
CL-057: TASK22260 next slice — phase7 behavioural harness compatibility update
date: 2026-03-25
author: Cline
scope: tests/phase7/service-behaviour.test.cjs
type: change
rationale: After service-layer client migration (getJson/requestJson/buildHashedQueryUrl), phase7 behavioural harness still assumed direct axios imports only; update harness defaults so legacy behavior assertions remain executable.
impact: Restores service behavioural regression coverage (12/12) without changing production runtime code.
status: completed
Summary:
- Enhanced phase7 VM loader default injections for migrated service helpers:
- added default
getJson(...)mock delegating toaxios.get(...).then(res.data) - added default
requestJson(...)mock delegating toaxios(config).then(res.data) - added default
buildHashedQueryUrl(...)mock resolving hash via/api/endpoint/gethash_apicompatibility path
- added default
- Updated notify behavior assertions to align with shared request client usage (
requestJsoninvokes axios config-style call):- switched notify test handlers from
axios.postHandlertoaxios.requestHandler - assertions now inspect
axios.calls[0].config.{url,method,data}
- switched notify test handlers from
Validation:
node tests/phase7/service-behaviour.test.cjs-> pass (12/12)
Follow-ups:
- Optional next bounded slice: add a small shared test utility for service harness client mocks to reduce future per-file drift as façade migration continues.
CL-058: TASK22260 next slice — phase6 behavioural harness compatibility parity
date: 2026-03-25
author: Cline
scope: tests/phase6/service-behaviour.test.cjs
type: change
rationale: Keep older phase6 behavioural harness aligned with service client-wrapper migration by adding default helper injections required by getJson/requestJson-based direct services.
impact: Restores phase6 behavioural regression execution parity (8/8) with no runtime code changes.
status: completed
Summary:
- Updated
loadServiceModuledefault context intests/phase6/service-behaviour.test.cjs:- added default
getJson(...)mock backed byaxios.get(...).then(res.data) - added default
requestJson(...)mock backed byaxios(config).then(res.data)
- added default
- Preserved existing test assertions and behavior semantics; this is harness-compatibility only.
Validation:
node tests/phase6/service-behaviour.test.cjs-> pass (8/8)
Follow-ups:
- Optional consolidation: extract shared phase6/phase7 VM loader helpers into a single test utility to reduce duplication.
CL-059: TASK22260 next slice — shared service harness extraction (continued bounded risk-reduction)
date: 2026-03-25
author: Cline
scope: tests/{serviceHarness,phase6/service-behaviour,phase7/service-behaviour}.cjs
type: change
rationale: Continue the bounded risk-reduction stream by removing duplicated test harness infrastructure across phase6/phase7 service behavioural suites and centralizing client-wrapper-compatible mocks.
impact: Reduces test harness drift risk and keeps client-wrapper migration verification stable across multiple suites, without runtime code changes.
status: completed
Summary:
- Added shared helper module
tests/serviceHarness.cjswith reusable:createAxiosMockcreateLoggerMockcreateAxiosErrorloadServiceModule(with defaultgetJson/requestJson/buildHashedQueryUrlinjections)normalize
- Refactored
tests/phase6/service-behaviour.test.cjsto import shared harness utilities and remove duplicated local harness implementation. - Refactored
tests/phase7/service-behaviour.test.cjsto import shared harness utilities and remove duplicated local harness implementation.
Validation:
node tests/phase6/service-behaviour.test.cjs-> pass (8/8)node tests/phase7/service-behaviour.test.cjs-> pass (12/12)npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded risk-reduction slice: evaluate whether other legacy service test suites can adopt
tests/serviceHarness.cjsto standardize migration-era service mocking behavior.
CL-060: TASK22260 next slice — core token helper client-wrapper migration (continued bounded risk-reduction)
date: 2026-03-25
author: Cline
scope: actions/core/token.js
type: change
rationale: Include the identified remaining candidate outside actions/services and continue the bounded risk-reduction stream by removing direct axios response extraction from core token retrieval.
impact: Aligns token helper request execution with shared endpoint client conventions while preserving existing token caching and error-return behavior.
status: completed
Summary:
- Refactored
getTokeninactions/core/token.js:- replaced direct
axios.post(...).then(res => res.data)chain with sharedrequestJson({...}) - migrated function to
async/awaitwith equivalenttry/catchbehavior - retained existing semantics:
- successful token payload cached in
cache.tokenResponse - failures logged via
consoleLoggerand returned to caller
- successful token payload cached in
- replaced direct
- Removed direct
axiosdependency fromactions/core/token.jsin favor ofactions/clients/endpointClient.
Validation:
node tests/phase21/api-contract-slice1.test.cjs-> pass- helper: 4/4
- file-handler: 53/53
- email-handler: 12/12
- endpoint-handler: 164/164
- documents-handler: 3/3
npm run lint-> warnings only (pre-existingreact-hooks/exhaustive-deps; no new lint errors)
Follow-ups:
- Optional next bounded risk-reduction slice: assess whether any remaining non-service utility modules still use promise-chain axios extraction patterns and migrate them to shared clients where behavior contracts remain unchanged.