import { randomUUID } from "node:crypto"; import { access, mkdir, readFile, stat, unlink, writeFile } from "node:fs/promises"; import path from "node:path"; /** * Local-disk storage for the Media Manager (see src/services/media). * * Files live under a storage root OUTSIDE `public/` (`storage/media` by * default — `/app/storage/media` in the Docker image, matching the * `next-chair-media-data` volume in docker-compose.local.yaml). This was * previously `public/media/`, served by Next's own static file handling * — that turned out not to work: verified directly against a real * production build/container that Next.js 16's `next start` does NOT * dynamically serve files added to `public/` after the build (a * build-time-present file served 200; a file written into `public/media` * at runtime served 404, even though it existed on disk with correct * permissions). See src/app/api/media/[...path]/route.ts, the dedicated * route that now serves these files itself instead of relying on Next's * public-asset resolution. * * SVG is deliberately not in the allow-list — an uploaded SVG can embed *