Skip to content

TAP LMS — Reusability Booklet for the Next Project

Prepared by: Nithun Date: 2026-06-16 · Status: For review Backed by: a full audit of the Summer Program codebase (see Where the detail lives, end of booklet)


The short answer

Most of what we built carries forward. The messaging, scheduling, reliability, and operations layers are program-agnostic and reuse as-is. What a new project rebuilds is its content and its own rules — not the plumbing.

We'd add each new program as its own thin layer on a shared core, so it's cheap to build and cannot affect the running Summer Program. And this isn't an optimistic claim: we audited every hardcoded decision in the core against the live code and data — the "rebuild surface" is small, now precisely mapped, and the code is healthy (only three real bugs across the whole module, one already fixed).

This booklet has three parts: what's reusable (§1–2), how we'd reuse it (§3, the strategy), and what the deep audit confirmed (§6, the evidence).

A rule of thumb while reading: the closer a component sits to the Summer Program's content and rules, the more adaptation it needs; the closer it sits to plumbing (messaging, scheduling, reliability, operations), the more it lifts wholesale.


At a glance — what carries over

What carries over to the next project Reusable as-is • Journey engine (state machine) • Dispatcher (~240K/hr) • WhatsApp / Glific layer • API standard for flows • Retry + dead-letter queues • Ops & diagnostic toolkit • Testing + load harness • Process / docs system Reusable with adaptation • Submission + AI feedback • Escalation machinery • Parent-call (Vocallabs) • Gamification engine • Enrollment / cohorts • Weekly content delivery swap rules / partners / scoring New each time • Lesson / quiz content • WhatsApp flow copy • Program states + week rules the program's own content and rules — by nature Plumbing — paid for Content & rules — per program

The three buckets at a glance: the left two we hand the next project; only the right one is rebuilt. §1–2 detail them; §3 is how the rebuild is done cheaply.

1. Reusable as-is (no rebuild needed)

Program-agnostic. A new project on the same platform inherits these with little or no change.

Student journey engine (state machine). The heart of the system: every student is always in exactly one named "state" (active, paused, escalated, dropped, completed, …), and every movement between states goes through one central engine that updates the record, writes an audit trail, and notifies WhatsApp — in one consistent step. A new program defines its own states and transitions; the engine, audit logging, and messaging sync come for free. This was the hardest part of the build and the single most valuable thing to carry forward.

Automated scheduler ("the dispatcher"). A background engine that wakes every minute, finds every student whose "next action" is due, and runs it — at a tested capacity of ~240,000 student-actions per hour. What runs is configuration; the engine doesn't care whether the program is about art, coding, or reading.

WhatsApp (Glific) integration layer. All the wiring for talking to WhatsApp through Glific: pushing student status into contact fields so chat flows can branch on it, moving students between messaging groups as their status changes, and receiving callbacks when a student taps a button or submits. The connection code, group-membership maintenance, and callback endpoints are reusable; only the list of fields and groups is program-specific.

API standard for chat-flow integrations. A written contract (docs/api-standard-glific.md) for how every backend endpoint a WhatsApp flow calls must shape its responses. It cost real iteration to get right and applies unchanged to any future messaging-driven project. Hand it to the next team on day one.

Reliability patterns (retry + dead-letter queues). Every external call (WhatsApp, parent-calling, feedback pipeline) is wrapped so temporary failures retry automatically and permanent ones land in a visible "needs attention" queue instead of disappearing. Generic.

Operational and diagnostic toolkit. Ready-made health checks and admin commands (student-health lookup, cohort drift checks, queue-failure triage, stale-record audits) plus a deployment runbook. Operations on the next project start from a mature toolkit, not zero.

Testing assets. Test data factories, written test runbooks, and a load-testing harness that proved the throughput above. The patterns transfer directly; only endpoint names change.

Project process assets. The documentation system itself: the living architecture document, change-request and architecture-decision-record templates, code-review and retrospective formats, and the AI-assisted development tooling (skills, agents, project memory). These made the project auditable and are entirely portable.


2. Reusable with adaptation (swap the program-specific parts)

These work end-to-end today but encode Summer Program rules or partner services. The structure is reusable; the rules and partners are pluggable. §3 explains exactly how the swap is done.

Submission and AI-feedback pipeline. Student sends work on WhatsApp → stored → queued to an external AI feedback service → feedback written back and delivered, with a watchdog for anything stuck. The pipeline shape (queue in, process out, callback, watchdog) is fully reusable; the feedback prompts and content types are program-specific.

Escalation module. The "weekly nudge" system: if a student goes quiet, a grace window opens, then escalating interventions fire — WhatsApp nudges and, for some student profiles, an automated parent call. The machinery (rules engine, scheduling, channel dispatch) is reusable; the specific rules (how many days, which profile gets which intervention) are configuration retuned per program.

Parent-call automation (Vocallabs). Automated outbound voice calls with retry and failure budgets. Reusable wherever voice outreach is wanted; swapping the voice vendor means rewriting one integration module, not the surrounding logic.

Gamification (points, gems, streaks). Three point streams plus gems and weekly streaks, with race-safe counting (two simultaneous submissions can't double-award) and weekly resets. The counting machinery is solid and reusable; the scoring rules are per-program design decisions.

Enrollment and cohort management. Batch (cohort) setup, bulk student import, per-cohort program runs, auto-activation on the start date, weekly calendar advancement. Any cohort-based program reuses this; field names and program length are configuration.

Weekly content delivery. Scheduled push of each week's content to the cohort's WhatsApp group, gated so students can't run ahead of the calendar. Reusable for any week-paced program.


3. How we'd add the next program (the strategy)

The next project does not have to be a fork of this one. The clean way to add a new program is three layers:

  1. Shared core (code, every program uses it untouched) — the journey engine, the dispatcher, the WhatsApp layer, the reliability wrappers, the gamification counting. Built once; never re-touched per program.
  2. Per-program module (code, one program owns it) — that program's own states, rules, handlers, and scoring. Built once per program — and because it's its own module, a new program cannot break the running Summer Program.
  3. Per-batch configuration (data, one cohort) — weeks, dates, escalation ladders, points, flow IDs. Operators set these in the UI per cohort; no code.

The system already has the seam for this. Every batch carries a program type (the schema already lists Summer / Regular). The Summer logic only acts on Summer batches, so a new type can be added alongside without touching Summer — physical isolation, not a promise.

Four ways to make something differ per program (pick the lightest that fits): - It's a value (a number, a threshold, a list) → put it in configuration. - It's a behavior (a different rule or algorithm) → give the new program its own handler (a small registry the core dispatches through). - The data already encodes it (e.g. the difficulty ramp is already tagged on the curriculum) → read it from the data, don't keep a parallel constant. - It's an on/off of an existing behavior (e.g. "no binge-pause") → a config flag.

The guiding principle: generalize from the second program, not speculatively. You don't truly know what's common between programs until you've built two. So we keep one shared core and build the second program as its own module when it's real — letting it pull the shared abstractions out, rather than guessing them now (which would over-fit to Summer's quirks).

One honest caveat. Today the program-type seam isolates the messaging and API layer cleanly, but not yet the full engine (a couple of internal dispatch points are shared across programs). Making the engine fully program-aware is one focused refactor — a per-program "handler registry" — best done when the second program is real and actually needs it. That refactor is scoped and documented (docs/adding-a-new-program-type.md); it is not a rewrite.


4. Proven designs worth copying (even where the code is program-specific)

Less "lift the code," more "don't re-solve the problem":

  • How to keep a student's individual journey and the cohort's shared calendar in sync without conflicts.
  • How to run grace windows that arm and expire themselves with no manual cleanup.
  • How to make weekly counters reset cleanly while permanent flags stick.
  • How to treat student profiles (archetypes) and experiment arms as upstream-supplied data the system never invents — which kept our A/B experimentation clean.

5. What is not reusable

To set expectations honestly: the Summer Program's content (lessons, quizzes, flow copy), the specific WhatsApp flow definitions inside Glific, the program's particular state names and week structure, and the legacy onboarding screens predating this build. These are per-program by nature — and they're exactly the "content + rules" the next project's effort should concentrate on.


6. What the deep audit confirmed (the evidence behind the claim)

We didn't just assert reusability — we audited every hardcoded decision in the core Summer Program module against the live code and data, one by one. The takeaways for planning:

  • The rebuild surface is small and now precisely mapped. An initial scan flagged ~15 "blockers." On verification, most turned out to be well-structured, by-design (e.g. the program-type isolation is a feature), or low-stakes (reporting/telemetry, not engine logic). The genuine per-program work is a handful of configuration-lifts plus the one engine-isolation refactor from §3.
  • The code is healthy. Across the whole module the audit found only three real bugs — one already fixed, two queued as one-line fixes. For a system of this size driving 70k+ students, that's a strong signal.
  • The reuse claim is grounded, not optimistic. Because the analysis went down to the code and the data (not just the architecture diagram), the Design team can plan on the "reusable" and "reusable with adaptation" lists being real.

Every finding, with its verdict and disposition, is recorded for the engineers (see below).


7. Summary for planning

If the next project needs… We already have… Rebuild needed?
Students moving through a staged journey Journey engine + audit trail No — configure states
Timed, per-student automation at scale Minute-level dispatcher (~240K actions/hr) No
WhatsApp-driven interaction Glific layer + API standard + callbacks No — define fields/flows
Nudges & escalation for inactive users Escalation machinery Rules only
Automated parent/guardian calls Vocallabs integration Vendor swap at most
Work submission + AI feedback Full pipeline + watchdog Prompts/content only
Points, streaks, rewards Race-safe gamification engine Scoring rules only
Cohorts, imports, weekly pacing Batch/enrollment/calendar stack Configuration
A different program on the same engine Three-layer model + program-type seam (§3) New program module + the one-time core-isolation refactor
Reliable ops from day one Runbooks, diagnostics, load tests, retry/DLQ No

The practical implication: the next project's effort concentrates on content, journey definition, and program rules — not on messaging plumbing, scheduling, reliability, or operations, which are paid for. The one engineering investment worth planning for is the per-program isolation refactor (§3), done when the second program is real.


Where the detail lives (for the engineering team)

  • docs/reusable-components.md — this booklet.
  • docs/adding-a-new-program-type.md — the developer playbook for §3: the three layers, the four mechanisms, worked examples (no binge-pause, different week advancement, different difficulty ramp), and the checklist for adding a program type.
  • docs/hardcoded-logic-audit.md — the full per-finding audit behind §6: every hardcoded decision, its verdict, and its fix.
  • docs/prds/ — the next-version PRDs (parent-call persona config; experiment-arm coverage; gamification/quiz hardcode removal) and the campaign tracker (README.md) with every finding's disposition.
  • docs/api-standard-glific.md — the chat-flow API contract (§1).