feat(api): add multipart file upload, workspace management, and download routes

- Register @fastify/multipart plugin with size limits from env config
- Workspace manager: createWorkspace, getWorkspacePath, cleanupWorkspace
- File validation: magic byte detection, format check, megapixel limit
- POST /api/v1/upload: multipart upload with validation, returns jobId + file metadata
- GET /api/v1/download/:jobId/:filename: serve files with Content-Disposition
- Path traversal guards on all file-serving endpoints
- Add @stirling-image/image-engine and sharp as API dependencies
- Add apiUpload, getDownloadUrl, apiDownloadBlob to web client
This commit is contained in:
Siddharth Kumar Sah
2026-03-22 03:47:54 +08:00
parent ccac5b885c
commit ece341e8c4
8 changed files with 957 additions and 0 deletions
+29
View File
@@ -0,0 +1,29 @@
import { mkdir, rm } from "node:fs/promises";
import { join } from "node:path";
import { env } from "../config.js";
/**
* Create a workspace directory structure for a processing job.
* Returns the workspace root path.
*/
export async function createWorkspace(jobId: string): Promise<string> {
const root = getWorkspacePath(jobId);
await mkdir(join(root, "input"), { recursive: true });
await mkdir(join(root, "output"), { recursive: true });
return root;
}
/**
* Get the workspace root path for a job.
*/
export function getWorkspacePath(jobId: string): string {
return join(env.WORKSPACE_PATH, jobId);
}
/**
* Remove the entire workspace directory for a job.
*/
export async function cleanupWorkspace(jobId: string): Promise<void> {
const root = getWorkspacePath(jobId);
await rm(root, { recursive: true, force: true });
}