Files
CMT/backend/BACKEND.md

297 lines
7.6 KiB
Markdown

# CMT Backend
FastAPI-based backend with JWT authentication, role-based access control, and comprehensive test coverage.
## Features
- **JWT Authentication**: Session-based auth with role-based token expiration
- **Role-Based Access Control**: Admin, Write, and Read-only user roles
- **Database Management**: SQLModel + Alembic migrations
- **Comprehensive Testing**: Unit tests with pytest and test fixtures
- **API Documentation**: Auto-generated OpenAPI/Swagger docs
## Quick Start
### Environment Setup
```bash
cd backend
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
```
### Database Setup
```bash
# Create initial migration
alembic revision --autogenerate -m "Initial tables"
alembic upgrade head
# Create admin user (optional)
python scripts/create_admin.py
```
### Run the Application
```bash
uvicorn app.main:app --reload
# or
fastapi run --reload app/main.py
# API will be available at http://localhost:8000
# Docs at http://localhost:8000/docs
```
## API Endpoints
### Authentication
- `POST /api/v1/users/login` - User login (returns JWT token)
- `GET /api/v1/users/me` - Get current user info
### Users (Admin only)
- `POST /api/v1/users/` - Create user
- `GET /api/v1/users/` - List all users
- `GET /api/v1/users/{id}` - Get user by ID
- `PUT /api/v1/users/{id}` - Update user
- `DELETE /api/v1/users/{id}` - Delete user
### Transactions (Write access required)
- `POST /api/v1/transactions/` - Create transaction
- `GET /api/v1/transactions/` - List transactions
- `GET /api/v1/transactions/{id}` - Get transaction by ID
- `PUT /api/v1/transactions/{id}` - Update transaction
- `DELETE /api/v1/transactions/{id}` - Delete transaction
### Role-Based Token Expiration
- **Admin**: 8 hours (480 minutes)
- **Write**: 4 hours (240 minutes)
- **Read-only**: 2 hours (120 minutes)
## Authentication Usage
### Getting a Bearer Token
First, you need to create an admin user (if you haven't already):
```bash
cd backend
python scripts/create_admin.py
```
Then login to get your bearer token:
```bash
curl -X POST "http://localhost:8000/api/v1/users/login" \
-H "Content-Type: application/json" \
-d '{"username": "your_admin_username", "password": "your_password"}'
```
**Response:**
```json
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer",
"expires_in": 28800,
"user": {
"id": 1,
"username": "admin",
"role": "admin"
}
}
```
Copy the `access_token` value - this is your bearer token.
### Using the Bearer Token
```bash
# Include token in Authorization header
curl -X GET "http://localhost:8000/api/v1/users/me" \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
```
**Note:** Replace `eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...` with your actual token from the login response.
### Create User (Admin only)
```bash
curl -X POST "http://localhost:8000/api/v1/users/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-d '{"username": "newuser", "password": "password", "role": "read_only"}'
```
## Database Management
### Alembic
### Alembic Migration Commands
```bash
cd backend
# Create new migration after model changes
alembic revision --autogenerate -m "Description of changes"
# Apply migrations to database
alembic upgrade head
# Rollback to previous migration
alembic downgrade -1
# Mark database as up-to-date without running migrations
alembic stamp head
# View migration history
alembic history
```
## Testing
### Test Structure
```
backend/tests/
├── conftest.py # Shared fixtures (admin user, tokens, etc.)
├── test_main.py # Main app tests
├── api/v1/
│ ├── test_users.py # User endpoint tests
│ └── test_transactions.py # Transaction endpoint tests
├── core/
│ └── test_auth.py # Authentication tests
└── schemas/
└── test_models.py # Model validation tests
```
### Test Features
- **Isolated Tests**: Each test uses fresh in-memory database
- **Authentication Fixtures**: Pre-configured admin users and tokens
- **Role-Based Testing**: Tests for different user permission levels
- **Comprehensive Coverage**: Endpoints, authentication, and data validation
### Running Tests
```bash
cd backend
# Run all tests
pytest
# Run with verbose output
pytest -v
# Run specific test file
pytest tests/api/v1/test_users.py
# Run specific test function
pytest tests/api/v1/test_users.py::test_create_user
# Run with coverage report
pytest --cov=app
# Run and generate HTML coverage report
pytest --cov=app --cov-report=html
```
### Test Examples
```bash
# Test user creation (requires admin token)
pytest tests/api/v1/test_users.py::test_create_user -v
# Test authentication flows
pytest tests/core/test_auth.py -v
# Test unauthorized access
pytest tests/api/v1/test_users.py::test_create_user_unauthorized -v
```
## Development
### Project Structure
```
backend/
├── app/
│ ├── main.py # FastAPI application
│ ├── api/v1/ # API route handlers
│ ├── core/ # Config, database, auth
│ └── schemas/ # Pydantic models and enums
├── tests/ # Test suite
├── scripts/ # Utility scripts
├── alembic/ # Database migrations
├── requirements.txt # Dependencies
└── pyproject.toml # Project configuration
```
### Adding New Endpoints
1. Create route handler in `app/api/v1/`
2. Add authentication dependencies (`require_admin`, `require_write_access`, etc.)
3. Create corresponding tests in `tests/api/v1/`
4. Update this documentation
### Environment Variables
Set in `.env` file or environment:
```bash
SECRET_KEY=your-secret-key-here
DATABASE_URL=postgresql://user:pass@localhost/dbname
ADMIN_TOKEN_EXPIRE_MINUTES=480
WRITE_TOKEN_EXPIRE_MINUTES=240
READ_ONLY_TOKEN_EXPIRE_MINUTES=120
```
## API Examples
### Transaction Management
```bash
# Create transaction (requires write access)
curl -X POST "http://localhost:8000/api/v1/transactions/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"partner_id": 1,
"transcation_type": "sell",
"transaction_status": "unpaid",
"total_amount": 1000,
"created_by": 1,
"updated_by": 1
}'
# Get all transactions
curl -X GET "http://localhost:8000/api/v1/transactions/" \
-H "Authorization: Bearer YOUR_TOKEN"
# Update transaction
curl -X PUT "http://localhost:8000/api/v1/transactions/1" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"transaction_status": "paid"}'
# Delete transaction
curl -X DELETE "http://localhost:8000/api/v1/transactions/1" \
-H "Authorization: Bearer YOUR_TOKEN"
```
### User Management (Admin only)
```bash
# List all users
curl -X GET "http://localhost:8000/api/v1/users/" \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
# Update user role
curl -X PUT "http://localhost:8000/api/v1/users/2" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-d '{"role": "write"}'
# Delete user
curl -X DELETE "http://localhost:8000/api/v1/users/2" \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
```
## Troubleshooting
### Common Issues
1. **401 Unauthorized**: Check if token is expired or invalid
2. **403 Forbidden**: User doesn't have required role permissions
3. **422 Validation Error**: Check request body format and required fields
### Debug Mode
```bash
# Run with debug logging
uvicorn app.main:app --reload --log-level debug
```
### Database Issues
```bash
# Reset database (DANGER: deletes all data)
alembic downgrade base
alembic upgrade head
```