A multi-tenant project management platform inspired by Linear and Jira. Built as a learning project to demonstrate full-stack TypeScript, real-time features, AI integration, and backend system design.
Lane lets teams organise work into workspaces → projects → tickets, with:
- Role-based access control (Creator / Admin / Editor / Viewer)
- Kanban board with real-time drag-and-drop sync across all open tabs
- Infinite-scroll ticket list, comments, labels, due dates, and activity history
- Server-Sent Events for live ticket updates without polling
- Background email and embedding jobs via BullMQ
AI features (all provider-agnostic, degrade gracefully when disabled):
- Semantic duplicate detection — vector similarity + LLM confirmation fallback
- Description generator with RAG — generates structured descriptions; improves existing ones using context from resolved tickets
- Assignee suggestion — recommends the least-loaded, best-matched team member
- Ask Lane — natural language queries with discriminated intent: filter tickets or retrieve team knowledge via RAG
- Weekly summary — synthesized digest of the past 7 days (cached 1 hr)
- Bottleneck detection — identifies where tickets stall in your workflow (cached 10 min)
- Project planner — groups open tickets into logical themes (feature-flagged)
lane/
├── backend/ Node.js + Express + TypeScript API
├── frontend/ React 19 + Vite SPA
├── docker-compose.yml PostgreSQL + Redis + RedisInsight
└── README.md ← you are here
| Document | What it covers |
|---|---|
| backend/README.md | API setup, Docker services, environment variables, all endpoints, Redis/Postgres connection details |
| frontend/README.md | SPA setup, routes, tech stack, project structure, key patterns |
| docs/SCALING.md | How Lane would scale from a single server to millions of users |
- Node.js 20+
- Docker Desktop
# From this directory
docker-compose up -d| Service | URL / Port | Purpose |
|---|---|---|
| PostgreSQL | localhost:5432 |
Primary database |
| Redis | localhost:6379 |
Cache + job queue + SSE |
| RedisInsight | http://localhost:5540 |
Redis browser GUI |
cd backend
npm install
npm run db:migrate
npm run db:seed # creates TechFlow demo workspace
npm run dev # http://localhost:5000cd frontend
npm install
npm run dev # http://localhost:5173All demo accounts use password password123:
| Role | |
|---|---|
| alice@lane.dev | Creator |
| bob@lane.dev | Admin |
| carol@lane.dev | Editor |
| dave@lane.dev | Editor |
| emma@lane.dev | Viewer |
| Layer | Choice |
|---|---|
| API | Node.js + Express + TypeScript |
| Database | PostgreSQL via Prisma ORM |
| Cache / Queue | Redis + BullMQ |
| Auth | JWT (access token in memory) + HttpOnly refresh cookie + Google OAuth |
| Real-time | Server-Sent Events (SSE) |
| AI (LLM) | Gemini / OpenAI / OpenRouter (provider-agnostic; swap via AI_PROVIDER) |
| AI (Embeddings) | OpenRouter nvidia/llama-nemotron-embed-vl-1b-v2:free via EMBEDDING_PROVIDER |
| Vector DB | pgvector extension on PostgreSQL (vector(2048) columns) |
| Frontend | React 19 + Vite + Tailwind CSS + shadcn/ui |
| Server state | TanStack Query v5 |
| Client state | Zustand |
Client (React SPA)
│ REST + SSE
▼
Express API
┌─────────────────────────────────────┐
│ Auth MW → Workspace MW → RBAC MW │
│ Zod Validation │
│ Controllers → Services → Repos │
└───────────────┬─────────────────────┘
│
┌─────────┴──────────┐
▼ ▼
PostgreSQL + pgvector Redis
(Prisma ORM) (cache · rate limit · BullMQ)
│
▼
BullMQ Workers
(email · embeddings)
│
▼
OpenRouter API
(LLM + embedding model)
Every request is scoped to a workspace at the middleware layer and again inside every repository query — defence in depth against cross-tenant data leakage.
See docs/SCALING.md for how this architecture evolves under load.