0%
balqalam Logo
balqalam
FeaturesCommunityPricingDocumentation
Login
  • Introduction
  • Help center
  • Common questions
  • Get Started
  • Localhost
  • Architecture
  • Structure
  • Pattern
  • Page
  • Layout
  • Content
  • Types
  • Config
  • Actions
  • Queries
  • Authorization
  • Validation
  • Form
  • Table
  • Detail
  • Card
  • Util
  • Hooks
  • List Params
  • Views
  • README.md
  • ISSUE.md
  • Technology Stack
  • Database
  • File
  • CDN Assets
  • Entry Points
  • Dashboard
  • Authentication
  • Credentials
  • OAuth
  • Flow Diagrams
  • Multi-Tenancy
  • Offline
  • Onboarding
  • Onboarding Videos
  • Add Values
  • Admission
  • Application
  • Attendance
  • Compliance
  • Profile
  • Exams
  • Exam Wizard
  • Timetable
  • Classrooms
  • Notifications
  • Conference
  • LMS (Lumos)
  • Finance
  • Fee Management
  • Invoice
  • Wallet
  • Salary
  • Payroll
  • Timesheet
  • Expenses
  • Budget
  • Receipt
  • Accounts
  • Banking
  • Reports
  • Dashboard
  • Permissions
  • Messages
  • Integration Flow
  • Provision
  • AI Document Processing
  • Document Intelligence
  • Internationalization
  • Translation
  • Translation Guide
  • Icons
  • Docs Factory
  • Inspiration
  • Listings
  • Teachers
  • Students
  • Catalog
  • Library
  • Contributing
  • Code of conduct
  • GitHub Workflow
  • Database Seeds
  • Database Safety
  • Test Accounts
  • Bulk import
  • Playwright
  • Prettier
  • Block Rebound
  • Transportation

Integration Flow

PreviousNext

The layer chain from global catalog to a running school — academic structure, terms-aware schedule, sections, the section-based timetable, people, attendance, exams, grades and reports, and the downstream blocks that consume them.

Every school progresses through the same dependency chain. Most layers are auto-provisioned the moment onboarding completes — the machinery (stages, idempotency, the repair doctor, the terms-aware calendar engine) is documented in Provision; this page is the map.

The ordering encodes one deliberate idea: the timetable comes before people. A timetable is derivable from structure alone (grades × subjects × sections × schedule), so it is generated teacher-less. Students are then placed into sections, teachers assigned to subjects — and attendance, exams, grades, and reports flow from there.

The layers

LayerNameWhat it createsDepends on
1Global catalogSubject (grade-specific) → chapters → lessons → books—
2School onboardingSchool profile + provisioning trigger1
3Academic structureAcademicLevel, AcademicGrade, AcademicStream2
4Subject selectionSubjectSelection bridge rows (grade ↔ catalog)1, 3
5ScheduleSchoolYear, Term ×N (terms-aware), Period, SchoolWeekConfig2
6Classrooms & sectionsClassroomType, Classroom, Section — N per grade3
7TimetableTimetable slots — section × subject × period × room, teacher-less4, 5, 6
8aTeacher assignmentTeacherSubjectExpertise, TeacherDepartment, slot teacherId4, 7
8bStudent placementStudent.sectionId (+ LMS Enrollment in the grade's subjects)6
9AttendanceAttendance — section rosters, period-aware via timetable slots7, 8b
10ExamsSchoolExam, sessions, marking, ExamResult4, 8
11Grades & reportsReportCard, certificates, transcripts, promotion9, 10
12Downstream consumersTransportation, LMS, conference, library, finance, messagingvaries

Layers 1–7 are fully auto-provisioned. Layers 8a/8b are admin actions with assistive UIs. Layers 9–11 are operational features that light up as soon as their dependencies exist.

Layer 1 — Global catalog

The shared backbone. All curriculum content lives once in global tables (no schoolId); schools connect through bridge tables.

Subject (grade-specific, per curriculum: us-g1-math, sd-g7-arabic, …)
  └─ Chapter
       └─ Lesson

Subjects are grade-specific, not level-based. Teacher-created content is saved PENDING + PRIVATE, reviewed by the SaaS operator, then published. School-proposed subjects go through the opt-in proposal flow (approve → publish to catalog → school adds from its picker). Full reference: Catalog.

Layer 2 — School onboarding

Onboarding answers drive everything downstream:

Onboarding stepSaves intoDrives
DescriptionSchool.schoolType (public, private, international…)Structure recommendation, curriculum inference
LocationSchool.country, city, stateCurriculum inference, term calendar
CapacitySchool.sectionsPerGrade, studentsPerSectionClassroom/section provisioning
ScheduleSchool.timetableStructure (structure slug)Periods, working days, calendar override
ComputedFormula
maxClassesgrades × sectionsPerGrade
maxStudentsmaxClasses × studentsPerSection

Accepting terms on the legal step fires completeOnboarding() → the provisioning chain. Stages, ordering, and repair semantics: Provision.

Timetable structures

~23 structures define the weekly period layout per country and school type (sd-gov-default 8×45m Sun–Thu, gulf-standard 7×45m, us-standard 7×50m Mon–Fri, ae-primary, jo-secondary, intl-default, …). getRecommendedStructures(country, schoolType, schoolLevel) ranks them:

SignalScore
Country exact match+40
Region match+25
Wildcard *+5
schoolType match+20
schoolLevel match+10

Score ≥ 30 → recommended; ≥ 50 → auto-select. Region map: SA/AE/QA/KW/BH/OM → GULF; EG/JO/LB/TN/MA/DZ → MENA.

A structure can carry a calendar override — sd-british follows the GB 3-term calendar even though the school's country is SD.

Layer 3 — Academic structure

setupCatalogForSchool() creates the hierarchy per curriculum config (SD Arabic 6+3+3 with Science/Arts streams, US 5+3+4, GB Key Stages, CBSE, generic fallback):

ModelKey fields
AcademicLevellevel, levelOrder, startGrade, endGrade
AcademicGradegradeNumber, levelId, yearLevelId
AcademicStreamstreamType (SCIENCE, ARTS), gradeId

schoolLevel scopes the range: primary → grades 1–6, secondary → 7–12, both/null → 1–12.

Layer 4 — Subject selection

The bridge between global catalog and school grades — knowing the grade and the curriculum means knowing the subjects. Auto-assignment matches catalog subject.grades arrays with a progressive fallback (country+curriculum+type → country+curriculum → worldwide → US baseline), ~99% auto-assigned. Details: Catalog.

Schools customize from there: add subjects from other systems, hide per grade (isActive), hide chapters/lessons (ContentOverride), rename (customName), and set weeklyPeriods — the number the timetable generator schedules per week.

Layer 5 — Schedule (terms-aware)

The schedule stage derives the academic year, term count, term boundaries, and the currently-active term from the school's country, structure, and today's date — ACADEMIC_CALENDARS in timetable/calendars.ts maps each country to its ministry pattern (SA = 2 semesters post-1447 revert, AE/KW/GB = 3 terms, IN = April-anchored year-wrap, …).

What gets created: one SchoolYear, N Terms with a date-correct isActive, all Periods from the structure, and SchoolWeekConfig (working days + lunch). Every record is admin-editable afterwards in School → Configuration → Academic. Full calendar table and resolution chain: Provision.

Layer 6 — Classrooms & sections

Capacity settings (sections-per-grade + capacity) drive N sections per grade, each paired one-to-one with exactly one main classroom — Section.classroomId is a single nullable FK, so a section can never have more than one. Room type governs: the main room is the classroom-type homeroom (Grade 7-A room ↔ Grade 7-A section). The chain this encodes:

Classroom (main) → belongs to a grade → grade + curriculum → subjects taught here
Section          → the student cohort that occupies that classroom

Labs and common spaces are a different thing — not grade-owned, never set as a section's main classroom; created with their own ClassroomType (Lab, Computer Room, Library) and reached per-period through the timetable (Timetable.classroomId), available to the generator for lab-flagged subjects.

No course axis (Class removed)

There is no separate course record. A grade has subjects (SubjectSelection, with weekly periods) and sections; the timetable, exams, results, assignments and attendance are set per section (or the whole grade) and subject, and teaching is SubjectTeacher. The Class, StudentClass and ClassTeacher models, and every classId column, were removed on 2026-10-04 (see the classes-removed note).

Layer 7 — Timetable

Slots are section-based:

Timetable {
  schoolId, termId, dayOfWeek, periodId,
  sectionId,   // who (the cohort)        — primary
  subjectId,   // what
  classroomId, // where
  teacherId,   // who teaches — nullable, assigned later
  weekOffset
}

Unique constraints prevent double-booking (school, term, day, period, section, week offset — and the same for the classroom). Auto-generation distributes each grade's subjects (weeklyPeriods each) across working days × teaching periods into the section's paired room, teacher-less. Manual editing in the grid is also section-first: pick section + subject (+ teacher when known).

getRecommendedStructures ranks layouts at onboarding; if no terms exist yet, the grid renders a non-persisting draft schedule with an admin CTA to provision for real.

Layer 8a — Teacher assignment

Teachers attach to subjects, then to slots:

RoleWhereDescription
Subject expertTeacherSubjectExpertiseQualification per subject (expertiseLevel)
Slot teacherTimetable.teacherIdWho teaches this section-period
Homeroom teacherSection.homeroomTeacherIdPastoral, per section
Department member / headTeacherDepartmentisPrimary, isDepartmentHead
Subject teacherSubjectTeacherOne teacher per section × subject per term

deleteTeacher blocks while SubjectTeacher or Timetable references exist; deleteSubject blocks on expertise, exam, or question-bank references. A section × subject pair with no teacher shows as "Needs teacher" in the timetable; assign one from the Add-teacher wizard, the /teachers row menu ("Assign subjects"), or the board at /timetable/assignments.

Layer 8b — Student placement

The 5-step admission wizard ends in ADMITTED → placement:

  • placement-dialog.tsx (per student) and bulk-placement.tsx (batch) both call placeStudentInSection(applicationId, sectionId) — validates maxCapacity, sets Student.sectionId (the operational placement), then gives the student an LMS Enrollment in every subject of the section's grade (syncStudentSubjectEnrollments — stream-filtered, adds only). No StudentClass row is written any more.
  • Through the section, a student inherits the classroom, the timetable, the attendance roster, and every exam, assignment or notice set for the section or its whole grade.
  • extractGradeNumber() in src/lib/grade-utils.ts parses free-text grades ("Grade 5", "5th grade", "الصف الخامس").

Layer 9 — Attendance

Attendance is section-based: the roster is Student.sectionId (there is no class roster), and period-mode lights up directly from the timetable —

  • Teacher scoping: a teacher can mark sections they have timetable slots in (or homeroom).
  • Current-period auto-selection: the active Period × the teacher's slot resolves the section automatically.
  • Period marking writes sectionId + periodId + timetableId; whole-day marking works with no timetable at all.
  • Sessions, hall passes and competition entries are per section too; there is no classId anywhere.

Status: ~92%, production-hardened (security pass 2026-06-02, 575 tests green). Compliance (ADEK eSIS) exports daily-mode records. Full reference: Attendance.

Layer 10 — Exams

The assessment stack is set for a grade plus one of its sections (or the whole grade) + subject + term:

SchoolExam → ExamSession → StudentAnswer → MarkingResult → ExamResult
QuestionBank → GeneratedExam → GeneratedPaper
Result (assignments / homework grades)

Exam scheduling checks timetable slots for conflicts (app-layer). Known open items from the production audit: two competing result models (Result + ExamResult), score-precision mismatch (Int vs Decimal), and cascade chains that don't preserve certificate proof — tracked in the exams block records. Full reference: Exams.

Layer 11 — Grades & reports

ExamResult + Result
  → ReportCard (per student per term)  → ReportCardGrade (per subject)
       ├─ Certificate PDF (composable engine, 4 regional presets) — production-ready
       ├─ Transcript (multi-year frozen snapshot, QR verify)
       ├─ Notifications (grade_posted, report_ready, certificate_issued, promotion_decided)
       └─ Promotion / Retention → Student.academicGradeId

Promotion operates per grade (PromotionPolicy by gradeId): batch evaluation → GPA + failed subjects + attendance percentage (layer 9 feeds layer 11) → admin review → execute (StudentYearLevel, grade reassignment) → notify.

Known gap: two different DEFAULT_BOUNDARIES scales exist (reports 9-tier vs grades 12-tier) when a school has no SchoolGradingConfig — converge before relying on letter grades.

Layer 12 — Downstream consumers

Each block consumes a different axis of the academic core:

BlockConsumesCoupling
ConferencesectionId (eligibility + fan-out), timetableId (start from slot), termIdSection-based
TransportationstudentId only (routes, boarding)Decoupled from sections/timetable
LMS (Lumos)catalogSubjectId (enrollment per catalog subject)Catalog-based, not section-based
LibraryschoolId only (global-first book adoption)Fully decoupled
FinancestudentId (fee assignment), optional grade groupingStudent-based
Messaging / WhatsAppSection groupsSection-based

None of these block the academic chain; they activate independently as their own setup completes.

Failure modes

MissingBlocks
CatalogSubject selection, timetable generation
Academic structureSubject selection, sections
TermsTimetable (draft fallback shown), attendance period-mode
SectionsTimetable generation, attendance rosters, placement
SubjectSelectionTimetable generation (No sections have subjects)
Timetable slotsAttendance period-mode, teacher section-scoping, conference-from-slot
SubjectTeacherTimetable slots show "Needs teacher"
Exams / ResultsReport cards, transcripts
Report cardsPromotion (GPA required)

Provisioning-specific failure modes and the readiness check live in Provision.

See also

  • Provision — the auto-provisioning engine, terms-aware calendars, the doctor
  • Onboarding
  • Catalog
  • Admission
  • Attendance
  • Multi-Tenancy
MessagesProvision

On This Page

The layersLayer 1 — Global catalogLayer 2 — School onboardingTimetable structuresLayer 3 — Academic structureLayer 4 — Subject selectionLayer 5 — Schedule (terms-aware)Layer 6 — Classrooms & sectionsNo course axis (Class removed)Layer 7 — TimetableLayer 8a — Teacher assignmentLayer 8b — Student placementLayer 9 — AttendanceLayer 10 — ExamsLayer 11 — Grades & reportsLayer 12 — Downstream consumersFailure modesSee also

Built by Databayt ·

Welcome to balqalam.

A great journey is about to begin.