# 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 ```