import { json, type NextFunction, type Request, type RequestHandler, type Response, } from 'express'; /** The one route that accepts a large body, and how large. */ export const VOICE_EXTRACT_PATH = '/api/voice/extract'; export const VOICE_BODY_LIMIT = '10mb'; /** * JSON body parsing for the whole app. * * Voice recordings are base64 JSON and pass Express's 100 kb default at roughly 20 seconds * of audio, so that one route needs a larger limit while every other endpoint keeps the * default — a large body should not become acceptable everywhere. * * Deliberately a single middleware that *chooses* a parser, rather than a path-mounted * parser stacked in front of a default one. That arrangement relied on Express's * mount-path stripping plus body-parser skipping an already-parsed request, and it * silently stopped applying when the surrounding middleware order shifted — at which point * the endpoint rejected every real recording with a 500. One explicit branch has no such * coupling, and is covered by body-parsers.spec.ts. */ export function createJsonBodyParser(): RequestHandler { const voiceParser = json({ limit: VOICE_BODY_LIMIT }); const defaultParser = json(); return (req: Request, res: Response, next: NextFunction) => req.path === VOICE_EXTRACT_PATH ? voiceParser(req, res, next) : defaultParser(req, res, next); }