Case Study • ALT Coach / CPD Tracker
Back to portfolio

ALT Coach
CPD Tracker Platform

A multi-tenant CPD platform for educational organisations, combining lesson visit assessments, coaching workflows, professional development guidance, and video-recorded classroom observations across web and mobile clients.

Node.js + Express (ESM)MongoDB + MongooseReact 18 (CRA) + MUI v5Redux Toolkit + redux-persistFlutter / Dart (iOS + Android)JWT + bcryptjs + JoiCloudflare R2 + ImagesMicrosoft Graph / OneDriveNode:test + Supertest + mongodb-memory-serverMulter + Nodemailer (Gmail OAuth)

Executive Summary

Core Pattern

Shared Node API with React admin UI and Flutter mobile app

Education Fit

Tenant-configurable hierarchy, principles, questions, guides, and role-based workflows

Video Strategy

Direct uploads to R2 or OneDrive with mobile retry queue and provider validation

Quality Signal

Isolated server tests plus broad Flutter widget/repository coverage

Overview

Problem, opportunity, and role.

The Problem

Schools need a usable system for lesson visit assessments, coaching workflows, guides, and recorded classroom observations, but those workflows span web admin, classroom/mobile capture, storage integrations, and strict role/tenant boundaries.

The Opportunity

Build a multi-tenant CPD platform with a shared backend and two fit-for-purpose clients: a React admin/data workflow UI and a Flutter mobile experience for classroom capture, analysis, and resilient video uploads.

My Role

Product architect and hands-on engineer across backend API design, data modeling, auth and storage integration, reporting pipelines, React admin workflows, and mobile architecture/testability decisions.

Constraints & Design Pressures

  • Educational tenant structures vary (location/division/level models and permissions)
  • Need for both admin-heavy web workflows and mobile in-field capture
  • Video storage/provider differences across organisations
  • Connectivity variability in real classroom/mobile environments
  • Role-based restrictions across web and mobile filter/action surfaces
  • Reporting needs require efficient aggregate outputs and flexible filter payloads

Architecture Decisions

Multi-tenant CPD platform built around channel-specific client strengths.

The architecture separates backend domain/API concerns from two distinct clients: a web admin/data workflow interface and a mobile field app for capture, coaching, and upload resilience. The platform decisions prioritize education-domain configurability and practical video operations.

Cross-Platform Runtime Flows

  1. 1Admin creates a user -> backend auto-generates initial password, hashes it, stores firstTimeLogin flag, and sends welcome email.
  2. 2User logs in -> backend validates credentials, returns JWT + user object + roles for role-based UI gating.
  3. 3Assessment forms and reports -> server applies org/location/division/level/date filters and aggregates by principle/question.
  4. 4Mobile video capture -> app records locally, selects org StorageConfig, then uploads directly via R2 presigned URL or Graph upload session.
  5. 5Connectivity loss during mobile upload -> failed uploads queue and retry when connectivity_plus detects reconnect.
  6. 6Video playback -> backend resolves provider-specific access (presigned GET or Graph download URL) without exposing raw storage credentials.
  7. 7Guides/content -> admins author via TipTap on web, while mobile renders guide HTML content for field use.

Why These Decisions

Three-package monorepo (server, web, mobile)

Why: The product needed shared domain behavior across channels while allowing each client to use tooling suited to its interaction model (data-heavy web admin vs mobile classroom workflows).

Impact: Clear separation of platform responsibilities with coordinated feature delivery across backend, web, and mobile.

Dual-provider video storage (OneDrive or Cloudflare R2)

Why: Different organisations have different enterprise requirements and infrastructure preferences for video storage.

Impact: Per-org storage flexibility with a validation workflow and graceful degradation when providers are not configured.

Direct-to-storage uploads via presigned/session flows

Why: Video files should not transit the API server due to payload size, cost, and reliability concerns.

Impact: Scalable upload path, reduced server load, and better mobile upload ergonomics.

Repository pattern + dependency injection in Flutter

Why: Mobile screens needed to be testable without real HTTP calls and support feature-level isolation.

Impact: 30+ tests across screens/repos/models with mockable dependencies and better long-term maintainability.

Assessment report aggregation in MongoDB

Why: Reporting screens need filtered aggregates by principle/question with percentages and DataGrid-style filters.

Impact: Server-side aggregation keeps clients lighter and enables consistent reporting outputs across web and mobile.

Startup initialization for principles

Why: Principles are foundational to lesson assessment workflows and must exist reliably per organisation.

Impact: Reduced admin setup friction and safer assumptions across assessment forms and reports.

Friendly duplicate-key error translation in model hooks

Why: Admin-heavy workflows generate duplicate-name/email edge cases frequently and raw Mongo errors harm UX.

Impact: Cleaner user-facing validation feedback without leaking database internals.

Backend (Server)

Node/Express + Mongo platform services for CPD workflows, reporting, and video operations.

The server is the shared backbone for both clients: authentication, hierarchy/tenant data, assessments/coaching domains, reporting aggregates, guide content, and video storage integration management.

Auth, Password Reset, and Onboarding

01

JWT auth with bcrypt hashing, admin-created users, welcome emails, password reset tokens/expiry, first-time login flag, and bearer-token middleware verification.

  • Auto-generated initial passwords on admin user creation
  • Crypto reset token + expiry on user model
  • firstTimeLogin flag for onboarding flow
  • Joi validation + JWT middleware

Multi-tenant Identity and Admin Data Model

02

Organisation, users, roles, and user-role junction models with audit/status fields and friendly duplicate-key error translation.

  • Role examples: System Admin / Trust Admin / User
  • UserRole unique compound index
  • Organisation and User post-save duplicate key translation
  • User model supports org/location/division/level scoping

Assessment Domain + Reporting Pipeline

03

Lesson visit assessments capture structured question responses, strength/growth flags, notes, and org hierarchy refs, with aggregation-driven reporting by principle and question.

  • Principle and PrincipleQuestion domain models
  • Compound indexes on Assessment
  • MUI DataGrid filter payload compatibility on reports endpoint
  • AssessmentReport output shape with percentages

Coaching and Video Visit Workflow

04

CoachingFeed entries and VideoVisit records connect lesson visits, coaching notes, upload status, device metadata, storage provider file references, and audit fields.

  • Phase-based coaching workflow (Identify/Action Step/Model/Review)
  • VideoVisit status machine (recording -> uploaded/failed)
  • Device/app metadata capture
  • Optional links to Assessment and CoachingFeed

Guides and Structured Content

05

Guide collections support structured rich content blocks for application guidance, deliberate practice, instructional coaching, and project overview content.

  • Reusable structured content block schema
  • Separate collections per guide category
  • Status and publish/archive lifecycle fields
  • Admin editing flows via web client

Storage Configuration + Validation

06

Per-organisation StorageConfig supports R2 or OneDrive, validation status/error tracking, and secure handling of secrets in API output.

  • clientSecret omitted from JSON output (hasClientSecret boolean)
  • Validation timestamps and error storage
  • Provider-specific config fields (drive/folder/tenant/client)
  • Per-org storage settings power mobile upload flows

Storage Services (R2 + OneDrive)

07

Cloudflare R2 uses S3-compatible presigned URLs; Microsoft Graph supports client-credentials auth and large-file chunked upload sessions.

  • Presigned PUT/GET URLs for R2
  • Graph createUploadSession for large files
  • Folder resolution by item ID or path
  • 501 guard when provider env config is missing

Startup, Security, and Platform Basics

08

Express middleware stack with Helmet/Morgan/Multer, route coverage across domain areas, and startup initialization of principles for all organisations.

  • Native ESM server
  • Helmet + Morgan + Joi validation
  • initialisePrinciples at startup
  • 20 route files across product/admin domains

Server Testability and Isolation

09

Node test runner + Supertest + mongodb-memory-server enable isolated CI-friendly tests without an external database dependency.

  • 11 test files across auth/admin/assessments/coaching/guides/storage/video
  • Shared test_helpers setup/teardown
  • In-memory MongoDB for fast and isolated runs
  • API behavior validation with real Express routes

Web Client (React)

Admin and analysis workflows optimized for data density and content authoring.

The React client is tuned for operational/admin usage: DataGrid-based management screens, filter-heavy analytics, and content authoring tools, all layered on role-based access and persisted global state.

Admin/Data Workflow UI

01

React 18 (CRA) + MUI v5 app with Redux Toolkit, DataGrid-heavy admin pages, role-based routing, and responsive layout patterns for data management.

  • MUI DataGrid for assessment and admin views
  • Redux Toolkit + redux-persist state
  • React Router v7 route organization
  • Sidebar + responsive drawer layout

Assessment Capture and Reporting UX

02

Lesson visit forms and T&L reporting graphs with rich filter panels and responsive behavior for location/division/level/person/date slicing.

  • T&L Principles Graph (principle-level aggregates)
  • T&L Foci Graph (question-level aggregates)
  • Responsive filter panel behavior
  • View/edit assessment flows

Coaching and Video Visit Interfaces

03

Coaching feed/index workflows and video visit list/playback with status filtering, aligned to backend coaching/video models.

  • Coaching feed + tabular coaching index
  • Create/edit coaching entries
  • Video visit list with status filters
  • Playback UI integration

Guides Authoring and Rendering

04

Admin-authored guides use TipTap with a shared editor wrapper, while rendered guide content is sanitized via DOMPurify.

  • TipTapWrapper with formatting toolbar
  • Guide viewers for multiple guide types
  • Rich text + images + structured block content
  • DOMPurify sanitization for safe rendering

Admin Panel Coverage

05

Separate admin pages for organisations, users, hierarchy entities, roles, principles/questions, and storage config with validation UI.

  • User admin (roles + org/location/division/level)
  • Principles and principle questions admin
  • Storage config validation UI for OneDrive/R2
  • Organisation/location/division/level admin pages

Forms, Uploads, and Content UX

06

Formik/Yup validation, drag/drop file and list interactions, lightbox viewing, and utility components support higher-velocity admin workflows.

  • Formik + Yup form validation
  • react-dropzone uploads
  • @hello-pangea/dnd reorderable lists
  • Lightbox and shared utility components

Mobile App (Flutter)

Field-ready capture, coaching, and video workflows with offline-aware upload resilience.

The Flutter app is not a thin wrapper. It includes role-aware analysis screens, lesson visit entry, coaching workflows, and a full in-app video recording/upload pipeline designed for inconsistent connectivity environments.

Mobile Architecture + Session Model

01

Flutter app uses repository-per-feature patterns, model serialization helpers, constructor-based dependency injection, and shared_preferences session persistence.

  • Repository pattern per feature area
  • fromMap()/toPayload() model methods
  • Session service for token/user persistence
  • Constructor-injected dependencies for testability

Guidance, Assessment, and Coaching Flows

02

Drawer-based navigation groups guidance, analysis, coaching, and account experiences, including lesson visits, graphs, coaching feed/table, and guide content.

  • AssessmentReportScreen shared across principles/foci graphs
  • LessonVisitsScreen + bottom-sheet assessment form
  • Coaching feed + coaching table screens
  • HTML guide rendering via flutter_widget_from_html_core

Video Capture and Upload Pipeline

03

In-app camera recording with local temp storage, storage-config-aware upload selection, progress tracking, and provider-specific upload strategies.

  • camera plugin recording flow
  • R2 presigned upload or Graph upload session
  • StorageConfig selection per org
  • Lesson ID linkage to visit record

Offline-resilient Upload Queue

04

Connectivity-aware upload retry logic queues failed video uploads and resumes processing automatically when network connectivity returns.

  • connectivity_plus stream listener
  • Queue + retry behavior on reconnect
  • Reduced upload-loss risk in classroom/mobile contexts
  • Status-driven user feedback

Role-aware Mobile UX

05

Permission flags lock filter fields and actions for non-admin users, aligning mobile behavior with tenant/role constraints from the backend.

  • getPermissionFlags(user, roles) utility
  • Auto-lock of non-admin location/division/level filters
  • Consistent role-aware visibility across screens
  • Shared auth and session gating

Mobile Test Coverage

06

30+ tests cover widgets, repositories, models, navigation, and auth flows with mocked HTTP responses and coverage reporting.

  • Widget tests for major screens
  • Auth/drawer/login/logout integration tests
  • Repository tests with mocked HTTP
  • Coverage reports committed to coverage/

Tradeoffs & Constraints

Delivery pragmatism across security, storage flexibility, and mobile reliability.

The product balances educational workflow complexity, multi-tenant flexibility, and media-heavy mobile usage. The strongest signal is not perfection; it is clear engineering tradeoffs with obvious future hardening paths.

Two client apps (web + mobile) vs simpler single-client delivery

Rationale: School workflows span admin/data management and in-classroom capture, which have very different UX and platform requirements.

Tradeoff: Higher coordination overhead, but much better fit for each operational context.

Dual video storage provider support vs simpler single-provider integration

Rationale: Organisations may require enterprise OneDrive/SharePoint or prefer R2-style object storage.

Tradeoff: More configuration and validation complexity, but stronger tenant flexibility and adoption fit.

Direct uploads + mobile queueing vs API-proxied uploads

Rationale: Video uploads are large and mobile connectivity can be unreliable.

Tradeoff: More storage integration logic on client/server, but reduced backend load and significantly better upload resilience.

Rich admin configurability vs simpler fixed workflows

Rationale: Educational organisations differ in hierarchy structure, principles, questions, and storage constraints.

Tradeoff: Broader configuration/test surface area, but a more deployable multi-tenant product.

JWT login tokens without expiry (current login flow) vs stricter expiry model

Rationale: Pragmatic delivery choice for session simplicity in the current implementation.

Tradeoff: Operational simplicity now, but a clear security hardening opportunity for future iteration.

Outcomes / Metrics

Strong product and engineering signals across API, web, and mobile surfaces.

Public metrics are not included here, but the architecture and implementation outcomes show substantial platform depth across tenant administration, instructional workflows, reporting, and video operations.

Outcomes / Delivery Signals

  • Delivered a true multi-channel product architecture: shared backend with React admin client and Flutter mobile app.
  • Implemented robust video workflows with dual-provider storage support and direct-upload patterns.
  • Created a reporting pipeline that supports both web and mobile T&L analytics experiences from the same backend aggregations.
  • Built substantial admin configurability for organisations, users, hierarchy data, principles, questions, and storage config.
  • Enabled practical mobile reliability through upload queue retry behavior and connectivity-aware processing.
  • Maintained strong engineering quality signals through isolated server tests and broad mobile test coverage.

Quality / Maturity Signals

  • Server tests use node:test + Supertest + mongodb-memory-server (no external DB dependency in CI)
  • 11 server test files across auth, admin, assessments, guides, storage config, and video visits
  • 30+ Flutter tests across widgets, repositories, models, and navigation/auth flows
  • StorageConfig secret obfuscation in API output (hasClientSecret instead of raw clientSecret)
  • Graceful 501 behavior when optional storage integrations are not configured
  • MUI DataGrid filter payload normalization support in reporting endpoints

What I'd Improve Next

Harden auth/session strategy and deepen shared contract discipline.

The platform already demonstrates strong cross-channel design. The next gains are in security hardening, contract standardization, and observability for media-heavy mobile workflows.

Standardize token expiry/refresh behavior (current login token lifetime is a clear hardening target).

Consider stronger initial password onboarding strategy (e.g., invite tokens/magic links) to replace deterministic password generation.

Extract shared API schemas/contracts to reduce drift between web and mobile clients over time.

Add deeper observability on mobile upload failures/retries and provider-specific error rates.

Continue modularizing larger controllers/services as feature scope expands.

Evaluate shared domain packages for validation/DTOs across server and client apps where practical.

Contact

Building a multi-channel product with operational complexity?

I can help shape the backend, admin workflows, and mobile delivery architecture so the product remains usable and maintainable as it grows.