Backend: Editing existing BTC školovanje
Last modified with commit 374306c on
by Aljaž.
Backend task for updating a BTC školovanje (POST /btc-trainings/{trainingId}) – check the status rule, candidate matching and the "candidate has data" rule against the API spec and DB structure, implement, and verify against the spec.
Docs: Editing existing BTC školovanje
Spec: POST /btc-trainings/{trainingId} (updateBtcTraining), BtcTrainingNewRequest, BtcTrainingConflict in api-docs/openapi.yaml
DB: BtcTrainings, BtcTrainingModules, BtcTrainingCandidates, BtcTrainingAttendance in api/database/create_schema.sql
The form is prefilled from GET /btc-trainings/{trainingId}
(Backend: BTC školovanje detail).
1. Double check API spec and DB structure
- Same fields and validation as create. Reuse the validation from Backend: Adding new BTC školovanje.
- Prefill: the detail response has everything the form needs (module dates, candidates with
partnerId,brandCode,hasData). Check. - Rule: only
active/upcomingcan be edited → 409training_past. - Changing dates into the past (decided: not allowed): a Modul 4 end date before today
(Europe/Zagreb) → 400
validation_error. Check the spec description ofupdateBtcTrainingsays so. Other module dates may be in the past (earlier modules have already happened). - Candidate with data: the docs say “any data (e.g. attendance)”. Attendance is the only
candidate data in the schema. Confirm, then → 409
candidate_has_data. - Candidates are matched by
id. Anidthat isn’t a candidate of this školovanje → 404. A new candidate is not present on any day (no attendance rows needed). - Modules are never added or removed; only their dates change. Attendance, Trener / Ocjena and signature files are kept.
- CTA label (“Uredi školovanje” vs “SPREMI ŠKOLOVANJE”) is frontend only.
- Response
200+BtcTrainingis enough to go back to the list with a toast. - Roles and permissions:
btc-trainings.edit, Trainer only. - DB:
UpdatedAtset on BtcTrainings, the changed modules and the changed candidates. - DB: “candidate has data” is enforced by the FK from BtcTrainingAttendance: deleting
such a candidate fails with 547.
UQ_BtcTrainingCandidates_Slotcaps candidates at 20.
2. Implementation
- Roles and permissions: require
btc-trainings.edit→ 403. - DB: in one transaction (several writes): check status (
past→ 409); delete removed candidates with oneDELETE … WHERE TrainingId = @id AND Id NOT IN (…)(no check first: FK error 547 → roll back, 409candidate_has_data); update BtcTrainings; update the 4 module rows byModuleNumber; update existing candidates; insert new ones with the lowest freeSlot. Commit only when every statement succeeds. Unique violation onSlot(another edit at the same time) → roll back and run the whole edit again once, in a new transaction; same failure again → 500. - Unknown / deleted školovanje → 404. Validation → 400, including a Modul 4 end date before
today. Conflicts → 409 with the
errorcode. Nothing is saved when any check fails. - Response 200 with the recalculated
BtcTraining.
3. Verify implementation against spec
- Route, request and response match
updateBtcTraining; 409 codes matchBtcTrainingConflict. - Modul 4 end date yesterday → 400; today → saved and still
active. Modul 1 end date in the past → saved. - Past školovanje → 409
training_past. Removing a candidate with attendance → 409candidate_has_data. Removing one without attendance → removed. - Adding a candidate → appears in every module’s attendance with
day1/day2false. - Attendance and signature files are unchanged after an edit. Evaluator → 403.
Done when
A trainer can edit an active or upcoming školovanje, without losing attendance or files.