https://github.com/pitzzahh/lrnr
A modern Learning Management System API built with Hono, Bun, and OpenAPI documentation. Fast, type-safe, and developer-friendly.
https://github.com/pitzzahh/lrnr
bun hono openapi scalar zod
Last synced: about 1 month ago
JSON representation
A modern Learning Management System API built with Hono, Bun, and OpenAPI documentation. Fast, type-safe, and developer-friendly.
- Host: GitHub
- URL: https://github.com/pitzzahh/lrnr
- Owner: pitzzahh
- License: mit
- Created: 2025-06-03T07:26:17.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-06-26T07:31:01.000Z (7 months ago)
- Last Synced: 2025-06-26T08:35:13.660Z (7 months ago)
- Topics: bun, hono, openapi, scalar, zod
- Language: TypeScript
- Homepage:
- Size: 237 KB
- Stars: 3
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# LRNR - Learning Management System API
A REST API for a learning management system built with Hono, Bun, and PostgreSQL.
## Features
- RESTful API with OpenAPI 3.0 specification
- Session-based authentication with HTTP-only cookies
- Role-based access control (Admin, Teacher, Student)
- User, course, category, and enrollment management
- Request/response validation with Zod schemas
- PostgreSQL database with Drizzle ORM
- Interactive API documentation with Scalar
- TypeScript for type safety
- Code quality tools (Biome for linting and formatting)
## Technology Stack
- **Runtime**: Bun
- **Framework**: Hono
- **Database**: PostgreSQL with Drizzle ORM
- **Authentication**: Session-based with HTTP-only cookies
- **Authorization**: Role-based access control
- **Validation**: Zod schemas
- **Documentation**: OpenAPI 3.0 with Scalar UI
- **Code Quality**: Biome (linting and formatting)
- **Language**: TypeScript
## Installation
### Prerequisites
- [Bun](https://bun.sh/) runtime
- PostgreSQL database
### Setup
1. Clone the repository:
```bash
git clone
cd lrnr
```
2. Install dependencies:
```bash
bun install
```
3. Set up your environment variables:
```bash
# Create .env file with your configuration
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_USER=your_username
DATABASE_PASSWORD=your_password
DATABASE_NAME=lrnr
SESSION_SECRET=your-session-secret
PORT=3000
NODE_ENV=development
```
4. Run database migrations:
```bash
bun run db:migrate
```
5. Start the development server:
```bash
bun run dev
```
The API will be available at `http://localhost:3000` with interactive documentation at `http://localhost:3000/reference`.
## Development
### Available Scripts
| Command | Description |
|---------|-------------|
| `bun run dev` | Start development server with hot reload |
| `bun run lint` | Check code with Biome |
| `bun run lint:fix` | Fix linting issues |
| `bun run format` | Check code formatting |
| `bun run format:fix` | Format code |
| `bun run check` | Run code quality checks |
| `bun run db:generate` | Generate database migrations |
| `bun run db:migrate` | Apply database migrations |
| `bun run db:push` | Push schema changes to database |
| `bun run db:studio` | Open Drizzle Studio |
### Environment Configuration
The application requires the following environment variables:
```env
# Server Configuration
PORT=3000
NODE_ENV=development
# Database Configuration
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_USER=your_username
DATABASE_PASSWORD=your_password
DATABASE_NAME=lrnr
# Authentication Configuration
SESSION_SECRET=your-session-secret
```
### Project Structure
```
src/
├── app.ts # Application setup and route registration
├── index.ts # Server entry point
├── env.ts # Environment variable validation
├── db/
│ ├── index.ts # Database connection setup
│ ├── schema/ # Database schema definitions
│ │ ├── users.ts # User schema with roles
│ │ ├── sessions.ts # Session management schema
│ │ ├── courses.ts # Course schema
│ │ ├── categories.ts # Category schema
│ │ ├── enrollments.ts # Enrollment schema
│ │ └── enums/ # Database enums (roles, status)
│ └── migrations/ # Database migration files
├── hooks/
│ ├── auth.ts # Authentication middleware
│ └── pino-logger.ts # Request logging middleware
├── lib/
│ ├── create-app.ts # Hono app factory
│ ├── configure-openapi.ts # OpenAPI configuration
│ ├── constants.ts # Application constants
│ ├── types.ts # TypeScript type definitions
│ └── auth/ # Authentication utilities
│ └── index.ts # Session management and password hashing
└── routes/
├── index.route.ts # Root API route
├── auth/ # Authentication endpoints
├── users/ # User management endpoints
├── courses/ # Course management endpoints
├── categories/ # Category management endpoints
├── enrollments/ # Enrollment management endpoints
└── llms/ # LLM integration endpoints
```
## Authentication
The API supports two authentication methods:
1. **Session-based authentication** - Uses HTTP-only cookies, ideal for web applications
2. **API key authentication** - Uses Bearer tokens, ideal for programmatic access
Users have different roles that control access to various endpoints.
### User Roles
- **STUDENT**: Default role for new users
- **TEACHER**: Can manage courses and view enrollments
- **ADMIN**: Full access to all system resources
### Authentication Endpoints
| Endpoint | Method | Description |
|----------|---------|-------------|
| `POST /auth/signup` | POST | Register a new user account |
| `POST /auth/signin` | POST | Sign in with email and password |
| `POST /auth/logout` | POST | Sign out and invalidate session |
### API Key Management
| Endpoint | Method | Description |
|----------|---------|-------------|
| `GET /api-keys` | GET | List user's API keys |
| `POST /api-keys` | POST | Create a new API key |
| `GET /api-keys/{id}` | GET | Get specific API key details |
| `PATCH /api-keys/{id}` | PATCH | Update API key (name, expiration) |
| `DELETE /api-keys/{id}` | DELETE | Revoke an API key |
### Protected Routes
Most API endpoints require authentication. The following routes are public:
- `GET /` - API root/health check
- `POST /auth/signup` - User registration
- `POST /auth/signin` - User authentication
- `GET /doc` - OpenAPI specification
- `GET /reference` - API documentation
### Session Management
- Sessions are valid for 15 days by default
- Sessions are automatically refreshed on API usage
- HTTP-only cookies are used for security
- Session data is stored in the database
### API Key Management
- API keys are prefixed with `lrnr_` for identification
- Keys can have optional expiration dates
- Keys are hashed before storage (never stored in plain text)
- Last usage time is tracked for each key
- Keys can be revoked/deactivated at any time
### Usage Examples
**Register a new user:**
```bash
curl -X POST http://localhost:3000/auth/signup \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"email": "john@example.com",
"password": "securepassword123",
"password_confirmation": "securepassword123"
}'
```
**Sign in (session-based):**
```bash
curl -X POST http://localhost:3000/auth/signin \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{
"email": "john@example.com",
"password": "securepassword123"
}'
```
**Create an API key:**
```bash
curl -X POST http://localhost:3000/api-keys \
-H "Content-Type: application/json" \
-b cookies.txt \
-d '{
"name": "My API Key"
}'
```
**Use session authentication:**
```bash
curl -X GET http://localhost:3000/users \
-H "Content-Type: application/json" \
-b cookies.txt
```
**Use API key authentication:**
```bash
curl -X GET http://localhost:3000/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer lrnr_your_api_key_here"
```
## Security
The application implements standard security practices:
- Password hashing for user credentials
- HTTP-only cookies to prevent XSS attacks
- API key hashing (keys never stored in plain text)
- Input validation using Zod schemas
- Role-based access control for endpoints
- Parameterized database queries
- Environment variables for sensitive configuration
## API Documentation
Interactive API documentation is available at:
- `/doc` - OpenAPI JSON specification
- `/reference` - Scalar UI for testing endpoints
The documentation includes request/response schemas, authentication requirements, and example requests.
## Troubleshooting
### Common Issues
**Database Connection Problems:**
- Verify PostgreSQL is running
- Check database credentials in environment variables
- Ensure database exists and is accessible
**Authentication Issues:**
- Check that cookies are being sent with requests
- Verify session hasn't expired
- Ensure proper authentication headers
### Development Notes
- Use `bun run db:studio` to inspect database contents
- Check server logs for detailed error information
- Visit `/reference` for interactive API testing
## Contributing
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/new-feature`)
3. Make your changes
4. Run tests and linting (`bun run check`)
5. Commit your changes (`git commit -m 'Add new feature'`)
6. Push to the branch (`git push origin feature/new-feature`)
7. Create a Pull Request
## License
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.