Backend: Adding new assessment
Last modified with commit e90a924 on
by Aljaž.
Backend task for creating an assessment (POST /assessments) – check the API spec and DB structure, set up roles, permissions, tables and lookups, implement, and verify against the spec.
Docs: Adding new assessment
Spec: POST /assessments (createAssessment), AssessmentNewRequest, Assessment in api-docs/openapi.yaml
DB: Assessments, AssessmentCandidates, AssessmentBoardMembers in api/database/create_schema.sql
This is the first assessment endpoint, so it also includes the shared setup: roles, permissions, tables and the Komisija / Partner lookups.
1. Double check API spec and DB structure
- Every docs field is in
AssessmentNewRequest, with the right required/optional setting: Marka (multiselect →brandCodes), Partner, Naziv, Datum, the “Igra uloga – argumentacija” checkbox, candidates (Ime i prezime required, E-mail optional), Komisija. - Limits: 1–5 candidates, 1–10 board members. Check that
minItems/maxItemsare in both the spec and the docs. - Naziv is autofilled from the partner. Is the year appended (“Auto Zubak 2026”)? This is an
open question in the docs and only affects the frontend, as long as
namestays free text. - Default activities: the docs say they are created on save. The schema has no activity rows (activities are fixed in code). Make sure the spec says this.
- Is
201+Assessmentenough for the next step (back to the list with a toast)? - Each DB column has a request field or a value set by the server (
CreatedBy,CreatedAt). Decide whetherCreatedBystores the user id or the display name; the spec example is a name. - Column types match the spec:
BrandCodes VARCHAR(6)vs^[SACVUL]{1,6}$;Email NVARCHAR(255) NULL. - DB constraints: the maximums are capped in the schema by
Slot:UQ_AssessmentCandidates_Slot(1–5) andUX_AssessmentBoardMembers_Slot(1–10, active members only). One row per user per assessment is guaranteed byUQ_AssessmentBoardMembers_User. The minimums (1 candidate, 1 member) are checked in code only.Slotis not the display order (that’sCreatedAt). - Roles and permissions: the spec uses
assessments.edithere. Neither theassessments.*permissions nor the Trainer / Assessment evaluator roles exist inapi/Authorization/Permissions.cs/RoleCode.cs. Confirm the role → permission mapping (expected: Trainer gets allassessments.*, Assessment evaluator onlyassessments.access) and whether Admin gets them too. - Komisija lookup: each dropdown option is “Ime i prezime – E-mail – Role”, limited to
Trainer and Assessment evaluator users. The spec has no endpoint for this and
api/has no users integration, yetAssessmentBoardMembers.FullNamesays it is “copied from the users API”. Decide the source and add an endpoint to the spec if the backend serves it. - Partner lookup: the docs say Partner is a dropdown and Naziv is autofilled with the
partner’s name. Today
partnerIdis a free-text field (events/invitees), and there is no partner lookup. Decide where the list and the names come from.
2. Implementation
- Roles and permissions: add
TrainerandAssessmentEvaluatortoRoleCode(codes, plus theGetRolescatalog). Add the fourassessments.*constants toPermissions.csand map them to roles. - DB: apply the
-- ASSESSMENTS --section ofcreate_schema.sql(plus a migration script for existing environments, if used). Add the status helper:active/upcoming/pastfromDate, using today’s date in Europe/Zagreb. - Lookups: if the backend serves them, add the Komisija users endpoint (user id, full name, e-mail, role) and the partner list, and a service that resolves a user id to a full name.
- Function + repository. Insert the assessment, candidates and board members in one
transaction (several writes). Candidates get
Slot1…n and board members 1…m, in request order. - Validation → 400: required fields;
brandCodesmatches the pattern with no duplicate letters; candidate and board member limits; no duplicateboardMemberUserIds; every board member has the Trainer or Assessment evaluator role. - Board member
FullNamecomes from the users source. - Requires
assessments.edit→ 403. Response 201 withAssessment(calculatedstatus,candidatesCount).
3. Verify implementation against spec
- Route, method, request and response shapes match
createAssessment. - 400 / 401 / 403 / 500 cases can be produced; no undocumented status codes.
- Evaluator token → 403. Six candidates → 400. Duplicate board member → 400.
-
GET /me/permissionsreturns the expected set for a Trainer and for an Assessment evaluator. Permission names inPermissions.csmatch thePermissionNameenum inopenapi.yaml. - Any new lookup endpoints are in
openapi.yaml.
Done when
A trainer can create an assessment that then shows up on the list and on the detail page.