Committed by Hermes autonomous QA sprint 2026-08-13. These files were modified during the Aug 12 sprint but never committed.
133 lines
4.0 KiB
JavaScript
133 lines
4.0 KiB
JavaScript
/**
|
|
* Response helpers - Standard API response formats
|
|
*
|
|
* Single source of truth for HTTP response shapes across DashCaddy.
|
|
* Standard envelope: { success: true, ...data } or { success: false, error: "..." }.
|
|
*
|
|
* All routes should import from this module — do not call res.json/res.status
|
|
* directly with the response shape, use these helpers instead.
|
|
*/
|
|
const { HTTP_STATUS } = require('../utilities/constants');
|
|
|
|
// ── Success helpers ────────────────────────────────────────────
|
|
|
|
/**
|
|
* Standard success response. Use this in route handlers.
|
|
* Wraps the data object with a `success: true` envelope.
|
|
* @param {object} res Express response
|
|
* @param {object} [data={}] fields to include in the response body
|
|
* @param {number} [statusCode=200] HTTP status code
|
|
*/
|
|
function ok(res, data = {}, statusCode = HTTP_STATUS.OK) {
|
|
return res.status(statusCode).json({ success: true, ...data });
|
|
}
|
|
|
|
/**
|
|
* Alias for `ok` — prefer `ok` in new code, but kept for code that imports as `success`.
|
|
*/
|
|
function success(res, data, statusCode) {
|
|
return ok(res, data, statusCode);
|
|
}
|
|
|
|
/**
|
|
* Success response with a human-readable message field.
|
|
* Use when there's no data to return, just confirmation.
|
|
*/
|
|
function successMessage(res, message, statusCode = HTTP_STATUS.OK) {
|
|
return res.status(statusCode).json({ success: true, message });
|
|
}
|
|
|
|
/**
|
|
* 201 Created response.
|
|
*/
|
|
function created(res, data = {}) {
|
|
return res.status(HTTP_STATUS.CREATED).json({ success: true, ...data });
|
|
}
|
|
|
|
/**
|
|
* 204 No Content response.
|
|
*/
|
|
function noContent(res) {
|
|
return res.status(HTTP_STATUS.NO_CONTENT).send();
|
|
}
|
|
|
|
// ── Error helpers ──────────────────────────────────────────────
|
|
|
|
/**
|
|
* Standard error response. Use this in route handlers.
|
|
* @param {object} res Express response
|
|
* @param {number} statusCode HTTP status code
|
|
* @param {string} message Human-readable error message
|
|
* @param {object} [extras={}] additional fields to merge into the response
|
|
*
|
|
* DC-086: If extras.code is set, it's treated as a machine-readable error code
|
|
* (e.g. 'DC-CONT-002'). If message looks like a DC code, it's auto-extracted.
|
|
*/
|
|
function errorResponse(res, statusCode, message, extras = {}) {
|
|
const body = { success: false, error: message, ...extras };
|
|
// DC-086: surface machine-readable code at top level for client handling
|
|
if (extras.code) {
|
|
body.code = extras.code;
|
|
}
|
|
return res.status(statusCode).json(body);
|
|
}
|
|
|
|
/**
|
|
* Alias for `errorResponse` — kept for code that imports as `error`.
|
|
*/
|
|
function error(res, message, statusCode = HTTP_STATUS.INTERNAL_ERROR) {
|
|
return res.status(statusCode).json({ success: false, error: message });
|
|
}
|
|
|
|
/**
|
|
* 400 Bad Request — invalid input from the user.
|
|
*/
|
|
function validationError(res, message) {
|
|
return res.status(HTTP_STATUS.BAD_REQUEST).json({ success: false, error: message });
|
|
}
|
|
|
|
/**
|
|
* 401 Unauthorized — no valid credentials.
|
|
*/
|
|
function unauthorized(res, message = 'Unauthorized') {
|
|
return res.status(HTTP_STATUS.UNAUTHORIZED).json({ success: false, error: message });
|
|
}
|
|
|
|
/**
|
|
* 403 Forbidden — credentials valid but permission denied.
|
|
*/
|
|
function forbidden(res, message = 'Forbidden') {
|
|
return res.status(HTTP_STATUS.FORBIDDEN).json({ success: false, error: message });
|
|
}
|
|
|
|
/**
|
|
* 404 Not Found — resource doesn't exist.
|
|
*/
|
|
function notFound(res, message = 'Not found') {
|
|
return res.status(HTTP_STATUS.NOT_FOUND).json({ success: false, error: message });
|
|
}
|
|
|
|
/**
|
|
* 409 Conflict — request conflicts with current state (e.g. duplicate).
|
|
*/
|
|
function conflict(res, message) {
|
|
return res.status(HTTP_STATUS.CONFLICT).json({ success: false, error: message });
|
|
}
|
|
|
|
module.exports = {
|
|
// Success helpers
|
|
ok,
|
|
success,
|
|
successMessage,
|
|
created,
|
|
noContent,
|
|
// Error helpers
|
|
errorResponse,
|
|
error,
|
|
validationError,
|
|
unauthorized,
|
|
forbidden,
|
|
notFound,
|
|
conflict,
|
|
};
|