4.6 KiB
Class Subjects Backend
Purpose
class_subjects is the per-organization join between classes and subjects — it represents a
subject taught in a class, optionally assigned to a teacher (staff). It is a generic-CRUD slice
assembled from the shared factories; the backend is the source of truth for these assignments.
Slice Files (by layer)
- Route:
src/routes/class_subjects.ts—createCrudRouter(controller, { permission: 'class_subjects' }). - Controller:
src/api/controllers/class_subjects.controller.ts—createCrudController(service, { csvFields }). - Service (BLL):
src/services/class_subjects.ts—createCrudService(DbApi, { notFoundCode: 'class_subjectsNotFound' }). - Repository (DAL):
src/db/api/class_subjects.ts(Class_subjectsDBApi) — entity-specificcreate/bulkImport/update/findBy/findAll;remove/deleteByIds/findAllAutocompletedelegate todb/api/shared/repository.ts. - Model:
src/db/models/class_subjects.ts. - Shared used: CRUD factories (
services/shared/crud-service.ts,api/controllers/shared/crud-controller.ts,api/http/crud-router.ts), repository helpers (db/api/shared/repository.ts),shared/constants/pagination.ts(resolvePagination),shared/constants/database.ts(BULK_IMPORT_TIMESTAMP_STEP_MS),db/utils.ts(Utils).
API
The standard generic-CRUD surface (all under /api/class_subjects, JWT +
${METHOD}_CLASS_SUBJECTS permission, all 200) — see backend-architecture.md for the shared
contract:
POST /— body{ data }, returnstrue.POST /bulk-import— multipart CSV file, returnstrue.PUT /:id— body{ data, id }(the service reads the id from the body), returnstrue.DELETE /:id— returnstrue.POST /deleteByIds— body{ data: string[] }, returnstrue.GET /— query filters, returns{ rows, count };?filetype=csvstreams a CSV ofcsvFields.GET /count— returns{ rows: [], count }.GET /autocomplete—?query&limit&offset, returns[{ id, label }]wherelabelisstatus(the field passed toautocompleteByField).GET /:id— returns the record with eager associations (see Data Contract).
csvFields: id.
Access Rules
- JWT required; the whole router is guarded by
checkCrudPermissions('class_subjects'), derivingREAD_CLASS_SUBJECTS/CREATE_CLASS_SUBJECTS/UPDATE_CLASS_SUBJECTS/DELETE_CLASS_SUBJECTSper HTTP method. - Access is granted by role permission or per-user
custom_permissions(seepermissions.md).
Tenant Scope
findAllscopeswhere.organizationIdtocurrentUser.organizationId; aglobalAccessrole clears the org filter (sees all tenants).createassigns the organization fromcurrentUser.organizationId;updateonly reassigns organization forglobalAccessusers (otherwise it stays the caller's org).
Data Contract
Model columns (paranoid, soft-delete via deletedAt):
id(UUID PK).status— ENUMactive|archived.importHash(unique),organizationId,classId,subjectId,teacherId,createdById,updatedById, timestamps.
Associations: belongsTo organization, class (classes), subject (subjects), teacher (staff),
createdBy/updatedBy (users); hasMany timetable_periods_class_subject,
attendance_sessions_class_subject, assessments_class_subject. findBy/GET /:id eager-load
timetable_periods_class_subject, attendance_sessions_class_subject, assessments_class_subject,
organization, class, subject and teacher in a single Promise.all (the class association is
exposed on the output as class).
List filters (ClassSubjectsFilter): id, class (id or name, |-separated), subject (id or
name, |-separated), teacher (id or employee_number, |-separated), status,
organization, createdAtRange, plus field/sort ordering and limit/page pagination.
Behavior / Notes
create/updatewire the organization, class, subject and teacher relations via theset*association mixins;bulkImportdoes not set these relations.bulkImportoffsetscreatedAtper row byBULK_IMPORT_TIMESTAMP_STEP_MSto preserve order.- List pagination uses the shared
resolvePaginationdefaults (page size 10, capped at 100). - Note:
ClassSubjectsFilteraccepts anactiveflag the model has no column for; it is currently inert (kept for source accuracy). - Note: only
idis incsvFields, so the CSV export emits just the id column.
Tests
None yet.
Related
- Generic-CRUD contract:
backend-architecture.md; related slices:classes,subjects,staff,timetable_periods,attendance_sessions,assessments,permissions.md.