← All work

Academic Program Operations

Turning a school program that ran on disconnected documents into an operations platform: what was taught, by whom, how long it took, and how it landed.

Context

A non-profit runs an executive-functioning curriculum in schools, lessons on focus, emotional regulation, and time management, taught by regular classroom teachers rather than specialists. The program is only as good as its delivery: if teachers skip lessons, rush them, or the material doesn't land, nobody finds out until the year is over.

The problem

Planning and delivery lived across disconnected documents and spreadsheets. The organization could not answer basic operational questions: which lessons were actually delivered, in which grades, by which teachers, how long each one took to prepare and to teach, and how teachers rated them.

What I owned

The full build, solo: data model, authorization, both role experiences, the analytics layer, and the deployment pipeline. Built with Next.js and Supabase, with plain token-based CSS instead of a UI framework.

How it works

Two roles, one loop
Teacherpicks a lesson for their gradeDelivers ittimer runningRates & commentsprep, engagement, contentProgram adminsees implementation health
Every delivery a teacher logs becomes a data point the program can act on, without anyone filling in a separate report
Program analytics: active teachers and classes, lessons delivered, ratings by grade and dimension, and teacher activity
Implementation health across teachers, grades, and lessons (production screenshot, brand and names anonymized)

Key decisions

  • Authorization lives in the database, not the UI. Row-level security policies are the authorization layer, so a teacher cannot read another teacher's classes or feedback even if a page or an API route were wrong. The app-level checks are a convenience on top, not the actual guarantee.
  • No UI framework. The portal runs on low-spec school Chromebooks, so I wrote plain token-based CSS ported from the brand system instead of shipping a component library. Fast first render, no dependency to maintain, and WCAG AA contrast throughout.
  • The portal indexes content, it doesn't host it. Lesson material stays where the team already maintains it. Rebuilding a document system would have doubled the scope and given the client something worse than what they had.
  • Two roles, deliberately. Admin and teacher. Every request for a third role got pushed back until the pilot proved it was needed.
Lesson timing report: average preparation and classroom delivery time, broken down by grade and teacher
Preparation versus classroom time, by grade and by teacher, from submitted feedback (production screenshot, brand and names anonymized)

Verification & delivery

74 unit test files plus Playwright end-to-end coverage, CI on every change, and a promotion workflow enforced by GitHub Actions so nothing reaches production without passing through staging first. Database changes ship as versioned migrations, 24 of them so far.

Outcome

In pilot with a school district across two grade levels. The program team can now see, without asking anyone, how much of the curriculum has been delivered, how teachers rate each lesson on preparation, engagement and content, and where preparation time is out of line with classroom time.

What I'd improve today

The analytics answer "what happened". The next useful step is "what needs attention": flagging a class that has fallen behind pace, or a lesson that consistently rates low, instead of leaving an admin to spot it in a table.

NDA note: the client, the program brand, and the district are withheld. Screenshots are real production screens with the brand and every personal name and email replaced with fictional ones.