A robust, secure, and clean-architecture Task Management API (simplified version of systems like Trello or Asana) built with Python 3.11+, FastAPI, MongoDB (Motor async), JWT Authentication (Access & Refresh Tokens), and Object-Level Role-Based Access Control (RBAC).
- Clean Layered Architecture (DDD): Strict separation of concerns across Domain, Repositories, Services, and API Controllers.
- Dual-Token JWT Security: Short-lived Access Tokens (30 mins) + Long-lived Refresh Tokens (7 days) with strict claim type validation.
- Object-Level RBAC Security: Strict permission checking enforcing project ownership for mutations and membership for read access.
- RESTful Sub-Resources: Add & remove project members by email via dedicated sub-resource endpoints (
/projects/{id}/members). - Multi-Criteria Task Filtering & Full-Text Search: Filter by status, assignee, due date, project, and perform regex keyword search over titles and descriptions.
- Paginated Responses: Standardized pagination metadata (
page,limit,total_pages,has_next,has_prev). - Task Audit Trail (Activity Logs): Automatic change tracking log stream for task updates and status transitions (
GET /tasks/{id}/activities). - Sliding-Window Rate Limiting Middleware: Per-IP request limiter (
RateLimitMiddleware) preventing API abuse (429 Too Many Requests). - Structured Logging & Request Correlation: Injects unique
X-Request-IDUUID headers andX-Process-Timetiming headers into every response. - Containerization & Automated Testing: 1-command Docker Compose setup and 100% passing
pytesttest suite (13 passed).
The application strictly follows Clean Architecture (Layered Domain-Driven Design) to isolate domain business rules from database frameworks, web drivers, and external protocols.
┌─────────────────────────────────────────────────────────┐
│ HTTP / REST │
│ FastAPI Routers & Middleware │
└────────────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Application Layer │
│ Services & Authorization Checks │
└────────────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Data Access Layer │
│ Repositories & MongoDB Aggregations │
└────────────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Database Layer │
│ MongoDB (Motor Async Engine) │
└────────────────────────────┴────────────────────────────┘
src/app/
├── core/ # Configuration, database lifecycle, security, logging & middleware
├── domain/ # Pydantic v2 domain schemas, custom ObjectId type, enums
├── repositories/ # Async MongoDB data access layer & queries
├── services/ # Application services, business logic, and RBAC enforcement
├── api/ # HTTP controller layer with FastAPI routers & dependencies
└── main.py # App initialization, CORS, exception handlers & health check
-
usersCollection:_id:ObjectIdname:stremail:str(lowercase, unique)hashed_password:str(Bcrypt)created_at/updated_at:datetime(UTC)
-
projectsCollection:_id:ObjectIdname:strdescription:str(optional)owner_id:ObjectId(references user)members:list[ObjectId](array of member user IDs)created_at/updated_at:datetime(UTC)
-
tasksCollection:_id:ObjectIdproject_id:ObjectId(references project)title:strdescription:str(optional)status:strenum (todo,in_progress,done)due_date:datetime(optional)assignee_id:ObjectId(optional, references user)created_by:ObjectId(references user)created_at/updated_at:datetime(UTC)
-
task_activitiesCollection (Audit Trail):_id:ObjectIdtask_id:ObjectId(references task)user_id:ObjectId(actor who modified task)action:str(created,updated,deleted)changes:dict(diff of modified fields)timestamp:datetime(UTC)
To optimize high-throughput read/write operations and filtering queries, the following indexes are automatically created at application startup:
users.email:unique=True(guarantees DB-level email uniqueness).projects.owner_id&projects.members: Single-field and multikey indexes for fast authorization lookups.projects.[("members", 1), ("created_at", -1)]: Compound index for listing projects sorted by creation date.tasks.[("project_id", 1), ("status", 1), ("assignee_id", 1), ("due_date", 1)]: Compound filter index optimizing multi-criteria task queries.task_activities.[("task_id", 1), ("timestamp", -1)]: Fast chronological audit trail retrieval.
- Password Hashing: Uses
passlibwith standardbcrypthashing for secure password storage. - JWT Dual-Token Security: Short-lived Access Tokens (30 mins) + Long-lived Refresh Tokens (7 days) with
typeclaim validation. - Object-Level Authorization (RBAC):
- Project Access: Users can only view projects they own or are members of.
- Project Mutation & Deletion: Only the project Owner can update project details, manage members, or delete the project.
- Task Access & Creation: Tasks can only be created, viewed, updated, or deleted within projects where the authenticated user is an owner or member.
- Task Filter Authorization: Task list queries automatically scope results to permitted projects, preventing unauthorized data leakage.
- Input Validation: Enforced at the boundary layer using Pydantic v2 models with strict type validation.
- Rate Limiting: IP-based sliding window rate limiter protects endpoints against brute-force attacks (
429 Too Many Requests).
- Python 3.11+
- MongoDB instance running locally on
mongodb://localhost:27017OR Docker
# 1. Clone repository & change directory
cd "path/to/ivs task"
# 2. Create virtual environment
python3 -m venv venv
source venv/bin/activate
# 3. Install dependencies
pip install -r requirements.txt
# 4. Copy environment configuration
cp .env.example .env
# 5. Run API server
python run.pyOr alternatively:
PYTHONPATH=src uvicorn app.main:app --reload --port 8000API will be live at http://localhost:8000. Interactive Swagger UI is available at http://localhost:8000/docs.
# Build and run API + MongoDB container stack
docker-compose up --build -dThe stack spins up:
- FastAPI Backend:
http://localhost:8000 - MongoDB 7.0:
localhost:27017
The repository features a complete test suite built with pytest, pytest-asyncio, and httpx. Tests run against an in-memory mongomock_motor client, so no live database is needed to execute tests.
# Run pytest
venv/bin/pytest -vDetailed endpoint contracts, request/response examples, and error codes are documented in API_DOCUMENTATION.md.
Navigate to http://localhost:8000/docs while the server is running to test all API endpoints interactively.
Run the included export utility script:
python generate_postman.pyThis generates:
openapi.json: OpenAPI 3.0 specification file.postman_collection.json: Importable Postman v2.1 collection.
| Category | Method | Endpoint | Description |
|---|---|---|---|
| Auth | POST |
/api/v1/auth/register |
Register user account |
| Auth | POST |
/api/v1/auth/login |
Authenticate user & issue access + refresh JWT |
| Auth | POST |
/api/v1/auth/refresh |
Refresh access token using refresh token |
| Auth | GET |
/api/v1/auth/me |
Get current user profile |
| Projects | POST |
/api/v1/projects |
Create a new project |
| Projects | GET |
/api/v1/projects |
List projects user belongs to |
| Projects | GET |
/api/v1/projects/{id} |
Get project by ID |
| Projects | PUT |
/api/v1/projects/{id} |
Update project (Owner only) |
| Projects | POST |
/api/v1/projects/{id}/members |
Add project member by email (Owner only) |
| Projects | DELETE |
/api/v1/projects/{id}/members/{user_id} |
Remove project member (Owner only) |
| Projects | DELETE |
/api/v1/projects/{id} |
Delete project & tasks (Owner only) |
| Tasks | POST |
/api/v1/tasks |
Create task inside project |
| Tasks | GET |
/api/v1/tasks |
Filter, search (?search=), and paginate tasks |
| Tasks | GET |
/api/v1/tasks/{id} |
Get task by ID |
| Tasks | PUT |
/api/v1/tasks/{id} |
Update task details/status |
| Tasks | DELETE |
/api/v1/tasks/{id} |
Delete task |
| Activities | GET |
/api/v1/tasks/{id}/activities |
Retrieve task activity history |