src/api/v2/projects/projectfiles/projectfiles.routes.tsmodifiedimport express from "express";
import {singleUpload} from "../../../../middleware/storage";
import {
validateBiggestFileRequest,
validateFileUploadRequest,
validateGetFileRequest,
} from "./projectfiles.validator";
import {
getFiles,
getFile,
getBiggestFile,
uploadFile,
} from "./projectfiles.controller";
import { hasRolesOrProjectAccess } from "../../../../middleware/authorisation";
import { Authorities } from "../../../auth/authorities.types";
const router = express.Router({ mergeParams: true });
/**
* @swagger
* /api/v2/projects/{projectId}/files:
* get:
* summary: List all files for a project
* tags: [Files]
* description: Returns metadata for all files uploaded to the specified project, ordered by most recently inserted first.
* parameters:
* - in: path
* name: projectId
* required: true
* schema:
* type: string
* format: uuid
* description: The project ID
* responses:
* 200:
* description: List of project files
* content:
* application/json:
* schema:
* type: array
* items:
* type: object
* properties:
* fileReferenceId:
* type: string
* format: uuid
* fileName:
* type: string
* fileExtension:
* type: string
* xyzDisplayName:
* type: string
* fileSizeBytes:
* type: number
* fileHash:
* type: string
* description: SHA-256 hash of the file content
* createdBy:
* type: string
* insertedOn:
* type: string
* format: date-time
* lastModifiedBy:
* type: string
* lastModifiedOn:
* type: string
* format: date-time
* 400:
* description: Bad request
* 401:
* description: Unauthorized
* 403:
* description: Forbidden
* 500:
* description: Server error
*/
router.get(
"/",
hasRolesOrProjectAccess([], [Authorities.IMAGE_VIEW]),
getFiles,
);
/**
* @swagger
* /api/v2/projects/{projectId}/files/biggest:
* get:
* summary: Get the largest file in a project
* tags: [Files]
* description: Returns the full metadata for the largest non-soft-deleted file (by FileSizeBytes) in the specified project. Returns 200 with a null body when the project has no files, and 404 when the project does not exist.
* parameters:
* - in: path
* name: projectId
* required: true
* schema:
* type: string
* format: uuid
* description: The project ID
* responses:
* 200:
* description: The largest file's metadata, or null when the project has no files
* content:
* application/json:
* schema:
* nullable: true
* type: object
* properties:
* fileReferenceId:
* type: string
* format: uuid
* fileName:
* type: string
* fileExtension:
* type: string
* xyzDisplayName:
* type: string
* fileSizeBytes:
* type: number
* fileHash:
* type: string
* description: SHA-256 hash of the file content
* createdBy:
* type: string
* insertedOn:
* type: string
* format: date-time
* lastModifiedBy:
* type: string
* lastModifiedOn:
* type: string
* format: date-time
* 400:
* description: Bad request
* 401:
* description: Unauthorized
* 403:
* description: Forbidden
* 404:
* description: Project not found
* 500:
* description: Server error
*/
router.get(
"/biggest",
validateBiggestFileRequest,
hasRolesOrProjectAccess([], [Authorities.IMAGE_VIEW]),
getBiggestFile,
);
/**
* @swagger
* /api/v2/projects/{projectId}/files/{fileReferenceId}:
* get:
* summary: Get details of a specific project file
* tags: [Files]
* description: Returns file details and a signed blob download URL for the specified file reference.
* parameters:
* - in: path
* name: projectId
* required: true
* schema:
* type: string
* format: uuid
* description: The project ID
* - in: path
* name: fileReferenceId
* required: true
* schema:
* type: string
* format: uuid
* description: The file reference ID returned from the upload endpoint
* responses:
* 200:
* description: File details retrieved successfully
* content:
* application/json:
* schema:
* type: object
* properties:
* fileReferenceId:
* type: string
* format: uuid
* fileName:
* type: string
* fileExtension:
* type: string
* xyzDisplayName:
* type: string
* fileSizeBytes:
* type: number
* fileHash:
* type: string
* description: SHA-256 hash of the file content
* createdBy:
* type: string
* insertedOn:
* type: string
* format: date-time
* lastModifiedBy:
* type: string
* lastModifiedOn:
* type: string
* format: date-time
* downloadUrl:
* type: string
* description: Signed blob download URL
* 400:
* description: Bad request
* 401:
* description: Unauthorized
* 403:
* description: Forbidden
* 404:
* description: File not found
* 500:
* description: Server error
*/
router.get(
"/:fileReferenceId",
validateGetFileRequest,
hasRolesOrProjectAccess([], [Authorities.IMAGE_VIEW]),
getFile,
);
/**
* @swagger
* /api/v2/projects/{projectId}/files:
* post:
* summary: Upload a file to a project
* tags: [Files]
* description: Uploads any file type (image, video, document, etc.) to Azure Blob Storage and records it in the database. Supports chunked upload for large files. On the first chunk (chunkIndex=0) a fileReferenceId is returned and must be supplied for subsequent chunks.
* parameters:
* - in: path
* name: projectId
* required: true
* schema:
* type: string
* format: uuid
* description: The project ID
* requestBody:
* required: true
* content:
* multipart/form-data:
* schema:
* type: object
* required:
* - file
* - fileName
* - xyzDisplayName
* - chunkIndex
* - totalChunks
* properties:
* file:
* type: string
* format: binary
* description: The file chunk to upload
* fileName:
* type: string
* description: Original file name including extension
* xyzDisplayName:
* type: string
* description: Display name shown in the XYZ platform
* chunkIndex:
* type: string
* description: Zero-based index of the current chunk
* totalChunks:
* type: string
* description: Total number of chunks for this upload
* fileReferenceId:
* type: string
* format: uuid
* description: Required for chunks after the first (returned from the first chunk response)
* responses:
* 200:
* description: Chunk uploaded successfully (more chunks expected)
* content:
* application/json:
* schema:
* type: object
* properties:
* fileReferenceId:
* type: string
* format: uuid
* message:
* type: string
* 201:
* description: File upload complete
* content:
* application/json:
* schema:
* type: object
* properties:
* fileReferenceId:
* type: string
* format: uuid
* message:
* type: string
* 400:
* description: Bad request
* 401:
* description: Unauthorized
* 403:
* description: Forbidden
* 500:
* description: Server error
*/
router.post(
"/",
...singleUpload("file"),
validateFileUploadRequest,
hasRolesOrProjectAccess([], [Authorities.IMAGE_UPLOAD]),
uploadFile,
);
export default router;