Skip to content
All projects
BackendFull StackAPIsLive Build

Student Progress Tracker

A full-stack FastAPI + Next.js application for tracking individual student progress across a training cohort.

BACKEND
FastAPINext.jsSQLAlchemySQLiteREST APIs

Project Overview

A cohort-facing tool for recording and reviewing individual student progress, built as a full-stack exercise in getting the unglamorous parts of a backend right: correct data isolation, correct API contracts, and correct cross-origin behavior between a separately hosted frontend and API.

The Problem

Early versions of the tracker mixed up student records under concurrent use — one student's submitted progress could bleed into another's view. That's a data-isolation bug, and in a training-progress tool it's the single worst thing the system can get wrong.

Target Users

Trainees recording their own progress, and trainers/mentors reviewing progress across a full cohort.

Goals

  • Guarantee that each student's data is strictly isolated from every other student's
  • Return well-formed, predictable JSON from every write endpoint
  • Serve a Next.js frontend hosted separately from the FastAPI backend without CORS failures

Challenges

  • A multi-student data isolation bug where records were not being scoped correctly per user, causing cross-contamination between student views
  • POST endpoints returning inconsistent or incomplete response objects, breaking the frontend's ability to immediately reflect a successful write
  • CORS misconfiguration blocking the deployed frontend from reaching the API in certain environments

Proposed Solution

Traced the data-isolation bug to missing scoping on the query layer (records were being fetched without a strict per-student filter) and fixed it at the query level rather than patching it in the frontend. Standardized every POST route to return the full created/updated object, matching what the frontend expected. Corrected CORS middleware configuration to explicitly allow the deployed frontend origin.

System & Technical Architecture

Next.js frontend (deployed separately) → FastAPI REST API with CORS middleware → SQLAlchemy ORM → SQLite (dev) — each request scoped to an authenticated student or trainer context before hitting the database layer.

Next.js Client
CORS Middleware
FastAPI Routes
SQLAlchemy Query Layer (scoped)
SQLite

Database Design

Students, progress_entries (linked to a student_id foreign key with an enforced query-time filter), and cohort metadata.

API Design

Every mutating endpoint (POST/PUT) returns the full resulting object rather than a bare status message, so the frontend can update its state directly from the response instead of issuing a follow-up GET.

Key Features

  • Per-student progress logging with strict data isolation
  • Trainer-facing cohort overview
  • Consistent REST response contracts across all endpoints
  • Deployed frontend/backend split with correctly configured CORS

Technical Decisions

Fixed data isolation at the query layer, not the UI

Filtering in the frontend would have left the underlying API insecure and reproducible by anyone calling it directly — the fix had to live where the data was actually fetched.

Standardized POST responses to return full objects

The frontend was written to expect the created resource back immediately; returning only a status code forced unnecessary extra requests and out-of-sync UI state.

Testing Strategy

Manual testing across multiple concurrent student sessions specifically to catch cross-contamination, plus endpoint-level testing of each POST/PUT contract.

Security Considerations

Per-student query scoping doubles as an access-control boundary no student-facing route can return another student's records regardless of how the request is shaped.

Results & Outcomes

A working full-stack application with the data-isolation, response-contract, and CORS issues resolved and verified. [Placeholder: add cohort usage numbers if this is put in front of a live cohort.]

Lessons Learned

  • Data isolation bugs are easy to miss in single-user manual testing they only show up under realistic concurrent use
  • Frontend and backend response-contract mismatches are often mistaken for frontend bugs when the real fault is an inconsistent API

Future Improvements

  • Migrate from SQLite to PostgreSQL for multi-cohort production use
  • Add trainer-side analytics on progress trends across a cohort

Want to talk through how this was built, or a similar problem you’re facing?

Get in touch