TaskLane is a production-ready, containerized full-stack Mini Kanban Board application designed for streamlined, distraction-free task management.
- Live Application URL: https://tasklane-app.onrender.com
- Interactive OpenAPI Docs: https://tasklane-app.onrender.com/docs
- GitHub Repository: https://github.com/LE0ST/tasklane
This project was developed across the AI Dev Tools Zoomcamp 2026 by DataTalks.Club:
-
Homework 2 (Spec-First Full-Stack Application):
- Defined product requirements and state transitions in
_docs/specs.md. - Designed OpenAPI 3.1 contract (
openapi.yaml). - Implemented FastAPI backend with Pydantic v2 and SQLite persistence.
- Built React Kanban UI with centralized API abstraction.
- Defined product requirements and state transitions in
-
Homework 3 (Containerization, PostgreSQL, CI/CD, and Cloud Deployment):
- Upgraded database layer to PostgreSQL 16 with Alembic schema migrations.
- Built a multi-stage production Dockerfile (Node 20 Alpine builder + Python 3.11 slim runtime) serving compiled static assets from FastAPI.
- Created Docker Compose stack with isolated PostgreSQL services and health checks.
- Implemented automated PostgreSQL integration tests and Playwright E2E browser tests.
- Built a 3-stage GitHub Actions CI/CD pipeline verifying builds, tests, Compose, and E2E in Chromium.
- Deployed live to Render (Docker Web Service + Managed PostgreSQL).
graph TD
subgraph Client Layer
Browser[Web Browser / Evaluator]
end
subgraph Render Cloud Platform
subgraph Render Web Service - Docker Multi-Stage
FastAPI[FastAPI Backend :10000]
Static[Mounted React 19 SPA Dist]
FastAPI --- Static
end
subgraph Render Managed Database
PG[(PostgreSQL 16 Database)]
end
FastAPI -->|Internal DATABASE_URL<br/>Alembic Migrations on Lifespan| PG
end
subgraph CI/CD Pipeline - GitHub Actions
GHA[Push to main / PR]
J1[1. Frontend Build & Asset Bundle]
J2[2. Backend Unit & Postgres Integration Tests]
J3[3. Docker Build, Smoke Tests & Playwright E2E]
GHA --> J1
J1 --> J2
J1 --> J3
J2 --> J3
end
Browser -->|HTTPS :443| FastAPI
| Layer | Technologies | Role / Highlights |
|---|---|---|
| Frontend | React 19, Vite 6, CSS Modules | Responsive 5-column Kanban board, live filters, modal dialogs |
| Backend | FastAPI, Uvicorn, Pydantic v2 | RESTful API, input validation, static file serving, lifespan hooks |
| Database & ORM | PostgreSQL 16, SQLAlchemy 2.0, Alembic | Relational data persistence, schema migrations (1ea1353bfe87) |
| Containerization | Docker, Multi-stage builds, Docker Compose | Node 20 builder + Python 3.11 slim runtime, pinned uv:0.12.18 |
| Testing | pytest, httpx, @playwright/test |
14 API/unit tests, 5 PostgreSQL integration tests, 9 E2E browser tests |
| CI/CD | GitHub Actions | Automated builds, migrations, smoke checks, Playwright E2E |
| Cloud Hosting | Render | Docker Web Service + Render Managed PostgreSQL |
- Deterministic 5-Stage Kanban Workflow:
Backlog→To Do→In Progress→Review→Done. - Enforced Initial Placement: All new tasks are strictly created in
Backlog. - Sequential Card Controls: Previous/next status transition buttons (
←/→), automatically disabled at column boundaries. - Search & Filtering: Real-time filtering by priority (
low,medium,high,urgent) and substring search across task titles and descriptions. - Deterministic Ordering: Tasks are returned newest first (
created_at DESC,id DESC). - Input Validation: Empty titles, invalid priorities, and illegal client-supplied creation statuses are rejected with
422 Unprocessable Entity. - Health Check Endpoints:
/healthand/api/healthreturning{"status": "healthy"}for container and cloud orchestrators.
tasklane/
├── .github/
│ └── workflows/
│ └── ci.yml # 3-job GitHub Actions CI/CD pipeline
├── _docs/
│ └── specs.md # Product specifications and acceptance criteria
├── backend/ # FastAPI + SQLAlchemy + Alembic application
│ ├── alembic/ # Alembic configuration and migration versions
│ │ ├── versions/
│ │ │ └── 1ea1353bfe87_create_tasks_table.py
│ │ └── env.py
│ ├── tests/
│ │ ├── test_api.py # 14 unit and API route tests
│ │ └── test_postgres_integration.py # 5 PostgreSQL integration tests
│ ├── alembic.ini # Alembic CLI configuration
│ ├── database.py # Database connection, pooling, URL normalization
│ ├── main.py # FastAPI entrypoint, lifespan migrations, static mounts
│ ├── models.py # SQLAlchemy Task ORM model
│ ├── pyproject.toml # uv dependencies and pytest markers
│ ├── schemas.py # Pydantic v2 schemas
│ └── uv.lock # Locked Python dependency tree
├── frontend/ # React 19 + Vite application
│ ├── e2e/
│ │ └── kanban.spec.js # 9 Playwright end-to-end browser scenarios
│ ├── src/
│ │ ├── services/
│ │ │ └── api.js # Centralized API client abstraction
│ │ ├── App.css # Responsive Kanban styling
│ │ ├── App.jsx # Board component and state logic
│ │ ├── index.css # Global design tokens
│ │ └── main.jsx # React entrypoint
│ ├── index.html # Single page application template
│ ├── package.json # Node dependencies and scripts
│ ├── package-lock.json # Locked Node dependencies
│ ├── playwright.config.js # Playwright E2E configuration
│ └── vite.config.js # Vite bundler configuration
├── .dockerignore # Docker build context exclusions
├── .env.example # Environment configuration template
├── .gitignore # Git version control exclusions
├── Dockerfile # Multi-stage production container definition
├── docker-compose.yml # Local multi-service PostgreSQL + App stack
├── openapi.yaml # OpenAPI 3.1 specification
└── README.md # Comprehensive project documentation
- Docker & Docker Compose or:
- Python 3.10+ with
uvand Node.js 20+ withnpm.
To start the full-stack containerized application with PostgreSQL 16:
docker compose up --buildThis command:
- Builds the multi-stage Docker image packaging React into FastAPI.
- Starts
postgres:16-alpinewith health checks on127.0.0.1:5432. - Runs Alembic migrations automatically on startup via FastAPI lifespan.
- Serves the full-stack application at
http://localhost:8000.
To stop and remove containers:
docker compose down
# Or to also wipe local volume data:
docker compose down -v-
Backend:
cd backend uv sync uv run uvicorn main:app --reload --port 8000(Defaults to local SQLite
tasklane.dbifDATABASE_URLis omitted). -
Frontend:
cd frontend npm install npm run devAvailable at
http://localhost:5173(proxies requests to backend on port 8000).
Configure environment variables in .env (copied from .env.example) or in your deployment dashboard:
| Variable | Required | Default (Local) | Purpose |
|---|---|---|---|
DATABASE_URL |
No | sqlite:///./tasklane.db (local dev) |
Connection string (PostgreSQL or SQLite). Automatically normalizes postgres:// to postgresql://. |
POSTGRES_USER |
No | postgres |
PostgreSQL username in Docker Compose. |
POSTGRES_PASSWORD |
No | postgres |
PostgreSQL password in Docker Compose. |
POSTGRES_DB |
No | tasklane |
PostgreSQL database name in Docker Compose. |
PORT |
No | 8000 |
HTTP port for Uvicorn server (dynamically overridden by cloud platforms). |
HOST |
No | 0.0.0.0 |
Bind host address. |
VITE_API_BASE_URL |
No | "" (production) / http://localhost:8000 (dev) |
API base path prefix for frontend. |
Warning
Never commit real secrets or production credentials to Git. Keep .env listed in .gitignore.
To run all 19 unit, API, and PostgreSQL integration tests:
cd backend
uv run pytest -v- 14 Unit/API Tests: Task creation, schema validation, column progression, 404 handling, search/filter, and Alembic error propagation.
- 5 PostgreSQL Integration Tests: Runs against real PostgreSQL instance, validating schema creation, sequence autoincrement, status transitions, clean deletions, and multi-session persistence.
To run the 9 E2E browser tests:
cd frontend
npm run test:e2e- Uses local Microsoft Edge on Windows (no heavy downloads required) and official Chromium in CI.
- Scenarios covered: App load & branding, 5 columns render, task creation in Backlog, forward/backward card movements, priority filtering, title search, reload persistence, deletion, and console/page error listening.
TaskLane uses a 3-stage GitHub Actions workflow (.github/workflows/ci.yml) running on pushes and pull requests to main:
frontend-build:- Compiles React production bundle with Vite.
- Uploads compiled
frontend-distartifact.
backend-tests:- Provisions fresh
postgres:16-alpineservice container. - Creates dedicated
tasklane_testdatabase and runsalembic upgrade head. - Downloads
frontend-distand executes all 19 pytest tests with--strict-markers(0 skipped).
- Provisions fresh
docker-e2e-smoke:- Builds multi-stage production Docker image (
tasklane:hw3). - Spins up ephemeral Docker Compose stack.
- Polls
/healthuntil ready, executes HTTP smoke tests (health, CRUD, static HTML). - Installs Chromium and runs all 9 Playwright E2E scenarios against the live container.
- Uploads Playwright HTML report on failure and tears down with
docker compose down -v.
- Builds multi-stage production Docker image (
TaskLane is publicly deployed on Render:
- Application URL: https://tasklane-app.onrender.com
- Deployment Mode: Render Web Service (Docker Runtime) connected directly to
LE0ST/tasklane(mainbranch). - Database: Dedicated Render Managed PostgreSQL 16 database (
tasklane-db) in the same region. - Internal Networking: Web Service communicates with PostgreSQL over Render's private internal network via
DATABASE_URL(postgres://...). - Automatic Migrations: Alembic migrations run automatically on container startup inside the FastAPI lifespan handler.
- Graceful Shutdown: The Dockerfile entrypoint uses
exec uvicornto receive POSIXSIGTERMsignals directly from Render.
- Sleep on Inactivity: Free Web Services spin down after 15 minutes of idle time. The first subsequent request triggers a cold start taking 50 to 60 seconds.
- Instance Hours: 750 free instance hours per month pooled across the workspace.
- PostgreSQL Expiration: Render Free PostgreSQL instances expire 30 days after creation, with a short upgrade grace period before permanent deletion.
- No Managed Backups: The Free database tier does not include automated snapshots or point-in-time restore.
- Public Demonstration Disclaimer: This deployment is an unauthenticated educational demonstration. Do not submit sensitive, personal, or confidential information.
If a regression is identified in a deployed version:
- In the Render Dashboard, navigate to the
tasklaneWeb Service. - Open the Deploys tab and find the last known healthy deployment.
- Click "Rollback to this deploy". Render will immediately redirect traffic to the previous immutable container image.
Caution
Application rollback does NOT revert database migrations or recover altered database data.
- Avoid Blind Downgrades: Executing
alembic downgrade -1is not a generic safe recovery tool in production, as dropping columns or tables can cause irreversible data loss. - Additive Migrations: Follow the expand-contract pattern for schema changes. When repairing schema issues, deploy a forward-fixing Alembic migration rather than a downgrade.
- Logical Backups: For critical state preservation, generate manual SQL dumps using
pg_dumpvia the external connection string prior to running major migrations.