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.
Sign in at
/login.php— every account below uses the same one page; there's no separate login per role.
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: this is 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.
Tested, not just written. This file was verified end-to-end against a real MariaDB 10.11 instance
running the actual 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.
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.
Solvo 2.0 additions
db/seeds/demo_data_2_0.sql adds content for the 2.0 features on top of the file above: published
websites with FAQs, events and testimonials for both schools, Greenfield's own brand colours (so the
"School colours" theme has something to show), live-chat settings, saved replies and conversations in
the platform and Riverside inboxes, and a populated message log including one failed send.
You normally don't load these files by hand. On the demo edition, scripts/demo_reset.php rebuilds
the whole database every night: schema, both seed files, the demo Super Admin
(superadmin@solvo.demo / Demo@2026), the school logos (light and dark variants) and the rendered
sample messages. On a standard installation, tick Also load sample data in the installer instead.