Skip to content

Assessors

Audience: domain, product, backend
Status: implemented
Owns: product + backend
Depends on: Domain entities, Personas, Policies

  • Assessors are platform-vetted (QAA, IQA / IQM, EV).
  • POL-09: one assessor type per centre.
  • POL-10: EV must not be an assessor at the centre whose applications they verify.
  • Platform admin owns the assessors table UI: overview cards, enriched list (name, email, qualifications/roles, centreCount, status, createdAt; newest first), search / status filter, single + bulk approve / reject / suspend (UI activate/deactivate maps to approvedsuspended), and delete unused assessors (no assignments, retained requests, job applications, or direct-observation sessions). Sector experience is cascaded; CapUser / onboarding / OL login remain.
  • Platform cards: active = approved, pending = pending, inactive = suspended only, total = pending + approved + suspended (rejected excluded from total; still filterable in the table).
  • centreCount = count of approved retained centre relationships only.
  • Detail is read-only and global (not centre-scoped): snapshot + onboarding personalDetails (name parts, dob, gender, nationality; null if none) + workload across centres; tabs for retained centres and assigned applications (applications include a centre column).
  • Only approved assessors may use the job-posting marketplace or create retained-assessor requests (assessor.not_approved when not approved). Marketplace sector gating still applies.
  • Assessors declare sector experience (editable after onboarding) — marketplace eligibility is approved status + sector match on the posting’s trade (§27).
  • Assessors may submit retained-assessor requests to a centre (standing relationship, not tied to a job posting) with a required preferredRole (assignment-role enum: facilitator / panelist / …) — preference only, not an assignment. Approved rows are the centre’s retained roster. Centres list/detail those requests with assessor name, email, qualifications, sectors, certificates, plus preferredRole. Bulk approve/reject is pending-only.
  • Assessor console: dashboard cards (GET /assessor/summary), pending/assigned apps (GET /assessor/applications as CentreAssessorApplication), calendar (GET /assessor/events across actively assigned apps), centres table (GET /assessor/centres with distinct assignment roles[], assignedCount, joinedAt), per-centre candidates (GET /assessor/centres/{centreId}/applications), and self settings (GET/PATCH /assessor/profile — GET nests assessor onboarding).
  • Folder Arrangement (facilitator): no nested folder CRUD — UI groups Evidence Vault items by evidenceType from GET /applications/{id}/evidence; allowed catalog for the trade is GET /trades/{id}/evidence-types. Approve/reject stays POST /applications/{id}/review.
  • Job-posting marketplace: centre shortlist maps to accepted (occupies a slot); the server sets posting filled when occupancy reaches slot. Centres close postings (closed) to leave the marketplace — they do not “mark as filled”.
  • Panel and IV pickers use GET /centre/assessors (default status=approved, optional qualification=IV). The centre Assessors page uses the same list plus GET /centre/assessors/summary, GET /centre/assessors/{id} (read-only), and GET /centre/assessors/{id}/applications. Centres do not create assessor accounts. Do not send centres to GET /admin/assessors.

Admin (platform staff — assessors screens):

Method Path Use
GET /admin/assessors Paginated enriched list (AssessorAdminListItem: snapshot + assessorNo, profile status, centreCount, createdAt; default createdAt desc then id desc; filter status, q on name/email)
GET /admin/assessors/summary Cards: total / active / pending / inactive (mapping above)
GET /admin/assessors/{id} Detail + onboarding personalDetails (or null) + global workload (assigned / ongoing / completed)
PATCH /admin/assessors/{id}/approve | reject | suspend Single lifecycle transition
DELETE /admin/assessors/{id} Hard-delete unused assessor (409 assessor.in_use if assignments, retained requests, job applications, or direct-observation sessions). Cascades sector experience; keeps CapUser / onboarding / OL login
PATCH /admin/assessors/bulk { ids, status: approved | suspended | rejected } or { ids, action: "delete" } (all-or-nothing, same unused rule)
GET /admin/assessors/{id}/centres Read-only retained relationships (centreId, centreName, retained status, requestedAt)
GET /admin/assessors/{id}/applications Read-only assigned apps across centres (CentreAssessorApplication, includes centre)

Nested admin routes are read-only. Profile status is AssessorProfile.status (pending | approved | suspended | rejected) — distinct from centre retained status (pending | approved | revoked).

Assessor persona (console + marketplace):

Method Path Use
GET /assessor/summary Cards: totalCentres (approved retained), totalApplications / completedApplications / pendingApplications (workload assigned / completed / ongoing)
GET /assessor/events Cross-app ApplicationEvent calendar for actively assigned apps (same membership as /assessor/applications); cursor / limit; eventAt asc; UI filters upcoming
GET /assessor/applications Active assignments as CentreAssessorApplication (roles, assignedAt; candidate.photo; facilitator); filters q / tradeId / type / status / sort
GET /assessor/centres Enriched retained centres (centreName, roles[], assignedCount, status, joinedAt, preferredRole); q / status / sort
GET /assessor/centres/{centreId}/applications History at one centre (CentreAssessorApplication); 404 if no/rejected membership
GET /assessor/retained-requests Raw retained request list (ids + status + preferredRole)
POST /assessor/retained-requests { centreId, preferredRole } — requires approved profile
GET/POST /assessor/job-postings*, /assessor/marketplace Marketplace apply / list
GET/PATCH /assessor/profile Self settings (quals, sectors, certificates); GET nests assessor onboarding. Successful PATCH sets status pending. Personal contact/photo stay on /me/profile
GET/PUT /assessor/profile/sectors Sector experience (same pending-on-write as PATCH profile)

Centre review: GET /centre/retained-requests (+ {id}, bulk, approve/reject/revoke). Centre roster: GET /centre/assessors (+ summary/detail/applications). Writers for platform status and unused-assessor delete: platform admin / platform staff (platform.orgs.read / .approve). Centres publish and manage job postings (centre.job_posting.*).

See Scalar — CAP REST (openapi/cap.yaml, lockstep with apps/cap/openapi/openapi.yaml) and API overview.