Backend: Potpisi page
Last modified with commit e90a924 on
by Aljaž.
Backend task for the Potpisi signature files (GET/POST/DELETE /btc-trainings/{trainingId}/…/signature-files, download) – check file types, size limits and delete behaviour against the API spec and DB structure, add blob storage handling, implement, and verify against the spec.
Docs: Potpisi page
Spec: GET /btc-trainings/{trainingId}/signature-files (getBtcTrainingSignatureFiles), POST /btc-trainings/{trainingId}/modules/{moduleNumber}/signature-files (uploadBtcTrainingSignatureFiles), DELETE /btc-trainings/{trainingId}/signature-files/{fileId} (deleteBtcTrainingSignatureFile), GET /btc-trainings/{trainingId}/signature-files/{fileId}/download (downloadBtcTrainingSignatureFile), BtcTrainingSignatureFile, BtcTrainingSignatureModule, BtcSignatureFileInvalid in api-docs/openapi.yaml
DB: BtcTrainingSignatureFiles, BtcTrainingModules in api/database/create_schema.sql
1. Double check API spec and DB structure
The page lists 4 module cards with their files.
getBtcTrainingSignatureFilesreturns all 4 modules, also those without files. The subtitle (školovanje name) comes fromGET /btc-trainings/{trainingId}. Confirm the frontend makes both calls, or add the name to this response.File types: the docs say “jpg, png, pdf …”. The spec allows only JPG, PNG and PDF (
file_type_not_allowed). Confirm the list (e.g. HEIC from phones?).Limits: the docs leave the max file size and file count open. The spec sets 10 MB per file and no count limit. Confirm, and check the Functions host request size limit covers several files in one upload.
“Uredi” button and delete confirmation: the docs comment recommends “Uredi” only switches the card to edit mode (frontend only) and “Odaberi datoteke” uploads immediately. Confirm; nothing in the API depends on it.
Delete (decided): a file the user removes with x is deleted permanently (row + blob). The 2-year retention rule (see BTC) doesn’t apply to it.
When a file can’t be deleted: the docs don’t say, and the spec allows deleting in any status, including Prošli.
Status rule: the spec allows uploading and deleting in any status (including Prošli, since lists are often scanned after the training). Confirm.
After the školovanje is deleted (soft), all four endpoints → 404, but the files stay in blob storage. Confirm.
Roles and permissions: list + download →
btc-trainings.access; upload + delete →btc-trainings.edit. Trainer only.DB:
FileName(original, shown) andBlobName(in containerbtc-signatures) are separate. The content type is not stored in the row; it is set on the blob at upload.
2. Implementation
- Roles and permissions: check the permission per endpoint → 403.
- Blob storage: add
btc-signaturesas a container constant inBlobStorageServiceand add aDeleteAsyncmethod (it has only Download / Exists / Upload today). Blob name e.g.{trainingId}/{moduleNumber}/{fileId}{ext}, never the user’s file name. - Multipart: functions use
HttpRequestDatatoday. Read the multipart body with the ASP.NET Core integration (ConfigureFunctionsWebApplicationis enabled, soHttpRequest/ReadFormAsynccan be used) or aMultipartReader. - Upload: validate every file first (none → 400
validation_error; type by extension and content signature → 400file_type_not_allowed; > 10 MB → 400file_too_large). Then upload the blobs (with the validated content type as the blob’sContentType) and insert the rows in one transaction. If the insert fails, delete the blobs already uploaded. Response 201 with the new files. - Store a sanitised original file name (max 255 characters, no path parts).
- Delete: the file must belong to a module of this školovanje (else 404). Delete the row, then the blob; a missing blob doesn’t fail the request. Response 204.
- Download: stream the blob with the content type from the blob’s properties and
Content-Disposition: attachmentwith the original name (RFC 5987filename*so č, š, ž survive).
3. Verify implementation against spec
- Routes, multipart field name
files, response shapes and status codes match the four operations; everyerrorinBtcSignatureFileInvalidcan be produced. - Upload 2 files to Modul 2 → both listed under module 2 only, in upload order.
- One valid file + one
.exerenamed to.pdf→ 400, nothing stored. - 11 MB file → 400
file_too_large. Downloading returns the original name with Croatian characters. - A file id from another školovanje → 404. Evaluator → 403.
Done when
A trainer can upload, download and delete signature lists per module, and the files are kept safely in blob storage.
errorcode (e.g.training_past) todeleteBtcTrainingSignatureFile, and hide the x on the Potpisi page.