Skip to content

Case Study · SAUT

Four Years, Two
Frameworks, One Mission.

How I built a Learning Management System for special educators teaching children with Down syndrome — then rewrote it from scratch when the architecture couldn't keep up.

2019 – 2023 EdTech · LMS Vue.js → SvelteKit · Rails · PostgreSQL

The result: a bilingual Arabic/English platform with offline-first assessments, a drag-and-drop worksheet builder, and a 65-feature release roadmap that shipped in full — built by a three-person dev team with no QA. The project grew my role from pure frontend developer into product manager and emergency UI designer.

SAUT LMS shown across tablet and mobile devices — bilingual Arabic interface with student profiles and skill modules

SAUT across devices — bilingual, RTL-first, designed for classrooms.

SAUT is a school in Riyadh for children with Down syndrome, backed by the Princess of Riyadh. The platform I built — also called SAUT — is a Learning Management System designed for their teachers: a tool for planning individualised curricula, running daily assessments, printing personalised learning materials, and tracking each child's progress across years of education.

The students never touch the software. Everything is in-person — flash cards on the table, worksheets on paper, assessments done face to face. The platform exists to help teachers do that work better: to know what each child has mastered, what they've forgotten, what to teach next. The technology serves the pedagogy, not the other way around.

I was on this project from day one to handoff — four-plus years. I built both versions of the frontend, managed the product roadmap, designed screens when the design team couldn't keep up, and helped ship all six release phases. It's the longest I've worked on any single product, and the one that taught me the most about what it means to build something that actually matters.

The complexity

This wasn't a simple CRUD app with a few forms. The data model alone would give you pause. A curriculum in SAUT has five levels of nesting: Curriculum → Domain → Category → Goal → Subgoal. Each subgoal carries its own assessment criteria, flashcards, lesson plans, and learning materials. Multiply that across every student, every classroom, every academic year.

Then there's assessment. Four different criteria types — a linear 5-point scale for most domains, binary pass/fail for others, an 8-point Makaton scale for sign language communication, and percentile-based scoring for early childhood. A subgoal is "complete" when a student hits a success threshold: say, three successful assessments out of five total attempts, non-consecutive. The system tracks all of this automatically.

The Scale

What the system had to handle.

01 9 user roles — from super admin to speech therapist, each with granular permissions
02 5-level curriculum hierarchy with linked references across schools
03 4 assessment criteria types — Linear, Binary, Makaton, Percentile
04 Offline-first daily assessments — syncs when connectivity returns
05 Bilingual Arabic/English with a live RTL ↔ LTR toggle
06 65+ features shipped across 6 phased releases

Nine user roles, each with a different slice of the system. A teacher creates IEPs and runs daily assessments. A supervisor reviews and approves them before they're finalised. A speech therapist only sees communication-related goals. The school admin manages staff but can't create IEPs. The super admin controls the curriculum across multiple schools. Every action in the system passes through an approval workflow — teacher creates, supervisor reviews, teacher finalises. The permission matrix had 66 rows.

V1 — the first build

V1 was built with Vue.js on the frontend and Ruby on Rails on the backend. I joined at Able.do (then called Uncommon) and this was one of my first major projects. For V1, I was 100% frontend — writing Vue components, building the assessment interfaces, the student profiles, the IEP creation flows. My colleague Surajith handled the functional plumbing; I took on the complex UI, the page animations, and the RTL work.

V1 worked. Teachers used it daily. Students were assessed, IEPs were created, reports were generated. But there was a fundamental architectural problem hiding under the surface, and it was getting worse with every school that adopted the system.

The duplication problem

In V1, when a teacher created an IEP for a student, the system copied goals and subgoals from the curriculum into the student's record. Every student got their own duplicate of every goal they were working on. If someone found a typo in the master curriculum, or restructured a category, or updated assessment criteria — none of those changes reached existing IEPs. You'd have to manually update every student's copy.

At one school, that was manageable. When the plan was to scale to multiple schools sharing the same curriculum, it was a time bomb. Imagine correcting a subgoal description and having to propagate that change across hundreds of student records across multiple institutions. It couldn't work.

The decision was made: complete rewrite. Not a refactor, not an incremental migration — a clean rebuild of the frontend and a restructuring of the backend data model. Central curriculum database with linked references instead of copies. Updates propagate automatically. No duplication.

V2 — the rewrite

We migrated the frontend from Vue.js to SvelteKit and restructured the Rails backend to support the new linked-reference architecture. The timeline was aggressive: kickoff in March 2023, beta by July 15, final release by August 1. Five months for a complete rewrite of a production system that teachers depended on daily.

The Migration

What changed between V1 and V2.

Frontend framework Vue.js SvelteKit + Tailwind
Data architecture Copied goals per student Linked references — single source of truth
Curriculum updates Manual propagation Automatic — edit once, propagates everywhere
School support Single-school Multi-school with centralised permissions
Assessment criteria Fixed per domain Flexible — overridable per student
IEP editing Locked after approval Versioned — case studies create new IEP versions
Offline support None Service worker — attendance and assessments sync on reconnection

The team was small: two frontend developers, one backend developer. No dedicated QA — we tested everything ourselves. I handled the complex UI work: the assessment interfaces, the curriculum browser, the student onboarding flows, all the page animations, and the entire RTL/LTR system. Surajith focused on the functional side — data fetching, state management, form handling.

We migrated all active student data, all curriculum content, all historical assessments and IEPs. Teachers had to log in to a new interface in August and keep working without missing a beat. The school year waits for no one.

Product demo — Student onboarding & IEP creation

Initial assessment → competency check → semester curriculum creation

The RTL challenge

SAUT is a bilingual application. The interface runs in both Arabic (right-to-left) and English (left-to-right), with a toggle that switches the entire UI live. This isn't just flipping direction: rtl on the body — it's every layout, every animation, every interaction.

Scroll animations that slide content in from the left? They need to slide from the right in RTL. A sidebar that opens from the left edge? It opens from the right. Progress bars that fill left-to-right? Reversed. Tab navigation, breadcrumbs, icon positions, text truncation, number formatting — everything mirrors. The CSS logical properties help (margin-inline-start instead of margin-left), but the edge cases are endless.

The curriculum content itself is in Arabic — domain names, goal descriptions, subgoal titles, flashcard labels. But the UI chrome, navigation, and structural elements needed to work in both directions. Teachers could switch languages without reloading, and the layout had to respond instantly.

Product demo — Daily classroom assessment

Teacher marks each student's progress on their assigned subgoals — all done in person

The roadmap

V2 wasn't a single release — it was a 65-feature roadmap phased across six versions. Phase 2.0 was the core: student onboarding, IEP creation, daily assessment, login. Each subsequent phase added a layer: materials library, case studies, worksheets, classgroups, reports at three levels (student, classroom, school), and finally a digital curriculum module for parents to subscribe to individually.

All six phases shipped. Every feature on the roadmap made it to production. For a three-person dev team working with daily client calls and no dedicated QA, that's the thing I keep coming back to. Not any single feature, but the fact that we planned sixty-five of them and delivered all sixty-five.

The team and the client

The design came from Tropics, an external design studio led by Zubin. They created the visual language and the Figma files. Our team at Able.do built the product: two frontend devs, one backend dev. The client team at SAUT — led by Haifa Alshaik — handled UAT and provided daily feedback.

We had daily calls. Not weekly check-ins — daily. The SAUT team would test new features, report issues, discuss improvements, and we'd plan the next steps together. That rhythm is what made the aggressive timeline possible. There was never a gap longer than a day between a question and an answer.

The stack

  • Frontend: SvelteKit + Tailwind CSS (V2), Vue.js (V1)
  • Backend: Ruby on Rails + PostgreSQL
  • Hosting: AWS Middle East region — $200-300/month operational cost
  • Security: Cloudflare — WAF, SSL/TLS, rate limiting, DDoS protection
  • Offline: Service worker with sync-on-reconnect for attendance and assessments
  • Testing: Rails unit tests + rspec (backend), vitest + Playwright (frontend)
  • Design: Figma — three files maintained by Tropics

The handoff

After four-plus years, the contract moved to a larger company based in the Middle East. SAUT is backed by the Princess of Riyadh, and as the project grew, the stakeholders wanted a regional team with a bigger name for investor visibility. It wasn't a performance decision — every phase had shipped, the product was stable, and the teachers were using it daily.

We handed off a fully documented, fully tested system with a complete product wiki, permission matrices, data migration guides, and operational runbooks. The kind of handoff where the receiving team can actually pick it up and keep going.

What I learned

  • A three-person team can ship a complex product if the communication loop is tight enough. Daily calls with the client removed ambiguity faster than any specification document.
  • Data architecture decisions made in year one define what's possible in year four. V1's copy-based model worked until it didn't — and "until it didn't" cost us a five-month rewrite.
  • RTL support isn't a feature you bolt on at the end. It's an architectural decision that shapes every component, every animation, every layout decision from day one.
  • Building the same product twice — first in Vue, then in Svelte — teaches you what the framework gave you and what was always just your code. Most of the hard problems were domain problems, not framework problems.
  • The best product knowledge comes from building every screen yourself. By V2, I could answer product questions faster than checking the spec because I'd already built the flows that the spec described.

Next up

7 min · 2023

Wearing Three Hats — Frontend Dev, PM, Designer

Essay · SAUT