HandbookAcademics06

Class logbook.

The logbook is where teaching becomes evidence. Every period filled, every lesson confirmed by the students who sat in it, every coverage gap explained — until the line from 'what was taught' to 'what gets paid' is unbroken. This is the founder's spine of YESS: the loop that ties a teacher's daily lesson to the cheque that lands on their account at month-end. Read it once and you'll understand half the LMS.

  • 11live logbook routes
  • 6actor types
  • 8feature surfaces
  • ≈14 minto read

Prologue

Why the logbook exists#

Every school admin we've sat with has, at some point, said this sentence: “I know my teachers cover the syllabus because they tell me they do.” That sentence is the problem YESS's logbook was built to retire. It replaces trust-as-policy with a trail anyone can follow: the teacher fills, the students confirm, the system counts, the admin reviews, payroll releases. No one signs anything they can't see; no one is paid for work nobody else can attest to.

The handbook ahead walks the loop end-to-end. We open with a Tuesday morning at Greenwood — the school the YESS handbook uses as its example throughout — and follow one logbook entry from the chalkboard to the payroll office. Then we open every surface in turn: the entry form, the student approval, the parent backup for minors, the substitute attribution, the coverage goals, the justification flow, the HOD oversight, the salary-release gate. By the end of the book the loop is familiar in your bones.

The logbook is the contract between a teacher, the students, and the school. YESS only keeps the receipts.

Chapter one

A Tuesday morning, end to end#

Greenwood Secondary, 22 October 2026. Form 5A, Period 3, Maths. Mr. K. Adjei is the teacher of record; the topic on the syllabus plan for today is “Quadratic equations — vertex form.” Follow this morning end-to-end and the rest of the book is just detail.

09:30. Period 3 starts. Mr. Adjei opens YESS on his phone, taps Start period on the timetable card. The period state flips from scheduled to in_progress.

09:32. He marks attendance from /teacher/attendance. Twenty-eight of thirty present. Attendance is C2's job; logbook waits its turn.

09:40. He teaches the planned topic. The syllabus plan row is linked to this period; when the entry lands later, the plan's status will flip to completed automatically.

10:25. Five minutes before the bell. He opens /teacher/logbook, types the topic covered, ticks two objectives, sets behaviour to good, hits Save. Three triggers fire in the next two seconds.

10:25:01. The syllabus plan flips to completed. The notification fanout RPC inserts thirty logbook_approvals rows (one per enrolled student) and writes twenty-eight notifications — twenty students directly + eight parents (for students under the school's age cutoff of 13).

10:31. Form 5A's WhatsApp-style notification badge lights up on every student's phone: “Math — logbook to confirm.” They tap; they're taken to /portal/logbook-approvals. Most tap Approve. One student (Ama Boateng) thinks the teacher wrote the wrong topic; she taps Revoke + types her reason. The audit row captures her dispute.

End of month — 31 October 23:00 UTC. A cron job (defensively dormant; schools opt in per database) walks every active teaching staff member and recomputes their compliance. Mr. Adjei's actual entries / expected entries for October lands on the /dashboard/logbook-overview overview page.

1 November. The school admin opens /dashboard/lms-justifications. Two teachers are below the 80% threshold; one (Mr. Adjei, who was sick three days) submits a justification with a doctor's note. Admin reviews, accepts. The compliance row's blocks_payment flag flips off.

5 November. Payroll runs. For every teacher, payroll calls can_release_teacher_salary. Mr. Adjei's returns true (justified). The lagging teacher with no justification returns false — their cheque holds until they explain.

Chapter two

Every surface, one page#

The loop opens out into eight surfaces. Each is a small, opinionated piece of UI built around one verb a school actually does. Read them as a carousel — they appear in the order a school visits them during a normal week.

Feature 01

Filling an entry

What it does. The teacher's daily action. Three minutes before the bell, the teacher opens the logbook from the teacher portal or the admin dashboard, picks the section + subject + period, types the topic covered, the subtopics, the objectives achieved, and a quick read on class behaviour. Optional: attach a photo of the chalkboard, a homework brief, links to a course resource the class used. The save fires three triggers: the syllabus plan row linked to this lesson flips to status='completed'; the notification fanout begins; and the entry is locked into the audit trail with the teacher's name + timestamp.

How to use it

  1. 01Open <DocsRouteChip href='/teacher/logbook' /> on the phone or the dashboard logbook page on a desktop.
  2. 02The form pre-populates the date, the period, and the linked syllabus plan if today's lesson was planned. Add the actual topic covered and any objectives achieved.
  3. 03Optionally attach files via Cloudinary (chalkboard photos, lesson handouts) — they're stored on logbook_attachments with the teacher's audit trail.
  4. 04Save. The UNIQUE constraint on (teacher_id, timetable_period_id, date) means you can only file once per period — re-saves update the existing row, never duplicate it.

Chapter three

State machines, three lifecycles#

Three small state machines run the logbook. Each is named, has a guarded transition path, and is auditable end-to-end. If you ever want to know “how did this entry end up in this state?”, the path is the same as the diagram below.

Start

  1. pending
  2. approved
  3. revoked

End

Start

  1. pending
  2. accepted
  3. rejected

End

Start

  1. compliant
  2. blocks_payment
  3. justified
  4. released

End

Chapter four

The data engine, in brief#

Four tables, five RPCs, two triggers, one cron — that's the entire logbook engine. We list it here for the engineers who want the receipts; if you're an admin reading the handbook for the first time, skim and skip to chapter five.

Tables: teacher_syllabus_plans (the planned topics, authored at term start). teacher_logbook_entries (the actual filed rows, one per period). logbook_approvals (one row per enrolled student per entry, with pending/approved/revoked status). logbook_justifications (teacher submissions with category + reason + reviewer audit). logbook_coverage_goals (school-configurable targets layered per scope). payroll_logbook_compliance (the per-month aggregate the salary gate reads).

RPCs: approve_logbook_entry + revoke_logbook_entry (identity-verified via get_user_profile_id). submit_logbook_justification + review_logbook_justification. compute_coverage_against_goal (most-specific-goal-wins resolution). can_release_teacher_salary (the boolean gate) + can_release_teacher_salary_with_reason (the structured payload for finance UI). recompute_compliance_for_all_teachers (the producer the cron calls).

Triggers: trigger_update_syllabus_status (AFTER INSERT on teacher_logbook_entries — flips the linked plan to completed). trg_teacher_logbook_entries_notify (AFTER INSERT/UPDATE on entries — best-effort fanout via notify_students_of_logbook_entry). trg_period_check_logbook (BEFORE INSERT on timetable_periods — enforces “every subject in every program MUST have a syllabus plan before teaching starts”).

Cron: logbook-compliance-recompute-daily at 23:00 UTC. Defensively dormant; schools opt in via the per-DB GUC app.logbook_compliance_cron_enabled = 'true'. The job walks every active school's teaching staff and calls recompute_compliance_for_all_teachers, persisting per (teacher, year, month) into payroll_logbook_compliance.

Chapter five

The knobs a school picks#

The logbook is opinionated by default but tunable in three places. Every knob below is per-school, stored in school_lms_policy (one row per school, auto-seeded at school provisioning).

parent_approval_age_cutoff — default 13. The age below which a student's parent receives the approval notification instead of the student. Set to 11 if your primary cohort is more independent; set to 16 if your culture treats older students as still under parental authority. The fanout reads each student's date_of_birth at notification time and routes accordingly.

logbook_compliance_threshold — default 80%. The school-wide default for what counts as compliant. Per-row overrides also exist (payroll_logbook_compliance.school_threshold) for one-off monthly adjustments. Per-goal overrides on logbook_coverage_goals can refine further by subject or class.

logbook_check_interval — default monthly. The cadence at which the HOD oversight + the teacher's own coverage page surface a snapshot. Acceptable values: weekly, monthly, mid_term, term. The cron runs daily regardless; this knob shapes what the UI shows as the “current period”.

The per-goal configuration page that lets admins layer subject + class targets lives at /dashboard/lms-settings/coverage-goals. The three school-wide knobs (parent_approval_age_cutoff, logbook_compliance_threshold, logbook_check_interval) are persisted in school_lms_policy and are currently configured at school provisioning time — a dedicated admin UI for editing them in place is a follow-up.

Chapter six

What the logbook touches#

The logbook is a hub: data flows in from one cluster, flows out to another, the loops close in a third. Here's the contract sheet.

From C1 academic. The logbook reads from teacher_syllabus_plans (which itself references subjects, sections, classes, terms, academic_years). The first period for any (subject, section, term) tuple is blocked unless a syllabus plan exists for it — the 00584 trigger enforces this at the database level so no timetable can be authored for an unconfigured subject.

To C5 communication. Every saved entry fans out notifications through C5's dispatcher. The notification.action_url points at the portal's approvals list page (the list's pending section sorts new rows to the top, so the student / parent lands on the right entry without a parameterised route).

To C3 payroll. The salary release gate is the cluster contract: payroll calls can_release_teacher_salary before disbursing each cheque. The structured-reason variant gives the finance officer enough context to decide what to do with a hold — talk to the teacher, talk to the admin, override via override_reason.

From C8 conduct. Substitute teacher assignments live in C8's period_states table (is_substitution, effective_teacher_id). The logbook entry form reads from period_states to drive the substitute banner.

To LMS analytics. Coverage gaps and compliance dips bubble up into the C6 LMS alerts engine (00078). Critical-level dips show on the school's live alert tile at /dashboard/lms-alerts.

Chapter seven

The edge cases YESS thought through#

The loop is straightforward in the happy path. The work was in the edges.

Re-filing. A teacher can edit an entry after saving — the UNIQUE constraint on (teacher_id, timetable_period_id, date) means the second save updates the existing row rather than creating a duplicate. But if the entry was already approved by students, the edit doesn't auto-flip them back to pending — the school decides whether silent edits are acceptable or whether they should trigger a re-approval. Default behaviour: edits stay attributed to the original entry; the approval status sticks.

Substitute attribution. The substitute banner on the entry form makes the “recording on behalf of” relationship unmistakable. The compliance counter and the salary gate read teacher_id (the original); the audit log reads verified_by (the substitute). If a substitute forgets to switch the teacher field, the banner doesn't appear and the entry counts toward the substitute's compliance instead — schools should make this an explicit step in the vice principal's substitution flow.

Unmeasured teachers. The salary gate default-allows when no compliance row exists. This is deliberate: a new teacher in their first month, or a teacher who joined mid-cycle, hasn't been measured yet — holding their cheque would be punitive without cause. The first monthly recompute writes their row; from that point on, the gate is meaningful.

Disputes. A revoked entry doesn't remove the teacher's compliance credit; it flags the entry as disputed in the admin's queue. The teacher and the student stay in good standing while the admin decides who's right. If the admin sides with the student, the teacher edits the entry to reflect what actually happened and the dispute closes.

Best-effort fanout. The notification fanout trigger wraps its PERFORM in EXCEPTION WHEN OTHERS + RAISE WARNING. If the dispatcher is temporarily down, the teacher can still save their entry — the audit warns admin via the log, and the next save (or the next manual recompute) retries the fanout.

Chapter eight

The six things competitors don't#

We've walked dozens of competing systems. Six things show up in YESS's logbook that no other product on the African or Middle Eastern market combines.

  1. 01

    Student-and-parent confirmation, not teacher self-report

    Every entry is confirmed by the students who sat in it (or their parent for minors). No silent approval-by-time-elapsed. The confirmation rate per teacher is part of compliance.

  2. 02

    Per-school configurable threshold + per-subject overrides

    The 80% default is just that — a default. Each school sets its own compliance bar; each subject can carry its own override; per-month manual overrides exist for the edge cases.

  3. 03

    The salary-release gate is at the DB layer, not the UI

    can_release_teacher_salary is a database function. C3 payroll calls it directly. The gate can't be bypassed by a misconfigured UI flag because the gate isn't in the UI.

  4. 04

    Best-effort fanout that doesn't block the teacher

    If notifications fail, the teacher's save still succeeds. The audit captures the failure for admin review. A flaky network never blocks the daily work.

  5. 05

    Substitute attribution that respects both names

    The lesson counts toward the original teacher's compliance (their class, their responsibility) but the audit captures the substitute (who actually taught). Both names matter.

  6. 06

    Justification as a first-class concept, not a workaround

    Illness, school closure, strike, exam marking, training — each is a categorised submission with an evidence URL. Schools can run reports on why teachers fell behind, not just whether they did.

Verified truth

The receipts behind this page#

Every claim on this page is backed by migrations 00077 (syllabus + entries), 00079 (permissions), 00089 (soft-delete columns), 00092 (compliance + payroll integration), 00193 (RLS user-profile-id repair), 00465 (drift-fix), 00560 (school_lms_policy), 00580 (logbook_approvals + approve/revoke RPCs), 00581 (justifications), 00582 (coverage goals), 00583 (can_release_teacher_salary), 00584 (validate_subject_logbook_exists trigger), 00585 (notify_students_of_logbook_entry fanout), 00613 (compliance cron + per-school threshold), 00614 (trigger route fixes). Truth audit: docs/atlas/audit/lms-logbook-truth-2026-05-22.md. Verified 2026-05-22.