Express + MySQL CRUD API for student records, with a plain HTML frontend. - Single-file backend (server.js) with 5 CRUD routes - Proper HTTP status codes and a consistent error envelope - 8-digit ids: 2-digit year + per-year 6-digit counter (e.g. 26000001), allocated under a MySQL advisory lock so concurrent inserts cannot collide - student_db.sql schema and seed data - .env for credentials; only .env.example is committed
2.7 KiB
Student Management System (MW600)
A mini system for managing student records, built with Express and MySQL.
Backend is a single file (server.js) exposing a CRUD API; the frontend is a
plain HTML page (index.html) served from the same server.
Requirements
- Node.js 20.6+ (uses
process.loadEnvFile) - A running MySQL server
Setup
npm install
cp .env.example .env # then fill in your MySQL credentials
npm run db:push # creates the database and imports student_db.sql
npm start
npm run db:push creates the student_db database and imports the schema and
seed data from student_db.sql. It is safe to re-run — the script drops and
recreates the students table.
Database
student_db.sql holds the schema and seed rows for a single table:
| Column | Type | Notes |
|---|---|---|
id |
INT |
Primary key, assigned by app |
name |
VARCHAR(100) |
Required |
course |
VARCHAR(50) |
Required |
year_level |
INT |
Required, 1–6 |
ID format
Ids are 8 digits: a 2-digit year followed by a 6-digit counter that resets each year.
26 000001 -> first student added in 2026
26 000002 -> second student added in 2026
27 000001 -> first student added in 2027
The counter is per year, so ids never collide across years. Because MySQL cannot
generate this pattern, id has no AUTO_INCREMENT — the application assigns it.
Allocation is guarded by a MySQL advisory lock (GET_LOCK) so simultaneous
requests cannot receive the same id.
API
| Method | Path | Response |
|---|---|---|
GET |
/api/students |
200 list of students |
GET |
/api/students/:id |
200 student, 400 bad id, 404 not found |
POST |
/api/students |
201 created, 400 invalid, 415 not JSON |
PUT |
/api/students/:id |
200 updated, 400 invalid, 404 not found |
DELETE |
/api/students/:id |
204 deleted, 404 not found |
Errors use one envelope:
{ "error": { "code": "VALIDATION_ERROR", "message": "...", "details": [] } }
Configuration
All connection settings live in .env (not committed):
| Variable | Default |
|---|---|
DB_HOST |
127.0.0.1 |
DB_PORT |
3306 |
DB_USER |
root |
DB_PASSWORD |
required |
DB_NAME |
student_db |
PORT |
3000 |