A full-stack open-source contribution to Scientia, Imperial College London's Department of Computing e-learning platform.
Scientia is the unified EdTech platform used across Imperial's Department of Computing — a role-aware React front end sitting in front of a fleet of microservices for exercises, e-marking, materials, module selection, tutoring, and PhD tracking.
The Module Progress Tracker is a feature added to that platform: a lightweight way for students to log a weekly confidence score (1–10) per module in seconds, and for teaching staff to see, on a live dashboard, how well material is landing across a term. It is designed to surface struggling cohorts early — turning a term's worth of informal "how's it going?" into structured, queryable signal.
This repository contains the complete contribution — a new FastAPI microservice, its gateway integration, and the React front end — alongside the Scientia frontend platform it plugs into. It is a genuinely full-stack addition, not a frontend widget.
For students
- A
Progress Reporttab on each enrolled module. - Submit a confidence score (1–10) for the current teaching week in a couple of clicks.
- Submissions are enrollment-gated — only students registered for a module can score it.
For staff
- A dashboard aggregating scores per module and per week: average score and response count.
- A confidence trend chart (Recharts) that makes a dip in a given week visible at a glance.
The tracker follows Scientia's existing microservice pattern. The React SPA talks only to a Gateway API (JWT-cookie auth); the gateway proxies to domain microservices. This feature adds one new service and wires it through the gateway.
Browser
└── NGINX
├── / → React SPA ── ProgressReport pages (StudentView / StaffView)
└── /api/ → Gateway API
├── Materials
├── e-Marking
├── Module Selection ──┐ (registration source)
├── Tutoring │
├── PhD Tracking │
└── Progress Report ◀──┘ ← this contribution
│
└── PostgreSQL (own database)
Three parts make up the contribution:
-
Progress Report microservice —
progress-report-service/. A standalone FastAPI service with its own PostgreSQL database. It exposesPOST /feedback(submit a weekly score) andGET /feedback/summary(per-module, per-week aggregates), and runs a scheduled task that syncs student–module registrations from the module-selection service so eligibility stays current. It owns no registration data of its own, and can be switched off or removed without touching any other service. See its README for the API and data model. -
Gateway integration — the feature is exposed to the client through the Scientia Gateway API, matching how every other microservice is reached: authorised feedback endpoints registered on the router, an upstream forwarder to the microservice, and request/response schemas.
-
Frontend — a
ProgressReportarea undersrc/pages/Module/that rendersStudentVieworStaffViewbased on the user's role, with all gateway calls encapsulated in dedicated hooks (submit / retrieve / summarise). UI is built with Radix (inheriting the user's chosen accent colour) so it is visually native to Scientia.
.
├── src/ # Scientia React + TypeScript front end
│ ├── pages/Module/ProgressReport/ # Student & staff views for this feature
│ ├── pages/ # The wider platform (exercises, materials, timeline, …)
│ ├── components/ · hooks/ · contextManagers/ · types/
│ └── constants/endpoints.ts # Gateway endpoints (incl. the new feedback routes)
├── progress-report-service/ # FastAPI microservice + PostgreSQL (the backend)
├── C4_DIAGRAMS.md # C4 architecture diagrams (context → component)
├── dev.docker-compose.yml # Local multi-service stack
└── public/ # Static assets
- A separate service and database, by design. Rather than bolting onto an existing microservice, the tracker is fully self-contained so a trial feature can be removed cleanly if it proves unhelpful — at the cost of standing up a new service, gateway wiring, and its own persistence. That reversibility was judged worth the overhead.
- Enrollment as derived, not owned. The service never becomes a second source of truth for registrations. It pulls
(student, module, year)pairs from the module-selection database on a schedule and gates submissions against that snapshot, keyed to the academic year so the dataset stays a constant size rather than growing indefinitely. - Immutable, retained feedback. Scores can't be edited or deleted once submitted — this captures genuine "in-the-moment" sentiment and removes a whole class of data-loss bugs. Feedback from a student who later drops a module is kept: it is still a valid datapoint and it makes the rejoin case trivial.
- Referential integrity. Weekly feedback is tied to an enrollment by a foreign key, so orphaned scores with no matching registration cannot exist.
- Built with a hexagonal / layered structure — API routers, schemas (Pydantic v2), ORM models (SQLModel), and scheduled tasks are separated, so the matching and aggregation logic is testable without a running web server.
The service currently models feedback as ten fixed week-columns per enrollment — simple and constant-time to read, but it assumes a ten-week term. A fully normalised one row per (student, module, week) design would generalise to multi-term modules and variable teaching-week counts and avoid empty columns; the right time to make that change is once database migrations (Alembic) are in place to manage the schema evolution safely.
| Layer | Technology |
|---|---|
| Frontend | React 18, TypeScript 5, Radix UI Themes, Tailwind CSS, React Router v6 |
| Data viz | Recharts (confidence trends), TanStack Table |
| Data fetching | Axios with context-managed JWT-cookie auth |
| Backend | FastAPI, SQLModel, SQLAlchemy, Pydantic v2 |
| Database | PostgreSQL (psycopg2) |
| Scheduling | APScheduler (nightly enrollment sync) |
| Tooling | Poetry, Docker, factory_boy, pytest · ESLint, Prettier, Jest |
cd progress-report-service
poetry install
poetry run fastapi dev # http://localhost:8005 (OpenAPI docs at /docs)
poetry run python seed_data.py # optional: seed development dataSee progress-report-service/README.md for the full API, data model, and Docker instructions.
yarn install
yarn start # http://localhost:3000Or bring up the multi-service stack with Docker:
docker compose -f dev.docker-compose.yml up# Backend
cd progress-report-service && poetry run pytest
# Frontend
yarn testBackend tests use factory_boy factories to generate ORM fixtures, so the API is exercised against a seeded database rather than hand-entered data. Frontend tests use React Testing Library and Jest.
C4_DIAGRAMS.md documents the system from context down to the internal components of the Progress Report service (C4 levels 1–4).
The Module Progress Tracker was designed and built by a small team as a contribution to Scientia, the open-source EdTech platform developed and maintained by Imperial DoC EdTech. It builds on that platform's existing microservice architecture, gateway pattern, and component library.
MIT — Edward Xu, 2026