346 lines
6.5 KiB
Markdown
346 lines
6.5 KiB
Markdown
# Fusero Boilerplate App
|
|
|
|
This is a Fastify + MikroORM + PostgreSQL boilerplate, designed to run in Docker for local development.
|
|
It is set up to run alongside other projects without port or database conflicts.
|
|
|
|
---
|
|
|
|
## 1. Prerequisites
|
|
|
|
- [Node.js](https://nodejs.org/) (v18+ recommended)
|
|
- [Docker](https://www.docker.com/get-started)
|
|
- [npm](https://www.npmjs.com/)
|
|
|
|
---
|
|
|
|
## 2. Clone the Repo
|
|
|
|
```bash
|
|
git clone <your-repo-url>
|
|
cd fusero-app-boilerplate
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Setup the `.env` File
|
|
|
|
Copy `.env.example` to `.env` (or create `.env` if not present):
|
|
|
|
```env
|
|
# Database connection for Docker
|
|
POSTGRES_NAME=fusero-boilerplate-db
|
|
POSTGRES_HOSTNAME=localhost
|
|
POSTGRES_PORT=19095
|
|
POSTGRES_USER=root
|
|
POSTGRES_PASSWORD=root123
|
|
|
|
# Test Database connection
|
|
POSTGRES_TEST_NAME=test-db
|
|
POSTGRES_TEST_PORT=19096
|
|
|
|
# Default admin user for seeding
|
|
DEFAULT_ADMIN_USERNAME=darren
|
|
DEFAULT_ADMIN_EMAIL=darren@fusero.nl
|
|
DEFAULT_ADMIN_PASSWORD=admin123
|
|
|
|
# JWT secret
|
|
JWT_SECRET=your_jwt_secret_here
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Start the Database (Docker)
|
|
|
|
```bash
|
|
docker-compose -f docker-compose.dev.yml up -d
|
|
```
|
|
|
|
This will start two Postgres instances:
|
|
- Main database on port 19095
|
|
- Test database on port 19096
|
|
|
|
Both with dedicated Docker volumes.
|
|
|
|
---
|
|
|
|
## 5. Install Dependencies
|
|
|
|
```bash
|
|
npm install
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Run Migrations
|
|
|
|
```bash
|
|
npm run migration:create # Create a new migration
|
|
npm run migration:up # Run migrations
|
|
```
|
|
|
|
This will create all tables in the database.
|
|
|
|
---
|
|
|
|
## 7. Seed the Database
|
|
|
|
```bash
|
|
npm run seed
|
|
```
|
|
|
|
This will create the default admin user and roles as specified in your `.env`.
|
|
|
|
---
|
|
|
|
## 8. Start the App
|
|
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
The app will be available at [http://localhost:14000](http://localhost:14000).
|
|
|
|
---
|
|
|
|
## 9. API Endpoints
|
|
|
|
### Authentication
|
|
|
|
#### Login
|
|
```bash
|
|
curl -X POST http://localhost:14000/api/v1/auth/login \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"username": "darren",
|
|
"password": "admin123"
|
|
}'
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Authentication successful",
|
|
"data": {
|
|
"token": "your.jwt.token",
|
|
"user": {
|
|
"id": 1,
|
|
"username": "darren",
|
|
"email": "darren@fusero.nl",
|
|
"roles": ["admin"]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### User Management
|
|
|
|
#### Create User
|
|
```bash
|
|
curl -X POST http://localhost:14000/api/v1/app/users \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer your.jwt.token" \
|
|
-d '{
|
|
"username": "newuser",
|
|
"password": "userpass123",
|
|
"email": "user@example.com",
|
|
"roleName": "user"
|
|
}'
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "User created successfully",
|
|
"data": {
|
|
"id": 2,
|
|
"username": "newuser",
|
|
"email": "user@example.com",
|
|
"roles": ["user"]
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Get All Users (Requires admin role)
|
|
```bash
|
|
curl -X GET http://localhost:14000/api/v1/app/users \
|
|
-H "Authorization: Bearer your.jwt.token"
|
|
```
|
|
|
|
#### Get User by ID
|
|
```bash
|
|
curl -X GET http://localhost:14000/api/v1/app/users/1 \
|
|
-H "Authorization: Bearer your.jwt.token"
|
|
```
|
|
|
|
### Canvas Dummy Grades API
|
|
|
|
The canvas API provides endpoints for managing dummy grades. All endpoints are prefixed with `/api/v1/canvas-api/`.
|
|
|
|
#### Get All Dummy Grades
|
|
```bash
|
|
GET /api/v1/canvas-api/
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Dummy grades retrieved successfully",
|
|
"data": {
|
|
"grades": [
|
|
{
|
|
"id": 1,
|
|
"student_id": 101,
|
|
"course_id": 1,
|
|
"assignment_id": 1,
|
|
"score": 85,
|
|
"grade": "B",
|
|
"submitted_at": "2024-03-15T10:00:00Z",
|
|
"graded_at": "2024-03-16T14:30:00Z"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Add a New Dummy Grade
|
|
```bash
|
|
POST /api/v1/canvas-api/add
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"student_id": 123,
|
|
"course_id": 456,
|
|
"assignment_id": 789,
|
|
"score": 85
|
|
}
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Dummy grade added successfully",
|
|
"data": {
|
|
"id": 3,
|
|
"student_id": 123,
|
|
"course_id": 456,
|
|
"assignment_id": 789,
|
|
"score": 85,
|
|
"grade": "B",
|
|
"submitted_at": "2024-03-15T10:00:00Z",
|
|
"graded_at": "2024-03-16T14:30:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Update a Dummy Grade
|
|
```bash
|
|
PUT /api/v1/canvas-api/update
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"id": 1,
|
|
"student_id": 123,
|
|
"course_id": 456,
|
|
"assignment_id": 789,
|
|
"score": 90
|
|
}
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Dummy grade updated successfully",
|
|
"data": {
|
|
"id": 1,
|
|
"student_id": 123,
|
|
"course_id": 456,
|
|
"assignment_id": 789,
|
|
"score": 90,
|
|
"grade": "A",
|
|
"submitted_at": "2024-03-15T10:00:00Z",
|
|
"graded_at": "2024-03-16T14:30:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Delete a Dummy Grade
|
|
```bash
|
|
DELETE /api/v1/canvas-api/delete
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"id": 1
|
|
}
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Dummy grade deleted successfully"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 10. Testing
|
|
|
|
Run tests with:
|
|
```bash
|
|
npm test # Run all tests
|
|
npm run test:watch # Run tests in watch mode
|
|
npm run test:coverage # Run tests with coverage
|
|
```
|
|
|
|
The test database is automatically used for running tests.
|
|
|
|
---
|
|
|
|
## 11. Authentication & Authorization
|
|
|
|
- All endpoints except login require a valid JWT token
|
|
- The JWT token should be included in the Authorization header as: `Bearer your.jwt.token`
|
|
- Some endpoints require specific roles (admin/user)
|
|
- JWT tokens expire after 1 hour
|
|
|
|
---
|
|
|
|
## 12. Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
1. **Database Connection Issues**
|
|
- Ensure Docker is running
|
|
- Check if the Postgres containers are up: `docker ps`
|
|
- Verify database credentials in `.env`
|
|
|
|
2. **Authentication Issues**
|
|
- Ensure JWT_SECRET is set in `.env`
|
|
- Check if the user exists in the database
|
|
- Verify the password is correct
|
|
|
|
3. **Role-based Access Issues**
|
|
- Ensure the user has the required role
|
|
- Check if the JWT token includes the correct roles
|
|
- Verify the token hasn't expired
|
|
|
|
### Logs
|
|
|
|
- Application logs can be viewed in the terminal where `npm run dev` was executed
|
|
- Database logs can be viewed using: `docker logs fusero-boilerplate-db`
|
|
|
|
---
|
|
|
|
## 13. Notes
|
|
|
|
- The app uses separate databases, ports, and Docker volumes from any other Fusero projects, so it can run in parallel.
|
|
- The default admin user is created by the seed script and can be changed via `.env`.
|
|
- For production, use `docker-compose.yml` and adjust ports/credentials as needed.
|
|
- The app includes TypeScript, ESLint, and Prettier for code quality.
|
|
|
|
--- |