All projects

Hobby2025

DevCode Academy LMS

A role-based learning management system for programming schools.

Roles
Admin · Teacher · Student
Tables
17
Pages
30+
Migrations
Drizzle Kit

01Overview

DevCode Academy runs a programming school end to end: courses and lessons, live class sessions with attendance, assignments with grading, public certificate verification and a blog.

Each role gets its own dashboard and navigation, backed by a single typed schema shared by the client and the server.

02Architecture

A React single-page app talks to an Express REST API. The database schema is defined once in a shared module and reused for queries, migrations and request validation.

Client

Admin

Courses, teachers, students

Teacher

Lessons, grading, attendance

Student

Courses, assignments, grades

Public

Landing, blog, certificate check

Client runtime

Wouter

Routing

TanStack Query

Server-state cache

React Hook Form + Zod

Validated forms

API

REST routes

Express · TypeScript ESM

Auth

Sessions + role guards

Storage layer

Repository over Drizzle

Shared

shared/schema.ts

Drizzle tables + drizzle-zod schemas

Data

PostgreSQL

Neon serverless

Session store

connect-pg-simple

03Components

Course domain

Content and enrolment

  • Courses → lessons → materials and lesson assignments, plus separate offline courses with their own enrolments.
  • Lesson progress is tracked per student and aggregated on dashboards.

Live sessions & attendance

Classroom operations

  • Teachers open a lesson session; a global active-session bar follows them across pages.
  • Attendance is recorded per session and visible to students.

Assignments & grading

Learning loop

  • Students submit work, teachers grade with feedback, grades roll up into the student's record.

Certificates

Trust outside the platform

  • Certificates are issued on completion and can be verified publicly by anyone with the certificate code.

04How it works

  1. 1

    Admin

    Creates courses and assigns teachers.

  2. 2

    Teacher

    Builds lessons, runs live sessions, takes attendance.

  3. 3

    Student

    Enrols, follows lessons, submits assignments.

  4. 4

    Teacher

    Grades submissions; progress updates on both dashboards.

  5. 5

    Platform

    Issues a verifiable certificate on completion.

05Technical deep dives

One schema, three uses

Tables are declared once with Drizzle. The same definitions produce SQL migrations, typed queries on the server, and Zod insert schemas that validate request bodies and client forms - so the API contract cannot drift from the database.

shared/schema.ts (excerpt)ts
export const courses = pgTable("courses", {
  id: serial("id").primaryKey(),
  title: varchar("title", { length: 255 }).notNull(),
  level: varchar("level", { enum: ["beginner", "intermediate", "advanced"] }).notNull(),
  instructorId: varchar("instructor_id").notNull(),
  isActive: boolean("is_active").default(true),
  enrollmentCount: integer("enrollment_count").default(0),
  createdAt: timestamp("created_at").defaultNow(),
  updatedAt: timestamp("updated_at").defaultNow(),
});

// Reused by the API (request validation) and the client (forms)
export const insertCourseSchema = createInsertSchema(courses).omit({
  id: true,
  createdAt: true,
  updatedAt: true,
});
export type InsertCourse = z.infer<typeof insertCourseSchema>;

06Design decisions

Storage interface between routes and database

Routes depend on a storage abstraction, not on Drizzle directly, which keeps handlers thin and the data layer testable.

Server state in TanStack Query

No global client store: server data is cached and invalidated by query keys, UI state stays local.

Sessions in PostgreSQL

Sessions live in the same database, so the app scales horizontally without a separate session service.

07Tech stack

Frontend
React 18TypeScriptViteTailwind CSSshadcn/uiTanStack QueryWouter
Backend
Node.jsExpressPassportexpress-session
Data
PostgreSQL (Neon)Drizzle ORMdrizzle-zod

08What's next

  • Automated grading for code assignments.
  • Real-time notifications for live sessions.

Next case study

Crypto Trading Bot

A multi-indicator trading engine with live dashboard, backtesting and Telegram control.