Demo Data
db/seeds/demo_data.sql populates a complete, realistic
demonstration environment — two schools, a financing partner, a standalone ElimuPay API
client, and every role — so a prospective customer can log in and actually use the product
before committing to anything.
Every account below signs in from the same page — there's no separate login per role.
Sign in at /login.php →Running it
Run this once, after db/01_schema.sql (or
install.php) has been applied, and after you've created your own Super Admin
account. This file deliberately creates no super_admin row, so
it can never interfere with that one-time, deliberately-singleton setup flow.
mysql yourdb < db/seeds/demo_data.sql
The whole file runs inside a single transaction — it either fully succeeds or fully rolls back. That matters in practice: if an import gets interrupted partway (a timeout on shared hosting, a dropped connection, or clicking import twice in phpMyAdmin), the transaction wrapping means nothing gets left half-committed for a retry to collide with.
Every ID in this file — every school, user, student, and everything else — starts at
500,000, not 1. That's deliberate: this file is meant to run after you've already
created your own Super Admin account (which takes users.id = 1 on a fresh table),
and possibly after you've already clicked around and created other real data too. Starting at a
high, clearly out-of-the-way number means the demo data can never collide with anything real,
without needing to check what's already there first.
Not designed to be re-run against a database that already has this demo data (or real school data) in it — it uses explicit primary keys throughout, matching what a fresh install's auto-increment would produce, so a second run against a database that already has that data will hit duplicate-key errors. That's intentional, not a bug: a one-time bootstrap for a fresh environment, not an idempotent seed.
If you hit "Duplicate entry '1' for key 'PRIMARY'"
If you're reading this because you just hit that error: it almost certainly means you
correctly followed the instructions above and created your Super Admin via
install.php before running this file — which is exactly right —
but an earlier version of this file used low, hardcoded IDs starting at 1, the same ID your
Super Admin account takes on a fresh users table. That's fixed now: every ID in
this file is offset by 500,000 (a school is id = 500001, not id = 1),
so it's structurally unable to collide with your own account or anything else created through
normal use, however many real schools, staff, or students already exist. If you're on the
current version of this file, this specific error shouldn't happen again — if it does, it means
something in your database is also at a 500,000+ ID, which would be worth a closer
look with the diagnostic query below.
If you still have partial rows left over from hitting this before the fix:
db/seeds/check_before_import.sql— read-only, shows you exactly what's currently in the tables this seed touches. Run this first if you're not sure what's there.db/seeds/reset_demo_data.sql— removes anything already created by this specific demo dataset (identified by name —Riverside Academy,Greenfield Primary,Jamii Finance Partners,Sunrise Schools Group— not a blind sweep, so your real Super Admin and any other real data is untouched), then you can safely re-rundemo_data.sqlfrom a clean slate. Leavessubscription_plansalone, since those are shared infrastructure a real school might already be using, not demo-specific data.
Both were tested against the exact scenario that causes this — a real MariaDB instance, a
Super Admin account created first via the same insert install.php uses (so it
lands on users.id = 1 exactly as it would on a real install), then the demo data
imported on top: zero collisions, both the real account and all ten demo accounts coexist
correctly.
db/01_schema.sql — schema
applies cleanly, the demo data loads with zero errors or warnings, and every table passed a
CHECK TABLE integrity pass. One real bug was caught and fixed in the process:
the schema itself already seeds six catalog curricula (844, CBE,
BRITISH, IB, AMERICAN, MADRASA) — an
early draft of this file tried to insert its own CBC curriculum row, colliding
with that pre-seeded data on primary key. Fixed by referencing the existing
CBE curriculum (the current name for what used to be called CBC) via a
subquery instead.
Every demo account shares one password
Demo@2026
Login directory
Riverside Academy — the fully-featured demo school
| Role | Who | What to look for | |
|---|---|---|---|
| School Admin | admin@riverside.ac.ke | Grace Wanjiru | Full administrative view across every module |
| Teacher | teacher@riverside.ac.ke | Peter Otieno | Teaches Mathematics to Grade 5 and Grade 7 |
| Accountant | accountant@riverside.ac.ke | David Mwangi | Fee balances, payroll, the accounting ledger |
| Librarian | librarian@riverside.ac.ke | Esther Njoki | Book catalog, active loans, one overdue fine |
| Parent | parent1@riverside.ac.ke | Alice Muthoni | Mother of two enrolled children (Brian, Faith) — sibling discount active; Brian has a self-serve ElimuPay plan with one instalment already paid |
| Parent | parent2@riverside.ac.ke | Daniel Kimani | Father of Cynthia — her ElimuPay plan is financing-partner backed (Jamii Finance Partners), already disbursed |
| Student | student1@riverside.ac.ke | Brian Muthoni | An open Head Boy election is waiting for his vote, and he's one of the two candidates — a genuine live-voting demo moment |
| Student | student2@riverside.ac.ke | Cynthia Kimani | Appointed Class Prefect for Grade 5 |
| Alumni | alumni@riverside.ac.ke | Kevin Otieno | Graduated 2023, has a donation on record |
Greenfield Primary — a second, smaller school
| Role | Who | |
|---|---|---|
| School Admin | admin@greenfieldprimary.ac.ke | Michael Ndungu |
Deliberately lighter (3 classes, 8 students, core academic + fee data only, still on its trial subscription) — its main purpose is proving multi-tenant isolation: logging in here shows nothing from Riverside, and vice versa.
Affiliate portal — a separate login, not /login.php
An affiliate isn't a users row and doesn't share the platform's regular session
(see AffiliateAuth.php — deliberately isolated the same way ApiAuth.php
is). Sign in at /affiliates/login.php, not the main login page.
| Role | Who | What to look for | |
|---|---|---|---|
| Affiliate | brenda.blogger@example.com | Brenda Otieno | Referral code DEMO01 — credited with referring Riverside Academy, with
one real paid commission (KES 432, 10% of Riverside's KES 4,320 subscription payment)
already on record. Visit the Marketing Toolkit from her dashboard for downloadable
banner images and HTML embed codes, each with her referral link already baked in. |
What's covered
Every module has real, interconnected data: academic setup (curricula, classes, sections, subjects, teacher assignments), attendance (last 5 weekdays for every student), exams and results (Grade 5 and Grade 7, where the demo logins are, so report cards have real substance), fee structures and balances in deliberately varied payment states (fully paid, partial, untouched), four ElimuPay instalment plans covering every real status (self-serve active, partner-financed active, completed, pending partner confirmation), library (including one overdue loan with a fine), transport (one vehicle has a live GPS ping so the parent view's map feature has something real to show), hostel, admissions (five applications across every review stage), student leadership (one open election ready to vote in, one finalized election with real tallies, one appointive holder), alumni, homework/assignments, live classes, messaging, announcements, payroll (a fully processed run), the accounting ledger, subscription billing (one paid invoice, one pending), and the standalone ElimuPay API client's own activity log.
What's deliberately NOT included
- No
super_adminaccount — by design, so this file can never conflict with the installer's singleton Super Admin safeguard. Create yours first viainstall.php, then run this. - No generated PDFs — report cards, certificates, ID cards, and payslips
exist as real underlying data (exam results, templates, issuance records) but with
pdf_pathleftNULL. PDF generation happens in the app itself via FPDF at request time, not something a SQL file can produce. Clicking "generate" or "download" for any of these during a demo is a genuine, real interaction — not a pre-baked screenshot. - No uploaded files — photos, logos, and admission documents aren't attached; every page that would show one instead shows its normal "not uploaded yet" state.