CS31A/Lab-System-Backend(opens in a new tab)
Language: TypeScript
- stars
- 2
- watchers
- 0
- forks
- 11
- open issues
- 0
- Last updated
- 11/27/2025
Language: TypeScript
A modern, type-safe REST API for laboratory management built with Hono.js, TypeScript, and Cloudflare Workers. This system manages laboratory schedules, equipment tracking, user roles, and seating arrangements for educational institutions.
The Lab System Backend is a comprehensive laboratory management solution designed for educational institutions. It provides a robust API for managing various aspects of computer laboratory operations, including:
The system is built using modern technologies ensuring type safety, performance, and scalability while providing an intuitive API for frontend applications.
Before setting up the project, ensure you have the following installed on your system:
git clone <repository-url> cd lab-system-backend
This project uses Bun as the package manager instead of npm:
bun install
Copy the example environment files:
cp .env.example .env cp .dev.vars.example .dev.vars
Edit both .env and .dev.vars files with your database connection details:
# Database DATABASE_URL=postgresql://username:password@localhost:5432/lab_system_db # Logger # Options: info | fatal | error | warn | debug | trace | silent LOG_LEVEL=debug # Node Environment # Options: development | production NODE_ENV=development
CREATE DATABASE lab_system_db;
DATABASE_URL in both .env and .dev.varsGenerate and apply database schema:
# Generate migration files (if you adjusted anythig in the schema otherwise just run bun run drizzle-kit push) bunx drizzle-kit generate # Push schema to database bunx drizzle-kit push
The system uses SendGrid for sending password reset emails. Follow these steps to configure email functionality:
Important: SendGrid requires sender verification to prevent spam.
The system supports both inline HTML emails and SendGrid dynamic templates. Using templates provides better email design and easier management.
d-07f4668c32d94aac9d7d93dcf19b7ab4{{username}} - The user's username{{reset_link}} - The password reset URLTemplate HTML Structure (if creating your own):
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Lab System - Reset Password</title> </head> <body style="margin: 0; padding: 0; background-color: #f5f5f5; font-family: Arial, sans-serif"> <!-- Your template content here --> <p>Hello <strong>{{username}}</strong>,</p> <p>Click the button below to reset your password:</p> <a href="{{reset_link}}" style="background-color: #007bff; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 5px" > Reset Password </a> <!-- Rest of your template --> </body> </html>
Add the following to both .env and .dev.vars files:
# Email Configuration - SendGrid SENDGRID_API_KEY=your_sendgrid_api_key_here SENDGRID_TEMPLATE_ID=d-07f4668c32d94aac9d7d93dcf19b7ab4 SMTP_FROM=your_verified_email@domain.com # Password Reset Configuration BCRYPT_COST=10 APP_URL=http://localhost:5173 RESET_TOKEN_EXPIRY_HOURS=1 # Frontend URL (for CORS and redirects) FRONTEND_URL=http://localhost:5173
Important Notes:
SMTP_FROM variablesSMTP_FROM email must match exactly what you verified in SendGrid.dev.vars has the correct SMTP_FROM valueStart the development server:
bun run dev
Create a test user (or use existing user)
Test password reset:
curl -X POST http://localhost:8787/auth/forgot-password \ -H "Content-Type: application/json" \ -d '{"email":"user@example.com"}'
Check the server logs for success message:
Password reset token generated and email sent
Issue: 403 - The from address does not match a verified Sender Identity
SMTP_FROM matches exactly the email you verified in SendGrid.env and .dev.vars have the same verified emailIssue: 400 - text/plain must be first, followed by text/html
Issue: No email received but logs show success
Issue: 401 - Unauthorized
To customize the email template:
d-07f4668c32d94aac9d7d93dcf19b7ab4) or create a new one{{username}} - User's display name{{reset_link}} - Complete password reset URLThe system uses SendGrid for email delivery:
# Resend Configuration (alternative to SendGrid)
RESEND_API_KEY=your_resend_api_key_herePriority Order:
SENDGRID_API_KEY and SENDGRID_TEMPLATE_ID are set)SENDGRID_API_KEY is set)Template Benefits:
Start the development server:
bun run dev
The API will be available at http://localhost:8787
| Script | Command | Description |
|---|---|---|
| Development | bun run dev |
Start development server with hot reload |
| Build & Deploy | bun run deploy |
Deploy to Cloudflare Workers |
| Type Generation | bun run cf-typegen |
Generate TypeScript types for Cloudflare bindings |
| Linting | bun run lint |
Run ESLint code quality checks |
| Lint Fix | bun run lint:fix |
Automatically fix linting issues |
| Tests | bun run test |
Run unit and integration tests |
| Generate Migration | bunx drizzle-kit generate |
Generate new migration files |
| Push Schema | bunx drizzle-kit push |
Push schema changes to database |
| Database Studio | bunx drizzle-kit studio |
Open Drizzle Studio (database GUI) |
GET / - API welcome messageGET /health - Health check endpointPOST /auth/login - User login with email and passwordPOST /auth/refresh - Refresh authentication tokenPOST /auth/logout - User logoutGET /auth/me - Get current user informationPOST /auth/forgot-password - Request password reset emailPOST /auth/reset-password - Reset password with tokenGET /auth/validate-reset-token - Validate reset tokenPOST /users - Create new user accountGET /users - List users with paginationGET /users/:id - Get specific user detailsPUT /users/:id - Update user informationDELETE /users/:id - Soft delete userPATCH /users/:id/restore - Restore soft deleted userDELETE /users/:id/hard - Permanently delete userGET /teachers - List teachers with paginationGET /teachers/:id - Get specific teacher detailsGET /teachers/:id/laboratories - Get laboratories assigned to teacherGET /teachers/:id/dashboard - Get teacher dashboard dataGET /laboratories - List laboratories with paginationPOST /laboratories - Create new laboratoryGET /laboratories/:id - Get specific laboratory detailsPUT /laboratories/:id - Update laboratory informationDELETE /laboratories/:id - Delete laboratoryGET /subjects - List subjects with paginationPOST /subjects - Create new subjectGET /subjects/:id - Get specific subject detailsPUT /subjects/:id - Update subject informationDELETE /subjects/:id - Delete subjecthttp://localhost:8787/referencehttp://localhost:8787/docsThe API documentation provides comprehensive information about all endpoints, request/response schemas, and example usage.
curl -X POST http://localhost:8787/users \ -H "Content-Type: application/json" \ -d '{ "username": "johndoe", "email": "john@example.com", "password": "SecurePassword123", "confirmPassword": "SecurePassword123", "user_type": "teacher" }'
curl "http://localhost:8787/teachers?page=1&limit=10"curl -X POST http://localhost:8787/auth/forgot-password \ -H "Content-Type: application/json" \ -d '{"email":"user@example.com"}'
curl -X POST http://localhost:8787/auth/reset-password \ -H "Content-Type: application/json" \ -d '{ "token":"selector.verifier_from_email", "newPassword":"NewSecurePassword123" }'
src/
├── index.ts # Main application entry point
├── db/ # Database layer
│ ├── index.ts # Database connection factory
│ └── schema.ts # Drizzle schemas & Zod validation
├── lib/ # Core application utilities
│ ├── create-app.ts # App factory with middleware
│ ├── openapi-configuration.ts # API docs setup
│ └── types/ # TypeScript definitions
├── middleware/ # Request processing middleware
│ ├── env.ts # Environment validation
│ ├── pino-logger.ts # Logging middleware
│ └── utils/ # Utility middleware
├── routes/ # API route definitions
│ ├── index.ts # Root routes
│ ├── auth/ # Authentication routes
│ ├── users/ # User management routes
│ ├── teachers/ # Teacher management routes
│ ├── laboratories/ # Laboratory management routes
│ └── subjects/ # Subject management routes
├── handlers/ # Business logic implementations
│ ├── auth/ # Authentication handlers
│ ├── users/ # User-related handlers
│ ├── teachers/ # Teacher-related handlers
│ ├── laboratories/ # Laboratory-related handlers
│ └── subjects/ # Subject-related handlers
├── services/ # Business service layer
│ ├── UserService.ts # User business logic
│ ├── TeacherService.ts # Teacher business logic
│ ├── LaboratoryService.ts # Laboratory business logic
│ ├── SubjectService.ts # Subject business logic
│ ├── EmailService.ts # Email sending functionality
│ └── PasswordResetService.ts # Password reset logic
└── openapi/ # OpenAPI utilities
The API provides comprehensive documentation through:
http://localhost:8787/reference when running the development serverhttp://localhost:8787/docsThe documentation includes:
We welcome contributions! Please read our CONTRIBUTION.md for detailed information on:
git checkout -b feature/amazing-featureThis project uses Vitest for unit and integration testing. See CONTRIBUTION.md for detailed testing guidelines.
# Run tests bun run test # Run tests with UI bun run test:ui # Run tests once bun run test:run # Run tests with coverage bun run test:coverage
bun run deploy
For detailed deployment instructions and environment configuration, see CONTRIBUTION.md.
This project is licensed under the terms specified in the LICENSE file.
Ready to contribute? Start by reading our CONTRIBUTION.md guide!