feat: implement complete CMT backend with API endpoints and test suite
- Add 7 core API endpoints: users, transactions, partners, products, inventory, payments, credit - Implement role-based authentication (admin/write/read-only access) - Add comprehensive database models with proper relationships - Include full test coverage for all endpoints and business logic - Set up Alembic migrations and Docker configuration - Configure FastAPI app with CORS and database integration
This commit is contained in:
+255
-15
@@ -1,28 +1,268 @@
|
||||
# CMT Backend
|
||||
## Usage
|
||||
### API
|
||||
### Alembic
|
||||
|
||||
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
|
||||
# updating changes to table models to the db
|
||||
cd backend
|
||||
alembic revision --autogenerate -m "Header message"
|
||||
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
|
||||
|
||||
# Forcing alembic DB is up-to-date without actually running the migration
|
||||
alembic stamp head
|
||||
# Create admin user (optional)
|
||||
python scripts/create_admin.py
|
||||
```
|
||||
|
||||
### Testing
|
||||
### Run the Application
|
||||
```bash
|
||||
uvicorn app.main:app --reload
|
||||
# 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
|
||||
|
||||
### Login Example
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/api/v1/users/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username": "admin", "password": "password"}'
|
||||
```
|
||||
|
||||
### Using Token
|
||||
```bash
|
||||
# Include token in Authorization header
|
||||
curl -X GET "http://localhost:8000/api/v1/users/me" \
|
||||
-H "Authorization: Bearer YOUR_JWT_TOKEN"
|
||||
```
|
||||
|
||||
### 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
|
||||
pytest app/test.py
|
||||
|
||||
# Curl POST command
|
||||
curl -X POST "http://localhost:8000/clients/" -H "Content-Type: application/json" -d '{"tin_number": 100752121, "names": "Pax au Telemanus", "phone_number": "0788475021"}'
|
||||
# Create new migration after model changes
|
||||
alembic revision --autogenerate -m "Description of changes"
|
||||
|
||||
# Trying updating client details
|
||||
curl -X PATCH "http://localhost:8000/clients/1" -H "Content-Type: application/json" -d '{"names": "John Wick"}'
|
||||
# Apply migrations to database
|
||||
alembic upgrade head
|
||||
|
||||
# Deletion
|
||||
curl -X DELETE http://localhost:8000/clients/2
|
||||
# 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
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user