Skip to content

Commit ced30b0

Browse files
MLaitarovskyclaude
andcommitted
feat: Week 5 — production Dockerfiles, CI pipeline, README, landing page
- Production Dockerfiles for API (with CMD) and frontend (multi-stage build) - docker-compose.prod.yml with health checks and proper service deps - Configurable CORS origins via env var - GitHub Actions CI: ruff lint/format (backend) + ESLint/tsc (frontend) - Professional README with badges, Mermaid architecture diagram, resume bullets - MIT license - Public landing page with hero, feature cards, and auth-aware CTA - 404 page - Dashboard moved to /dashboard route to free root for landing page - Celery NullPool fix for stale DB connections in forked workers - Code cleanup: ruff formatting, unused imports, raise-from-none fixes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 580e34c commit ced30b0

46 files changed

Lines changed: 909 additions & 310 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,19 @@ DATABASE_URL=postgresql+asyncpg://docpilot:docpilot_secret@postgres:5432/docpilo
88
REDIS_URL=redis://redis:6379/0
99

1010
# ── JWT Auth ───────────────────────────────────────────
11-
SECRET_KEY=change-me-to-a-random-secret
11+
SECRET_KEY=change-me-to-a-random-string
1212
ACCESS_TOKEN_EXPIRE_MINUTES=30
1313
REFRESH_TOKEN_EXPIRE_DAYS=7
1414

1515
# ── OpenAI ─────────────────────────────────────────────
1616
OPENAI_API_KEY=sk-your-key-here
1717
LLM_MODEL=gpt-4o-mini
1818

19+
# ── CORS ───────────────────────────────────────────────
20+
CORS_ORIGINS=http://localhost:3000,http://localhost:3001
21+
1922
# ── File Storage ───────────────────────────────────────
2023
UPLOAD_DIR=/data/uploads
24+
25+
# ── Frontend (used at build time by Next.js) ───────────
26+
NEXT_PUBLIC_API_URL=http://localhost:8001

.github/workflows/ci.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
backend-lint:
11+
name: Backend Lint & Format
12+
runs-on: ubuntu-latest
13+
defaults:
14+
run:
15+
working-directory: apps/api
16+
steps:
17+
- uses: actions/checkout@v4
18+
- uses: actions/setup-python@v5
19+
with:
20+
python-version: "3.12"
21+
- run: pip install ruff
22+
- run: ruff check .
23+
- run: ruff format --check .
24+
25+
frontend-check:
26+
name: Frontend Lint & Typecheck
27+
runs-on: ubuntu-latest
28+
defaults:
29+
run:
30+
working-directory: apps/web
31+
steps:
32+
- uses: actions/checkout@v4
33+
- uses: actions/setup-node@v4
34+
with:
35+
node-version: "20"
36+
cache: npm
37+
cache-dependency-path: apps/web/package-lock.json
38+
- run: npm ci
39+
- run: npm run lint
40+
- run: npx tsc --noEmit

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 DocPilot
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# DocPilot
2+
3+
**AI-powered contract review and extraction platform.**
4+
5+
![Screenshot](docs/screenshot.png)
6+
7+
[![Next.js](https://img.shields.io/badge/Next.js-15-black?logo=next.js)](https://nextjs.org/)
8+
[![FastAPI](https://img.shields.io/badge/FastAPI-0.115-009688?logo=fastapi)](https://fastapi.tiangolo.com/)
9+
[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-16-4169E1?logo=postgresql&logoColor=white)](https://www.postgresql.org/)
10+
[![Redis](https://img.shields.io/badge/Redis-7-DC382D?logo=redis&logoColor=white)](https://redis.io/)
11+
[![Celery](https://img.shields.io/badge/Celery-5.4-37814A?logo=celery)](https://docs.celeryq.dev/)
12+
[![OpenAI](https://img.shields.io/badge/OpenAI-GPT--4o-412991?logo=openai)](https://openai.com/)
13+
[![Docker](https://img.shields.io/badge/Docker-Compose-2496ED?logo=docker&logoColor=white)](https://docs.docker.com/compose/)
14+
[![TypeScript](https://img.shields.io/badge/TypeScript-5-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
15+
[![CI](https://github.com/your-username/docpilot/actions/workflows/ci.yml/badge.svg)](https://github.com/your-username/docpilot/actions)
16+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
17+
18+
## What It Does
19+
20+
Upload PDF contracts (NDAs, service agreements, employment contracts) and DocPilot automatically classifies the document type, extracts key fields like parties, dates, and payment terms using GPT-4o, and flags risky clauses with plain-English explanations. Compare two contracts side-by-side to spot differences at a glance.
21+
22+
## Key Features
23+
24+
- **AI-Powered Extraction** — Classifies document type and extracts structured fields using GPT-4o with JSON mode and Pydantic validation
25+
- **Risk Analysis** — Identifies risky clauses (non-compete, liability, termination) with risk levels and plain-English explanations
26+
- **Contract Comparison** — Side-by-side field-level diff between any two contracts with match/difference/missing indicators
27+
- **Real-Time Progress** — Server-Sent Events stream processing updates to the browser as each pipeline step completes
28+
- **Team Workspaces** — Multi-tenant architecture with role-based access (owner, admin, member) and team invitations
29+
- **Async Pipeline** — Celery workers process documents in the background so the API stays responsive
30+
31+
## Architecture
32+
33+
```mermaid
34+
graph LR
35+
Browser -->|REST API| Next["Next.js Frontend"]
36+
Next -->|HTTP| API["FastAPI"]
37+
API -->|async queries| DB[(PostgreSQL)]
38+
API -->|dispatch task| Worker["Celery Worker"]
39+
Worker -->|structured output| OpenAI["OpenAI GPT-4o"]
40+
Worker -->|read/write| DB
41+
Worker -->|publish progress| Redis[(Redis)]
42+
API -->|SSE stream| Redis
43+
```
44+
45+
## Tech Stack
46+
47+
| Layer | Technology |
48+
|-------|-----------|
49+
| **Frontend** | Next.js 15, TypeScript, Tailwind CSS, shadcn/ui |
50+
| **Backend** | Python 3.12, FastAPI, SQLAlchemy (async), Alembic |
51+
| **AI** | OpenAI GPT-4o, structured JSON output, Pydantic validation |
52+
| **Queue** | Celery, Redis |
53+
| **Database** | PostgreSQL 16 |
54+
| **DevOps** | Docker Compose, GitHub Actions CI |
55+
56+
## Getting Started
57+
58+
### Prerequisites
59+
60+
- [Docker](https://docs.docker.com/get-docker/) and Docker Compose
61+
- [Node.js 20+](https://nodejs.org/) (for frontend development)
62+
- An [OpenAI API key](https://platform.openai.com/api-keys)
63+
64+
### Setup
65+
66+
```bash
67+
# Clone the repo
68+
git clone https://github.com/your-username/docpilot.git
69+
cd docpilot
70+
71+
# Copy env file and add your OpenAI API key
72+
cp .env.example .env
73+
# Edit .env and set OPENAI_API_KEY=sk-your-key-here
74+
75+
# Start the backend services (API + worker + Postgres + Redis)
76+
docker compose up -d
77+
78+
# Run database migrations
79+
docker compose run --rm api alembic upgrade head
80+
81+
# Install frontend dependencies and start the dev server
82+
cd apps/web
83+
npm install
84+
npm run dev
85+
```
86+
87+
Open [http://localhost:3000](http://localhost:3000) and create an account to get started.
88+
89+
> **Note:** The API runs on port 8001 by default. Swagger docs are available at [http://localhost:8001/docs](http://localhost:8001/docs).
90+
91+
## Project Structure
92+
93+
```
94+
docpilot/
95+
├── apps/
96+
│ ├── api/ # FastAPI backend
97+
│ │ ├── app/
98+
│ │ │ ├── main.py # App entry point + CORS
99+
│ │ │ ├── config.py # Pydantic Settings (env vars)
100+
│ │ │ ├── database.py # Async SQLAlchemy engine
101+
│ │ │ ├── models/ # ORM models (User, Document, Extraction, ...)
102+
│ │ │ ├── schemas/ # Pydantic request/response schemas
103+
│ │ │ ├── routers/ # API endpoints (auth, documents, compare, teams)
104+
│ │ │ ├── services/ # Business logic (extraction pipeline, compare)
105+
│ │ │ ├── tasks/ # Celery background tasks
106+
│ │ │ ├── prompts/ # LLM prompt templates per doc type
107+
│ │ │ └── utils/ # PDF parser, text chunker, LLM client
108+
│ │ ├── alembic/ # Database migrations
109+
│ │ ├── Dockerfile
110+
│ │ └── requirements.txt
111+
│ │
112+
│ └── web/ # Next.js frontend
113+
│ ├── src/
114+
│ │ ├── app/ # App Router pages
115+
│ │ ├── components/ # UI components (shadcn + custom)
116+
│ │ ├── hooks/ # React hooks (SSE, documents, auth)
117+
│ │ ├── lib/ # API client, auth utils
118+
│ │ └── types/ # TypeScript interfaces
119+
│ ├── Dockerfile
120+
│ └── package.json
121+
122+
├── docker-compose.yml # Local dev (with hot reload)
123+
├── docker-compose.prod.yml # Production
124+
├── .github/workflows/ci.yml # CI pipeline
125+
└── .env.example # Environment variables template
126+
```
127+
128+
## API Documentation
129+
130+
With the backend running, interactive API docs are available at:
131+
132+
- **Swagger UI:** [http://localhost:8001/docs](http://localhost:8001/docs)
133+
- **ReDoc:** [http://localhost:8001/redoc](http://localhost:8001/redoc)
134+
135+
## Resume Bullets
136+
137+
> For anyone using this as a portfolio piece — here's how to talk about it:
138+
139+
- Built an AI-powered contract review platform that extracts key fields and flags risky clauses using GPT-4o with structured JSON output and Pydantic validation
140+
- Designed an async document processing pipeline using Celery and Redis with real-time progress streaming via Server-Sent Events
141+
- Implemented side-by-side contract comparison with field-level diffing across different contract types
142+
- Built a multi-tenant architecture with JWT authentication, role-based access control, and team workspaces
143+
144+
## License
145+
146+
[MIT](LICENSE)

apps/api/alembic/env.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@
88
# Ensure the project root (/app) is on sys.path so `app.*` imports work
99
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
1010

11-
from alembic import context
1211
from sqlalchemy.ext.asyncio import create_async_engine
1312

14-
from app.config import settings
15-
from app.database import Base
16-
1713
# Import all models so metadata is populated
1814
import app.models # noqa: F401
15+
from alembic import context
16+
from app.config import settings
17+
from app.database import Base
1918

2019
# Alembic Config object (provides access to alembic.ini values)
2120
config = context.config

0 commit comments

Comments
 (0)