Markaz il Ginna
A school management and student results platform, rebuilt from a static Firebase app. Staff register students and publish results; students and parents sign in to see them, in English or Arabic.
- My role
- Architecture, database design, authentication, development and deployment
- Client
- Markaz il Ginna, an Islamic school
- Category
- Web application, Education

01
Overview
The school's first system was a static Firebase app. Version 2 is a ground-up rebuild on PostgreSQL, designed around how a school actually works: sessions, terms, levels, subjects, enrolments, results and families.
Every page exists in English and Arabic. The Arabic version is a full right-to-left layout, not a translated overlay.
- Next.js
- React
- TypeScript
- Tailwind CSS
- PostgreSQL (Neon)
- Drizzle ORM
- Neon Auth
- argon2id
- Vitest
02
The problem
Student records are sensitive and long-lived. Results must not be silently overwritten, families must only ever see their own child, and staff need different powers depending on their job.
The interface had to work equally well in two scripts and two reading directions.
03
Approach
The browser never talks to the database. Every read and write goes through server code that authenticates the caller, checks a named permission and validates input.
History is append-only: results, enrolments and identifiers are corrected with new records, and an audit log records who did what.
Business rules such as student IDs and grading policy live in plain TypeScript modules with unit tests, separate from React and the database.
04
Architecture
- Application
- Next.js App Router with Server Components and Server Actions. Every route lives under /en or /ar.
- Database
- PostgreSQL on Neon through Drizzle ORM: UUID keys, integer kobo for money, constraints and triggers that enforce the rules as well as the code.
- Staff access
- Neon Auth sign-in, then role and permission checks on every server action.
- Family access
- Student ID and PIN sign-in, with PINs hashed using argon2id and sign-in throttling.
- Internationalisation
- Typed dictionaries (a missing Arabic string is a compile error), logical CSS properties for mirroring, and Intl formatting in the Africa/Lagos time zone.
05
Key features
Student records
Registration, profiles, guardians, placement, status changes and never-recycled student IDs.
Staff administration
A staff workspace with permissions per role, academic sessions, terms and enrolments.
Results
Score entry, validation, grading, ranking and publication by term, level and subject.
Student and parent portal
Overview, published results and profile, scoped to the signed-in student.
Bilingual interface
English and Arabic throughout, right-to-left layout, and both scripts with their own fonts.


06
Challenges
Two directions, one codebase
Problem
Mirroring a layout by hand for Arabic doubles the work and drifts over time.
What I did
Logical properties (start/end instead of left/right) mirror components automatically, and typed dictionaries make a missing translation fail the build.
Mixed-script data
Problem
Latin names inside Arabic pages, and the reverse, scramble their reading order.
What I did
Free text uses bidi-plaintext rendering and dir=auto inputs; IDs, PINs and emails stay left-to-right inside Arabic pages.
Records that must not be rewritten
Problem
A results system that allows silent edits cannot be trusted.
What I did
Corrections are new records, enforced by database constraints and an audit log, not only by application code.
07
Where it stands
Built
- Bilingual foundation, design system and PostgreSQL schema
- Staff and student authentication with roles and permissions
- Student administration, results and the student portal
Planned or in progress
- Fees and payment ledger
- Promotion and graduation
- Reports and further hardening