A production-minded multi-tenant task management API built with FastAPI, PostgreSQL, SQLAlchemy, JWT authentication, Docker, and GitHub Actions.
TeamFlow demonstrates backend engineering fundamentals that matter in real applications: authentication, role-based authorization, tenant isolation, database integrity, automated testing, migrations, containerization, and CI.
-
User registration and JWT-based authentication
-
Secure password hashing with Argon2
-
Multi-tenant organizations
-
Organization memberships
-
Role-based access control:
OWNERADMINMEMBER
-
Project management
-
Task management
-
Tenant-aware resource authorization
-
Cross-organization access protection
-
PostgreSQL persistence
-
Alembic database migrations
-
Automated API and security-focused tests
-
Dockerized development environment
-
GitHub Actions CI
TeamFlow is intentionally implemented as a modular monolith.
Client
│
▼
FastAPI
│
├── Authentication
│ └── JWT + password hashing
│
├── Authorization
│ └── Organization membership + RBAC
│
├── Organizations
│ └── Memberships
│
├── Projects
│ └── Organization-scoped resources
│
└── Tasks
└── Project + organization-scoped resources
│
▼
PostgreSQL
Every tenant-owned resource contains an organization_id.
The API does not trust a client-provided organization as proof of access. Authorization is based on the authenticated user's membership in the requested organization.
| Area | Technology |
|---|---|
| Language | Python |
| API | FastAPI |
| Database | PostgreSQL |
| ORM | SQLAlchemy |
| Validation | Pydantic |
| Migrations | Alembic |
| Authentication | JWT |
| Password hashing | Argon2 via pwdlib |
| Testing | pytest + HTTPX |
| Containerization | Docker + Docker Compose |
| CI | GitHub Actions |
| Dependency management | uv |
- View organization
- View members
- Add members
- Change member roles
- Remove members
- Create projects
- Update projects
- Delete projects
- Create, view, update, and delete tasks
- View organization
- View members
- Create projects
- Update projects
- View projects
- Create, view, update, and delete tasks
- Cannot manage organization membership
- Cannot delete projects
- View organization
- View members
- View projects
- Create tasks
- View tasks
- Update tasks
- Cannot manage members
- Cannot create, update, or delete projects
- Cannot delete tasks
TeamFlow treats organization boundaries as a security boundary.
For organization-scoped resources, authorization follows this pattern:
Authenticated User
│
▼
Organization Membership
│
▼
Authorized Organization
│
├── Projects
│
└── Tasks
Project and task queries include organization scope rather than relying only on resource IDs.
For example, a task lookup is constrained by:
task_id
+
organization_id
+
project_id
This prevents resources from being accessed simply by guessing an ID belonging to another organization.
POST /auth/register
POST /auth/login
GET /users/me
POST /organizations
GET /organizations
GET /organizations/{organization_id}
GET /organizations/{organization_id}/members
POST /organizations/{organization_id}/members
PATCH /organizations/{organization_id}/members/{user_id}
DELETE /organizations/{organization_id}/members/{user_id}
POST /organizations/{organization_id}/projects
GET /organizations/{organization_id}/projects
GET /organizations/{organization_id}/projects/{project_id}
PATCH /organizations/{organization_id}/projects/{project_id}
DELETE /organizations/{organization_id}/projects/{project_id}
POST /organizations/{organization_id}/projects/{project_id}/tasks
GET /organizations/{organization_id}/projects/{project_id}/tasks
GET /organizations/{organization_id}/projects/{project_id}/tasks/{task_id}
PATCH /organizations/{organization_id}/projects/{project_id}/tasks/{task_id}
DELETE /organizations/{organization_id}/projects/{project_id}/tasks/{task_id}
GET /health
TeamFlow/
├── alembic/
│ ├── versions/
│ └── env.py
├── src/
│ └── teamflow/
│ ├── auth.py
│ ├── database.py
│ ├── main.py
│ ├── models.py
│ ├── organizations.py
│ ├── projects.py
│ ├── schemas.py
│ ├── security.py
│ ├── tasks.py
│ └── users.py
├── tests/
│ ├── conftest.py
│ ├── test_api.py
│ └── test_security.py
├── .dockerignore
├── .env.example
├── .gitignore
├── Dockerfile
├── compose.yml
├── alembic.ini
├── pyproject.toml
└── uv.lock
- Python 3.12+
- uv
- Docker Desktop
git clone https://github.com/Mugheerik/TeamFlow
cd TeamFlowCopy the example environment file:
Copy-Item .env.example .envGenerate a development JWT secret:
python -c "import secrets; print(secrets.token_urlsafe(32))"Put the generated value in .env:
DATABASE_URL=postgresql+psycopg://teamflow:teamflow@localhost:5432/teamflow
JWT_SECRET_KEY=your-generated-secretdocker compose up -d postgresuv run alembic upgrade headuv run uvicorn teamflow.main:app --reloadThe API will be available at:
http://localhost:8000
Interactive API documentation:
http://localhost:8000/docs
Health check:
http://localhost:8000/health
Expected response:
{
"status": "ok"
}The complete application stack can be started with:
docker compose up -dCheck running services:
docker compose psApply migrations:
uv run alembic upgrade headCheck the API:
curl.exe http://localhost:8000/healthStop the stack:
docker compose downRun the complete test suite:
uv run pytestThe test suite covers authentication, organization membership, RBAC, project authorization, task authorization, and cross-tenant access boundaries.
The current suite passes with:
35 passed
Tests intentionally focus on important application behavior and security boundaries rather than pursuing arbitrary code-coverage targets.
Create a migration after a model change:
uv run alembic revision --autogenerate -m "describe change"Review the generated migration before applying it.
Apply migrations:
uv run alembic upgrade headCheck the current database revision:
uv run alembic currentEvery push to main and pull request targeting main runs GitHub Actions.
The CI pipeline:
- Checks out the repository
- Installs
uv - Sets up Python
- Installs locked dependencies
- Starts PostgreSQL
- Runs Alembic migrations
- Executes the test suite
This provides an automated verification step before changes are considered integrated.
TeamFlow implements several application-level security controls:
- Passwords are never stored in plaintext.
- Passwords are hashed using Argon2.
- Authentication uses signed JWT access tokens.
- Protected endpoints require authentication.
- Organization access requires membership.
- Role permissions are enforced server-side.
- Organization ownership cannot be transferred through the membership role endpoint.
- Members cannot remove themselves as organization owners.
- Cross-organization resource access is explicitly tested.
- Resource queries include organization scope.
- Secrets are supplied through environment variables rather than committed to the repository.
This project is intended as a backend engineering demonstration and is not presented as a production-ready SaaS security system.
The project is intentionally small enough to understand as a single deployable application.
Introducing microservices, message brokers, distributed caches, or Kubernetes would add operational complexity without providing meaningful value for the current problem.
The application requires relational data, foreign keys, unique constraints, transactions, and organization-based relationships. PostgreSQL provides these capabilities directly.
Authentication answers:
Who is this user?
Authorization answers:
What is this user allowed to do here?
TeamFlow keeps those concerns separate so that organization membership and role checks are explicit in the application.
Complete
The project has met its intended scope:
- Authentication
- Authorization
- Multi-tenancy
- RBAC
- Projects
- Tasks
- PostgreSQL
- Migrations
- Security-focused testing
- Docker
- CI
Further infrastructure such as microservices, Redis, Kafka, Kubernetes, or cloud deployment is intentionally outside the scope of this project.
TeamFlow is designed to demonstrate practical backend engineering ability rather than simply CRUD implementation.
Key areas demonstrated:
API Design
↓
Authentication
↓
Authorization / RBAC
↓
Multi-Tenant Data Isolation
↓
Relational Database Design
↓
Testing Security Boundaries
↓
Database Migrations
↓
Containerization
↓
Continuous Integration
This project forms part of a broader progression toward backend, cloud, distributed systems, and intelligent systems engineering.