Skip to content

Commit fc978c0

Browse files
committed
fix: add dotenv installation for database migration in CI
1 parent 7e31310 commit fc978c0

2 files changed

Lines changed: 127 additions & 92 deletions

File tree

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ jobs:
4545
working-directory: ./backend
4646
run: npm ci
4747

48+
- name: Install Database Dependencies
49+
working-directory: ./database
50+
run: npm install dotenv
51+
4852
- name: Run Prisma Migrations
4953
working-directory: ./backend
5054
run: npx prisma migrate deploy --config=../database/prisma.config.ts --schema=../database/prisma/schema.prisma

README.md

Lines changed: 123 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,143 @@
1-
# Learning Management System (LMS)
2-
3-
## 📌 Project Overview
4-
A comprehensive Learning Management System designed to bridge the gap between teachers and students. This platform features a scalable backend for managing data and a responsive frontend for a seamless user experience. It supports role-based access, course management, assignment tracking, and secure authentication.
5-
6-
## 🚀 Tech Stack
7-
8-
### Frontend
9-
- **Framework:** React (Vite)
10-
- **State Management:** Redux Toolkit
11-
- **Styling:** CSS Modules & Global Variables
12-
- **Routing:** React Router v6
13-
- **HTTP Client:** Axios
1+
# Mini LMS (Learning Management System) Backend
2+
3+
An advanced, resilient, and secure RESTful API for a Learning Management System designed to handle core educational workflows: course creation, student enrollment, assignment distribution, and grade-less submission tracking.
4+
5+
## Overview
6+
This backend powers a multi-tenant learning environment where Teachers manage courses and assignments, and Students enroll in those courses and submit their work. It heavily emphasizes security boundaries, rate-limiting resilience, and strict data consistency logic utilizing modern Node.js backend practices.
7+
8+
## Tech Stack
9+
* **Language & Runtime:** Node.js (v20), ES Modules
10+
* **Framework:** Express.js (v5)
11+
* **Database & ORM:** PostgreSQL (v15), Prisma ORM
12+
* **Security & Hardening:** Helmet, express-rate-limit, CORS, bcrypt, Joi
13+
* **Observability:** Winston (Structured logging, Recursive redaction)
14+
* **Testing:** Jest, Supertest
15+
* **CI/CD:** GitHub Actions (Clean-clone DB migration tests)
16+
17+
## Architecture
18+
19+
```mermaid
20+
graph TD
21+
Client[Client App / Postman] --> |HTTP / JSON| API[Express API Gateway]
22+
23+
subgraph Express Backend
24+
API --> RateLimit[Rate Limiter]
25+
RateLimit --> Auth[Auth Middleware]
26+
Auth --> Validation[Joi Boundary Validation]
27+
Validation --> Controllers[Controllers]
28+
Controllers --> CoreAuth[Core Authorization]
29+
CoreAuth --> Services[Domain Services]
30+
end
31+
32+
Services --> |Prisma Client| DB[(PostgreSQL)]
33+
34+
subgraph Observability
35+
Controllers -.-> Logger[Winston Logger]
36+
Services -.-> Logger
37+
Logger -.-> |Redacts PII/Tokens| LogOutput[Stdout/JSON]
38+
end
39+
```
1440

15-
### Backend
16-
- **Runtime:** Node.js
17-
- **Framework:** Express.js
18-
- **Database:** PostgreSQL (via Prisma ORM)
19-
- **Authentication:** JWT (JSON Web Tokens)
20-
- **Validation:** Joi
21-
- **Security:** Helmet, CORS, bcrypt
41+
## Project Structure
42+
```text
43+
backend/
44+
├── src/
45+
│ ├── app.js # Express app configuration & hardening
46+
│ ├── server.js # Entry point & Graceful shutdown
47+
│ ├── config/ # Centralized environment variable parsing
48+
│ ├── controllers/ # HTTP request/response handlers
49+
│ ├── core/ # Core domain logic (e.g., authorization.js)
50+
│ ├── middlewares/ # Joi validation, error handling, logging, JWT auth
51+
│ ├── routes/ # Route definitions
52+
│ ├── services/ # Business logic and Prisma DB interactions
53+
│ ├── utils/ # Helpers (e.g., JWT signing/verification)
54+
│ └── validations/ # Joi schema definitions
55+
├── tests/ # Jest integration test suite & fixtures
56+
├── database/ # Prisma schema, migrations, config
57+
├── .github/workflows/ # CI/CD pipelines
58+
├── package.json # NPM dependencies & scripts
59+
└── eslint.config.js # Linter configuration
60+
```
2261

23-
## ✨ Features
62+
## Getting Started
2463

25-
### Core
26-
- **User Authentication:** Secure signup/login with JWT.
27-
- **Role-Based Access Control (RBAC):** Strict separation between Teacher and Student roles.
64+
### Prerequisites
65+
* Node.js (v20+)
66+
* Docker & Docker Compose (for the local test database)
67+
* PostgreSQL (if running locally without Docker)
68+
69+
### Environment Setup
70+
Create a `.env` file in the `backend/` directory:
71+
72+
```env
73+
NODE_ENV=development
74+
PORT=3000
75+
DATABASE_URL=postgresql://lmsuser:lmspassword@localhost:5432/lmsdb
76+
JWT_SECRET=super_secret_jwt_key_that_is_at_least_32_bytes_long
77+
JWT_EXPIRES_IN=1d
78+
CORS_ORIGIN=http://localhost:3000
79+
RATE_LIMIT_LOGIN_MAX=5
80+
RATE_LIMIT_REGISTER_MAX=10
81+
```
2882

29-
### 👩‍🏫 Teacher Portal
30-
- **Dashboard:** Overview of created courses.
31-
- **Course Management:** Create and update courses.
32-
- **Assignments:** Create assignments and review student submissions.
83+
### Installation & Execution
84+
```bash
85+
cd backend/
86+
npm install
3387

34-
### 👨‍🎓 Student Portal
35-
- **Dashboard:** View enrolled courses.
36-
- **Enrollment:** Browse and enroll in available courses.
37-
- **Assignments:** Submit work and track progress.
88+
# Apply database migrations
89+
npx prisma migrate dev
3890

39-
## 📂 Project Structure
40-
```
41-
Learning_management_system/
42-
├── frontend/ # React application
43-
│ ├── src/ # Components, Pages, Redux Store
44-
│ └── ...
45-
├── backend/ # Node.js Express API
46-
│ ├── src/ # Controllers, Routes, Services, Prisma
47-
│ └── ...
48-
└── README.md # Project documentation (this file)
91+
# Start the server (Development)
92+
npm run dev
4993
```
5094

51-
## 🛠️ Setup & Installation
95+
## API Reference
5296

53-
### Prerequisites
54-
- Node.js (v18+)
55-
- PostgreSQL (installed and running)
97+
### Authentication
98+
| Method | Endpoint | Description | Auth Required |
99+
| :--- | :--- | :--- | :--- |
100+
| `POST` | `/auth/register` | Register a new user (Teacher/Student) | No |
101+
| `POST` | `/auth/login` | Authenticate and receive a JWT | No |
56102

57-
### 1. Backend Setup
58-
Navigate to the backend directory and set up the API and database.
103+
### Courses & Enrollments
104+
| Method | Endpoint | Description | Auth Required (Role) |
105+
| :--- | :--- | :--- | :--- |
106+
| `GET` | `/courses` | List all available courses | No |
107+
| `POST` | `/courses` | Create a new course | Yes (TEACHER) |
108+
| `GET` | `/courses/enrolled` | List courses the student is enrolled in | Yes (STUDENT) |
109+
| `POST` | `/courses/:id/enroll` | Enroll the current student into a course | Yes (STUDENT) |
110+
| `GET` | `/courses/:id/assignments` | List assignments for a course | Yes (Enrolled STUDENT / Owning TEACHER) |
111+
| `POST` | `/courses/:id/assignments` | Create a new assignment for a course | Yes (Owning TEACHER) |
59112

60-
```bash
61-
cd backend
62-
```
113+
### Assignments & Submissions
114+
| Method | Endpoint | Description | Auth Required (Role) |
115+
| :--- | :--- | :--- | :--- |
116+
| `POST` | `/assignments/:id/submit` | Submit work for an assignment | Yes (Enrolled STUDENT) |
117+
| `GET` | `/assignments/:id/submissions` | List all submissions for an assignment | Yes (Owning TEACHER) |
63118

64-
**Install Dependencies & Setup Environment:**
65-
You can use the provided setup script or configure manually.
119+
## Security
66120

67-
```bash
68-
# Option A: Automatic Setup
69-
./setup.sh
70-
71-
# Option B: Manual Setup
72-
npm install
73-
cp .env.example .env
74-
# Edit .env with your DATABASE_URL and JWT_SECRET
75-
npx prisma migrate dev --name init
76-
```
121+
This system implements a defense-in-depth security architecture:
77122

78-
**Start the Server:**
79-
```bash
80-
npm run dev
81-
```
82-
> The backend runs on `http://localhost:3000`.
123+
1. **Strict Boundary Validation**: All incoming requests pass through a global `validateBody` middleware using strict Joi schemas (`stripUnknown: false`, `allowUnknown: false`), dropping malformed payloads before they reach business logic.
124+
2. **Rate Limiting**: Authentication endpoints are heavily protected against brute-force attacks via memory-stored rate limiters (`trust proxy` enabled).
125+
3. **Recursive Log Redaction**: The Winston logger utilizes a recursive object traversal function to guarantee `password`, `token`, and `authorization` keys are redacted (`[REDACTED]`), regardless of how deeply nested they are within request payloads or error stacks.
126+
4. **Isolated Authorization (`core/authorization.js`)**: Authorization is strictly split from authentication. Role checks are handled via the JWT middleware, but **ownership** (`assertOwnsCourse`) and **enrollment** (`assertEnrolled`) domain checks are abstracted into an isolated `core/authorization.js` module. This guarantees that standard Prisma queries always wrap the required database lookups to verify a Teacher actually owns the course they are modifying, or a Student is genuinely enrolled in the course they are interacting with.
83127

84-
### 2. Frontend Setup
85-
Open a new terminal and navigate to the frontend directory.
128+
## Testing
129+
The repository maintains strict integration test coverage spanning the full API boundary, database constraint validation, rate limiting, and log redaction.
86130

87131
```bash
88-
cd frontend
132+
# Run the full test suite (automatically spins up a clean Postgres container)
133+
npm test
89134
```
90135

91-
**Install Dependencies:**
92-
```bash
93-
npm install
94-
```
136+
## Design Decisions
137+
- **Hard Delete cascades**: `onDelete: Cascade` rules were implemented strictly across the schema. A course serves as a container; deleting a course destroys its assignments and submissions. However, deleting a user is restricted if they have graded submissions, preserving historical academic integrity.
138+
- **UUIDs and API Coercion**: A dedicated integer coercion middleware shields the database from Prisma's `NaN` panics.
139+
- **Graceful Shutdown & Resilience**: The application leverages `SIGTERM`/`SIGINT` traps and explicitly delays startup until the database emits a successful connection ping.
95140

96-
**Start the Application:**
97-
```bash
98-
npm run dev
99-
```
100-
> The frontend runs on `http://localhost:5173`.
101-
102-
## 🧪 Verification & Usage
103-
1. **Register as a Teacher** to create a test course and assignment.
104-
2. **Register as a Student** (incognito window recommended) to enroll in the course.
105-
3. **Submit an Assignment** as a student and view it as a teacher.
106-
107-
## ✅ Requirements Fulfillment
108-
This project satisfies the core requirements for a scalable LMS platform:
109-
- **Architecture:** Decoupled Frontend and Backend.
110-
- **Security:** Password hashing, JWT auth, and RBAC middleware.
111-
- **Database:** Relational schema with Prisma ORM.
112-
- **Code Quality:** Modular structure, centralized error handling, and input validation.
141+
## Limitations
142+
- **No Frontend**: This repository is strictly a backend API. The GitHub Actions CI pipeline verifies backend linting, database migrations from scratch, and integration tests, but intentionally does not build or assert UI artifacts.
143+
- **In-Memory Rate Limiting**: The `express-rate-limit` configuration uses the default memory store. In a multi-node production deployment, this should be migrated to a Redis store.

0 commit comments

Comments
 (0)