From 3cbd876b779ba32664b958c3c857ce45d4d96f6b Mon Sep 17 00:00:00 2001 From: robbond Date: Tue, 17 Mar 2026 12:58:20 +0000 Subject: [PATCH] TASK22102: slice3 migrate file proxy handlers --- memory-bank/change-log.md | 32 +++++++++++++++++++ .../createappealcompletemessageproxy_api.js | 15 +++++++-- .../getawaitingsubmissionfromblobproxy.js | 15 +++++++-- pages/api/file/getbloblistproxy.js | 15 +++++++-- pages/api/file/getrepsblobproxy.js | 15 +++++++-- 5 files changed, 80 insertions(+), 12 deletions(-) diff --git a/memory-bank/change-log.md b/memory-bank/change-log.md index b3268476..a96091d1 100644 --- a/memory-bank/change-log.md +++ b/memory-bank/change-log.md @@ -1371,3 +1371,35 @@ Validation: Follow-ups: - Next slice can target selected file handlers for equivalent response contract cleanup. + +--- + +### CL-037: TASK22102 API contract consistency — Slice 3 (file proxy handlers) + +date: 2026-03-17 +author: Cline +scope: `pages/api/file/{getbloblistproxy,getrepsblobproxy,getawaitingsubmissionfromblobproxy,createappealcompletemessageproxy_api}.js` +type: change +rationale: Extend contract consistency into selected proxy file handlers by replacing raw error passthrough and empty 400s with standardized structured responses. +impact: Improves API error contract clarity for selected file proxy routes while preserving success payload pass-through behavior. +status: completed + +Summary: + +- Migrated selected file proxy handlers to shared response helper usage: + - `getbloblistproxy` + - `getrepsblobproxy` + - `getawaitingsubmissionfromblobproxy` + - `createappealcompletemessageproxy_api` +- Replaced direct `res.status(...).json(...)` handling with: + - `respondSuccess(...)` + - `respondError(...)` +- Added explicit structured 400 responses for missing required query values and proxy fetch failures. + +Validation: + +- `npx next lint --file pages/api/file/getbloblistproxy.js --file pages/api/file/getrepsblobproxy.js --file pages/api/file/getawaitingsubmissionfromblobproxy.js --file pages/api/file/createappealcompletemessageproxy_api.js` -> pass (no warnings/errors) + +Follow-ups: + +- Next slice should target non-proxy file handlers that still return raw `error` payloads. diff --git a/pages/api/file/createappealcompletemessageproxy_api.js b/pages/api/file/createappealcompletemessageproxy_api.js index 5ebbdb6c..b495040c 100644 --- a/pages/api/file/createappealcompletemessageproxy_api.js +++ b/pages/api/file/createappealcompletemessageproxy_api.js @@ -3,6 +3,7 @@ import { getToken } from "../../../actions/core/token"; import { azureHeaders } from "../../../actions/core/headers"; import { consoleLogger } from "../../../actions/core/logger"; import axios from "axios"; +import { respondError, respondSuccess } from "../middleware/apiResponse"; import nextConnect from "next-connect"; import middleware from "../middleware/middleware"; @@ -20,7 +21,11 @@ ApiProxy.get(async (req, res) => { var tempCaseRef = req.query.tempcaseref; if (!hasValue(containerName) || !hasValue(tempCaseRef)) { - return res.status(400).json(); + return respondError(res, { + status: 400, + code: "MISSING_REQUIRED_QUERY", + message: "container and tempcaseref are required" + }); } var token = await getToken(); @@ -37,11 +42,15 @@ ApiProxy.get(async (req, res) => { azureHeaders(token.access_token) ) .then(({ data }) => { - res.status(200).json(data); + return respondSuccess(res, data); }) .catch((error) => { consoleLogger(error); - res.status(400).json(error); + return respondError(res, { + status: 400, + code: "CREATE_APPEAL_COMPLETE_MESSAGE_PROXY_FAILED", + message: "Failed to create appeal complete message" + }); }); }); diff --git a/pages/api/file/getawaitingsubmissionfromblobproxy.js b/pages/api/file/getawaitingsubmissionfromblobproxy.js index 6f8e3ef7..f04a2198 100644 --- a/pages/api/file/getawaitingsubmissionfromblobproxy.js +++ b/pages/api/file/getawaitingsubmissionfromblobproxy.js @@ -3,6 +3,7 @@ import { azureHeaders } from "../../../actions/core/headers"; import { consoleLogger } from "../../../actions/core/logger"; import { hashAPIPath } from "../../../actions/core/hash"; import axios from "axios"; +import { respondError, respondSuccess } from "../middleware/apiResponse"; const BASE_URL = process.env.API_ROOT || `http://localhost:${port}`; @@ -13,7 +14,11 @@ export default async function ApiProxy(req, res) { var containerName = req.query.container; if (!hasValue(containerName)) { - return res.status(400).json(); + return respondError(res, { + status: 400, + code: "MISSING_REQUIRED_QUERY", + message: "container is required" + }); } var token = await getToken(); @@ -27,10 +32,14 @@ export default async function ApiProxy(req, res) { azureHeaders(token.access_token) ) .then(({ data }) => { - res.status(200).json(data); + return respondSuccess(res, data); }) .catch((error) => { consoleLogger(error); - res.status(400).json(error); + return respondError(res, { + status: 400, + code: "GET_AWAITING_SUBMISSION_PROXY_FAILED", + message: "Failed to fetch awaiting submission blob" + }); }); } diff --git a/pages/api/file/getbloblistproxy.js b/pages/api/file/getbloblistproxy.js index 10a7b958..c6771fca 100644 --- a/pages/api/file/getbloblistproxy.js +++ b/pages/api/file/getbloblistproxy.js @@ -3,6 +3,7 @@ import { azureHeaders } from "../../../actions/core/headers"; import { consoleLogger } from "../../../actions/core/logger"; import { hashAPIPath } from "../../../actions/core/hash"; import axios from "axios"; +import { respondError, respondSuccess } from "../middleware/apiResponse"; const BASE_URL = process.env.API_ROOT || `http://localhost:${port}`; @@ -14,7 +15,11 @@ export default async function ApiProxy(req, res) { var casefolderID = req.query.casefolderID; if (!hasValue(containerName) || !hasValue(casefolderID)) { - return res.status(400).json(); + return respondError(res, { + status: 400, + code: "MISSING_REQUIRED_QUERY", + message: "container and casefolderID are required" + }); } var token = await getToken(); @@ -31,10 +36,14 @@ export default async function ApiProxy(req, res) { azureHeaders(token.access_token) ) .then(({ data }) => { - res.status(200).json(data); + return respondSuccess(res, data); }) .catch((error) => { consoleLogger(error); - res.status(400).json(error); + return respondError(res, { + status: 400, + code: "GET_BLOB_LIST_PROXY_FAILED", + message: "Failed to fetch blob list" + }); }); } diff --git a/pages/api/file/getrepsblobproxy.js b/pages/api/file/getrepsblobproxy.js index 3a0bb850..36383f1a 100644 --- a/pages/api/file/getrepsblobproxy.js +++ b/pages/api/file/getrepsblobproxy.js @@ -3,6 +3,7 @@ import { azureHeaders } from "../../../actions/core/headers"; import { consoleLogger } from "../../../actions/core/logger"; import { hashAPIPath } from "../../../actions/core/hash"; import axios from "axios"; +import { respondError, respondSuccess } from "../middleware/apiResponse"; const BASE_URL = process.env.API_ROOT || `http://localhost:${port}`; @@ -13,7 +14,11 @@ export default async function ApiProxy(req, res) { var containerName = req.query.container; if (!hasValue(containerName)) { - return res.status(400).json(); + return respondError(res, { + status: 400, + code: "MISSING_REQUIRED_QUERY", + message: "container is required" + }); } var token = await getToken(); @@ -26,10 +31,14 @@ export default async function ApiProxy(req, res) { azureHeaders(token.access_token) ) .then(({ data }) => { - res.status(200).json(data); + return respondSuccess(res, data); }) .catch((error) => { consoleLogger(error); - res.status(400).json(error); + return respondError(res, { + status: 400, + code: "GET_REPS_BLOB_PROXY_FAILED", + message: "Failed to fetch representation blobs" + }); }); }