Architecture
This page describes the current implementation architecture of the ILS application in ILS-dev.
It is grounded in the actual source files and route mounting behavior of the backend and the frontend.
System overview
The ILS application is split into two repositories:
ILS-dev/backend— Node.js + Express backend with Sequelize model loading and JSON APIsILS-dev/frontend— React 18 + Vite frontend with an admin-style SPA and teacher intelligence pages
The architecture is API-first and modular: the backend exposes /api/* JSON endpoints, and the frontend consumes those endpoints through a shared API client.
Architecture at a glance
| Layer | Components | Role |
|---|---|---|
| Backend | Node.js, Express, Sequelize, PostgreSQL | Data storage, API routing, model associations, grading and reporting logic |
| Frontend | React 18, Vite, Tailwind CSS | Admin UI, teacher cockpit, heatmap, and forms |
| Data model | Vertical hierarchy + horizontal intelligence | Curriculum structure, outcome mapping, and mastery reporting |
The documentation repository ILS-doc is separate and reads the application code for factual reference only.
Backend architecture
The backend starts in ILS-dev/backend/index.js.
Key implementation points:
dotenvloadsbackend/.envandDATABASE_URLis required.Sequelizeconnects to PostgreSQL andinitModels()dynamically imports models frombackend/models/*.js.- Model associations are defined in
backend/models/index.jsafter all model factories are loaded. - All API routes mount under
/apiand the app injects the Sequelize models intoreq.modelsbefore each router. - JSON responses are serialized with a custom BigInt-safe replacer so
BigIntvalues are converted to strings. - A lightweight CORS policy allows the frontend origin configured by
CORS_ORIGINor*in development. requireAuthprotects all routes except/api/healthand/api/auth.- The backend is intentionally modular, with each route file responsible for a specific entity or feature area.
The backend does not use sequelize.sync() in the main startup flow.
Migrations and the database schema are intended to be managed outside the runtime.
Route structure
The backend exposes these top-level API groups:
GET /api/healthPOST /api/authand related auth routesGET|POST|PUT|DELETE /api/institutionsGET|POST|PUT|DELETE /api/campusesGET|POST|PUT|DELETE /api/coursesGET|POST|PUT|DELETE /api/modulesGET /api/modules/bank/outcomesGET /api/modules/bank/ref_teaching_methodsGET /api/modules/bank/assignmentsGET|POST|PUT|DELETE /api/assignmentsGET|POST|PUT|DELETE /api/themesGET|POST|PUT|DELETE /api/outcomesGET|POST|PUT|DELETE /api/outcome-categoriesGET /api/frameworksGET /api/referenceGET|POST|PUT|DELETE /api/rubricsGET /api/rubrics/categoriesGET /api/rubrics/criteriaGET /api/grading/*GET /api/heatmap/*GET /api/cockpit/summaryGET|POST|PUT|DELETE /api/classes/api/admin/*maintenance routesGET /api/matrixGET /api/assessment-typesGET /api/periods
Backend route categories
| Category | Example paths | Purpose |
|---|---|---|
| Curriculum management | /api/institutions, /api/courses, /api/modules, /api/assignments |
Create and maintain the vertical curriculum structure |
| Learning intelligence | /api/themes, /api/outcomes, /api/rubrics, /api/frameworks |
Manage reusable outcome, rubric, and mastery metadata |
| Grading and reporting | /api/grading/*, /api/heatmap/*, /api/cockpit/summary |
Capture scores, compute mastery, and summarize classroom health |
| Class delivery | /api/classes, /api/users, /api/periods |
Manage classes, enrollment, and scheduling context |
| Administration | /api/admin/*, /api/reference, /api/matrix |
Back-office maintenance and lookup data |
The homepage route definitions are located in ILS-dev/frontend/src/App.jsx.
That file defines the teacher and admin SPA routes, including:
/admin/...admin pages/courses/:courseId/modules/:moduleId/assignments/...assignment editor paths/admin/grading/admin/heatmap/admin/classroom-intelligence/admin/student-cockpit
Core model architecture
The app separates two domains:
- Vertical curriculum structure:
institutions,campuses,courses,modules,assignments,classes- Horizontal intelligence layer:
themes,outcomes,rubrics,rubric_criteria,rubric_ratings,student_outcome_snapshots
The module is the central hub of the vertical hierarchy. Assignments belong to modules, and classes are the enrollment context for a module.
Development & Architecture Rules
The ILS implementation follows a strict set of architectural rules to keep the system stable and consistent.
| Rule | Why it matters |
|---|---|
| Vertical hierarchy only through ownership | Keeps structure clear and avoids orphan entities |
| Assignments belong only to modules | Preserves the module hub as the authoritative owner of work items |
| Modules belong only to courses | Prevents cross-course ownership and keeps curriculum clean |
| Horizontal intelligence is global | Makes themes, outcomes, and rubrics reusable across courses |
| Use explicit junctions for links | Decouples intelligence data from ownership and enables flexible mapping |
| No nesting of intelligence entities | Keeps the model normalized and easier to maintain |
| No new tables without approval | Protects the stabilization phase from uncontrolled schema drift |
| Database schema is the source of truth | Ensures application code matches actual database structure |
| Environment-driven configuration | Avoids hardcoded database credentials and makes deployments safe |
| UI/API contract first | Keeps the frontend aligned with live backend behavior |
Model Definitions & Associations
The backend defines Sequelize models in backend/models/*.js and initializes associations in backend/models/index.js.
Model conventions include:
idisBIGINTand auto-incrementing for primary keys.deleted_atis used for soft deletes and models are configured withparanoid: true.created_atandupdated_atare standard timestamp fields.underscored: truemaps JavaScript camelCase to snake_case database columns.defaultScopetypically filters out soft-deleted records by requiringdeleted_at IS NULL.
Association patterns include:
hasMany/belongsTofor one-to-many relationships.belongsToManythrough junction models for many-to-many relationships.- Junction tables are modeled explicitly and used for decoupling intelligence entities from the vertical hierarchy.
The code uses explicit association aliases such as Module.hasMany(ModuleStructureRow, { as: 'structures' }) and Module.belongsToMany(Outcome, { through: ModuleLearningOutcome, as: 'outcomes' }) to make relationship usage readable in queries.
Main backend associations
The model associations defined in backend/models/index.js include:
Course.hasMany(Module)andModule.belongsTo(Course)Module.hasMany(Assignment)andAssignment.belongsTo(Module)Module.belongsToMany(Theme)viaModuleThemeModule.belongsToMany(Outcome)viaModuleLearningOutcomeAssignment.belongsToMany(Rubric)viaAssignmentRubricRubric.hasMany(RubricCriterion)andRubricCriterion.belongsTo(Rubric)RubricCriterion.hasMany(RubricRating)andRubricRating.belongsTo(RubricCriterion)RubricCriterion.belongsTo(Outcome)throughlinked_outcome_idUser.hasMany(Submission)andSubmission.belongsTo(User)Submission.belongsTo(Assignment)andAssignment.hasMany(Submission)Submission.belongsTo(Class)andClass.hasMany(Submission)StudentOutcomeSnapshot.belongsTo(Outcome),Class,User, andSubmission
Snapshot and intelligence tables
The key intelligence artifact is student_outcome_snapshots.
It stores the most recent mastery score per student, outcome, and class, and it is the source of truth for the heatmap and classroom cockpit reports.
Backend intelligence flow
The core intelligence flow is implemented in /api/grading and /api/heatmap.
Grading flow
POST /api/grading/submissions/:submissionId/score is the primary grading endpoint.
It:
- upserts
submission_criterion_scoresfor each rubric criterion - computes the submission total score from selected ratings
- marks grading status as
completewhen the run is finalized - updates
submissions.overall_scoreandsubmissions.grade_status - writes outcome snapshots in the same transaction using
backend/lib/snapshotWriter.js
The flow supports two assessment modes:
simplemode finalizes grading immediatelyadvancedmode allows draft saves and explicit finalization
Heatmap flow
GET /api/heatmap/classes/:classId builds the classroom heatmap by:
- selecting outcomes linked to rubric criteria used by assignments in the class
- loading the most recent non-stale
student_outcome_snapshots - detecting pending ungraded submissions for linked outcomes
- optionally enriching the response with trend data when
includeTrends=true
Cockpit flow
GET /api/cockpit/summary aggregates class and student health metrics using:
- class reporting rules from
campus_reporting_rules - pending submission counts and overdue work from
submissions - outcome mastery snapshots from
student_outcome_snapshots - student trend averages computed from snapshot history
Frontend architecture
The frontend uses React Router in ILS-dev/frontend/src/App.jsx and a single-page admin UI design.
Important frontend entrypoints:
frontend/src/pages/GradingPage2.jsx— grading cockpit and student submission selectionfrontend/src/pages/HeatmapPage.jsx— outcome mastery matrixfrontend/src/pages/ClassroomIntelligencePage.jsx— report summary and recommendation logicfrontend/src/pages/StudentCockpitPage.jsx— teacher task prioritization and student risk listfrontend/src/pages/RubricsPage.jsxandfrontend/src/pages/RubricEditor.jsx— rubric managementfrontend/src/pages/AssignmentForm.jsx— assignment builder with rubric selectionfrontend/src/pages/ModuleForm.jsx— module edit flow with outcomes, teaching methods, and structures
The shared API client is frontend/src/lib/api.js, which prefixes requests with /api and attaches the stored JWT token.
Developer implications
- Backend route behavior should be audited against
backend/routes/*.jsfor exact contract expectations. - The frontend UI is tightly coupled to the backend route payload shapes in the grading, heatmap, and admin pages.
student_outcome_snapshotsis the canonical data source for reporting; it should be treated as the consistency layer for heatmap and cockpit results.
Navigation and documentation
This architecture page is the entry point for the developer guide. It is intentionally tied to the live code in ILS-dev and does not describe future or unimplemented features.
Last updated: 2026-07-08