Project backend for an auto dealership system: user authentication, role-based access (customer/employee/admin), catalog management (cities/dealerships/models/vehicles), sales flows (orders and custom orders), customer activity (reviews, favorites, test drives), and an audit/logging subsystem.
- Features
- Tech stack
- Architecture and repository structure
- Configuration
- How to run
- Database initialization
- API overview
- Authentication and sessions
- Audit logging and reports (MongoDB)
- Known limitations / important notes
- Troubleshooting
- Authentication: signup, login, refresh, logout with JWT access/refresh tokens.
- RBAC (roles):
customer,employee,adminrestrictions at endpoint level and in service logic. - Users and customers: manage user accounts and customer profile records.
- Reference data: cities and dealerships.
- Vehicle catalog: models, features/options, and vehicles in stock.
- Transactions: orders (stock vehicles) and custom orders (factory-style).
- Customer activity: reviews, favorites, test drives.
- Audit logs and reports: store mutating actions and errors in MongoDB, query and export reports.
- Caching / invalidation: Redis cache + Redis Pub/Sub channel for cache invalidation on data changes.
- Python: 3.12
- Web framework: FastAPI
- SQL database: PostgreSQL (async) via
asyncpg - Cache / sessions / pubsub: Redis (
redis.asyncio) - Audit / analytics storage: MongoDB (Motor)
- Object storage: S3-compatible (MinIO in Docker) via
aioboto3 - Dependency management: Poetry (
pyproject.toml) - Containerization: Docker + Docker Compose (
Dockerfile,docker-compose.yaml)
The backend follows a layered structure:
- API layer (
src/api/)\n- Versioned HTTP routes live in
src/api/v1/endpoints/.\n - Routing aggregation:
src/api/v1/router.py.\n - Security helpers:
src/api/security.py.\n - RBAC decorator:
src/api/rbac.py.\n - Dependencies (DI providers):
src/api/dependencies/.\n - Middleware:
src/api/middlewares/(audit logging).\n - Exception mapping:
src/api/exception_handlers.py.\n
- Versioned HTTP routes live in
- Application layer (
src/application/)\n- Services implement use cases (e.g.
src/application/services/auth_service.py).\n - DTOs and mappers translate between API models and domain entities.\n
- Services implement use cases (e.g.
- Domain layer (
src/domain/)\n- Entities, value objects, and abstractions/interfaces.\n
- Domain exceptions (auth, tokens, business rules).\n
- Infrastructure layer (
src/infrastructure/)\n- PostgreSQL connection/UoW/repositories.\n
- Redis client/repositories/healthcheck.\n
- MongoDB client + log repository.\n
- S3 client implementation.\n
- Startup helpers (e.g. employee seeding).\n
The application uses environment variables (Pydantic settings in src/config.py). A template is provided in .env.example.
Create a .env file at the repository root (next to docker-compose.yaml) with at least:
POSTGRES_USERPOSTGRES_PASSWORDPOSTGRES_NAMEPOSTGRES_HOST(when running locally without Docker, typicallylocalhost)POSTGRES_PORT(typically5432)
REDIS_USERREDIS_PASSWORD(Redisrequirepass)\nREDIS_USER_PASSWORD(ACL user password)\nREDIS_HOST(typicallylocalhost)\nREDIS_PORT(Docker compose maps to6380on host)
MONGO_HOSTMONGO_PORT(typically27017)MONGO_USERMONGO_PASSWORDMONGO_DB(default in compose:audit_logs)
The backend expects an RSA key pair:
PRIVATE_KEY: PEM string (PKCS8 recommended)PUBLIC_KEY: PEM string
Generate locally:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private_key.pem
openssl rsa -pubout -in private_key.pem -out public_key.pemThen paste PEM contents into .env values (including the -----BEGIN ...----- / -----END ...----- lines).
Media storage is optional in runtime: if S3_ACCESS_KEY / S3_SECRET_ACCESS_KEY are missing, the S3 client provider returns None (see src/api/dependencies/s3.py).
S3_ACCESS_KEYS3_SECRET_ACCESS_KEYS3_ENDPOINT_URL(Docker:http://minio:9000, local host: typicallyhttp://localhost:9000)S3_BUCKET_NAME(default in compose:auto-dealer-media)S3_REGION_NAME(e.g.us-east-1)
When running via Docker Compose, some connection settings are overridden for container-to-container networking in docker-compose.yaml:
POSTGRES_HOST=databaseREDIS_HOST=redisS3_ENDPOINT_URL=http://minio:9000
This brings up the backend and its dependencies (Postgres, Redis, MinIO, MongoDB). The compose file also contains a frontend service, but the backend can be used independently.
-
Create
.envfrom.env.exampleand fill values. -
Pull MinIO images before running compose.\n
docker-compose.yamlusespull_policy: neverfor MinIO images, so you must have them locally:
docker pull minio/minio:latest
docker pull minio/mc:latest- Start services:
docker compose up --build- Backend is available at:
- API base:
http://localhost:8000/api/v1 - OpenAPI docs:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc
- Install dependencies:
poetry install-
Export env vars via
.env(or your shell), ensure Postgres/Redis/Mongo are running locally. -
Run FastAPI:
poetry run uvicorn src.main:app --host 0.0.0.0 --port 8000 --reloadAll API routes are under /api/v1 (see src/api/v1/router.py).
Primary routers:
/auth(signup/signin/refresh/logout)/health/users,/customers/cities,/dealerships/models,/features,/vehicles/orders,/custom-orders/reviews,/test-drives,/favorites/logs(audit logs + reports)