Files
nick-doc/03 - API Reference/File API.md
2026-05-23 20:35:34 +03:30

112 lines
4.1 KiB
Markdown

---
title: File API
tags: [api, file, reference]
---
# File API
Endpoints live under `/api/files/*`. The router is [`backend/src/services/file/fileRoutes.ts`](../../backend/src/services/file/fileRoutes.ts), delegating to `fileController` and `fileService`. Multer is used for multipart parsing and uploaded files are written under `uploads/<subfolder>`.
All endpoints require `Bearer JWT`. Static serving is wired in `app.ts` at `/uploads/*` with `helmet({ crossOriginResourcePolicy: { policy: "cross-origin" } })` so files can be embedded from the frontend domain.
## Multer configuration
`fileService.getUploadMiddleware(options)` produces a Multer instance per route. Options:
- `subfolder` - where the file lands under `uploads/`
- `fieldName` - form field name
- `fileTypes` - allowed MIME types (default: any)
- `maxFiles` - default 1
- `maxFileSizeMB` - default 10 MB
Global body limits in `app.ts` are `10mb` for `express.json` and `express.urlencoded`.
## Upload
### POST /api/files/upload/avatar
**Description:** Upload an avatar image. Lands in `uploads/temp/` and is then moved when the user persists it on their profile.
**Auth required:** Bearer JWT
**Form fields:** `avatar` (image; JPEG / PNG / GIF / WebP)
**Response 200:**
```json
{
"success": true,
"data": {
"url": "/uploads/temp/avatar-1716459200000.jpg",
"filename": "avatar-1716459200000.jpg",
"mimeType": "image/jpeg",
"size": 51234
}
}
```
**Errors:** `400` bad type / too large, `401` not authenticated.
**Side effects:** None — caller is responsible for `PUT /api/user/profile` to persist the URL.
### POST /api/files/upload/file
**Description:** Generic single-file upload (any MIME), lands in `uploads/temp/`.
**Auth required:** Bearer JWT
**Form fields:** `file`
**Response 200:** `{ success, data: { url, filename, mimeType, size } }`
### POST /api/files/upload/files
**Description:** Multi-file upload (up to 5).
**Auth required:** Bearer JWT
**Form fields:** `files` (repeated)
**Response 200:** `{ success, data: { files: [{ url, filename, ... }] } }`
### POST /api/files/upload/request-template-images
**Description:** Up to 10 images for a [[RequestTemplate]]. Lands in `uploads/request-templates/`.
**Auth required:** Bearer JWT
**Form fields:** `images` (repeated; JPEG / PNG / GIF / WebP)
**Response 200:** `{ success, data: { files: [...] } }`
### POST /api/files/upload/blog-images
**Description:** Up to 10 images for a [[BlogPost]]. Lands in `uploads/blog/`.
**Auth required:** Bearer JWT
**Form fields:** `images` (repeated; JPEG / PNG / GIF / WebP)
**Response 200:** `{ success, data: { files: [...] } }`
## Delete
### DELETE /api/files/delete
**Description:** Delete a file by relative path.
**Auth required:** Bearer JWT
**Request body:** `{ filePath: string }` (e.g. `"temp/avatar-1716459200000.jpg"`)
**Response 200:** `{ success, message: "File deleted" }`
**Errors:** `400` invalid path (must stay inside `uploads/`), `404` file missing.
## Inspect
### GET /api/files/info/:filePath
**Description:** Returns metadata for a file (URL-encoded `filePath` segment).
**Auth required:** Bearer JWT
**Response 200:** `{ success, data: { url, size, mimeType, createdAt } }`
### GET /api/files/stats
**Description:** Aggregate upload statistics (counts and sizes per subfolder).
**Auth required:** Bearer JWT (admin gating planned per TODO in source)
**Response 200:** `{ success, data: { subfolders: [{ name, count, sizeBytes }], total: { count, sizeBytes } } }`
## Serving
- `GET /uploads/<path>` - static file delivery (no auth, public read). Suitable for embedding avatars and blog/template images.
- The server logs `❌ File not found:` for missing paths and `✅ Serving file:` on hits — useful when debugging frontend image refs.
The on-disk root resolves from `config.uploadPath`. In production this defaults to `/app/uploads`; in development to `<repo>/uploads`. Both are normalised to an absolute path before being passed to `express.static`.
## Related
- [[File Storage Architecture]]
- [[User API]] (avatar consumer)
- [[Marketplace API]] (template image consumer)
- [[Blog API]] (blog image consumer)
- [[Chat API]] (message attachments use a separate multipart route under chat)