AI copilot for construction project managers.
Turn project chaos into clear action.
SitePilot reads RFIs, submittals, emails, and project logs to show construction teams what needs attention today.
Upload any construction project document (PDF, CSV, Excel, or TXT) and SitePilot will:
- Extract all text and data from the file
- Send it to Claude AI for analysis
- Return a structured dashboard showing:
- Urgent items — what needs action today
- Overdue items — what's already past due
- Waiting on someone — who's blocking progress
- Project risks — what could derail the project
- Weekly summary — executive overview for PMs
- Suggested follow-up messages — ready to send
| Layer | Technology |
|---|---|
| Frontend | Next.js 14 (App Router, TypeScript, Tailwind CSS) |
| Backend | FastAPI (Python 3.11) |
| Database | PostgreSQL 16 |
| AI | Anthropic Claude API |
| Infra | Docker + Docker Compose |
- Docker Desktop installed and running
- An Anthropic API key
git clone <this-repo>
cd sitepilot
cp .env.example .envEdit .env and set your API key:
ANTHROPIC_API_KEY=sk-ant-your-key-here
docker-compose up --buildThis starts:
- PostgreSQL on port 5432
- FastAPI backend on http://localhost:8000
- Next.js frontend on http://localhost:3000
Visit http://localhost:3000
Upload a file from the sample-data/ folder to try it out.
cd backend
# Create virtual environment
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Set environment variables
export ANTHROPIC_API_KEY=sk-ant-your-key-here
export DATABASE_URL=postgresql://sitepilot:sitepilot_password@localhost:5432/sitepilot
# Start PostgreSQL (Docker is the easiest way)
docker run -d --name sitepilot-db \
-e POSTGRES_DB=sitepilot \
-e POSTGRES_USER=sitepilot \
-e POSTGRES_PASSWORD=sitepilot_password \
-p 5432:5432 \
postgres:16-alpine
# Start the server
uvicorn main:app --reload --port 8000API docs available at http://localhost:8000/docs
cd frontend
# Install dependencies
npm install
# Create local env file
echo "BACKEND_URL=http://localhost:8000" > .env.local
# Start dev server
npm run devFrontend available at http://localhost:3000
The sample-data/ folder contains realistic construction project files for testing:
| File | Type | Contents |
|---|---|---|
sample_rfi_log.txt |
TXT | 6-entry RFI log with statuses, priorities, and due dates |
sample_submittal_log.csv |
CSV | 12-item submittal register with review statuses |
sample_project_notes.txt |
TXT | Full weekly meeting minutes with action items, change orders, and risk issues |
Upload all three to see the dashboard populate with real-looking construction data.
sitepilot/
├── backend/
│ ├── main.py # FastAPI entry point
│ ├── database.py # SQLAlchemy engine + session
│ ├── models.py # DB models (UploadedFile, Analysis)
│ ├── schemas.py # Pydantic response schemas
│ ├── routers/
│ │ ├── files.py # File upload, list, delete endpoints
│ │ └── analysis.py # Dashboard + analysis detail endpoints
│ ├── services/
│ │ ├── extractor.py # PDF/CSV/Excel/TXT text extraction
│ │ └── claude_service.py # Claude API integration + prompt
│ ├── requirements.txt
│ └── Dockerfile
├── frontend/
│ ├── app/
│ │ ├── page.tsx # Landing page
│ │ ├── upload/page.tsx # File upload page
│ │ ├── dashboard/page.tsx # Project dashboard
│ │ └── analysis/[id]/page.tsx # Analysis detail
│ ├── components/
│ │ └── Navbar.tsx
│ ├── lib/
│ │ └── api.ts # API client + TypeScript types
│ ├── next.config.js # Rewrites proxy to backend
│ └── Dockerfile
├── sample-data/ # Test files for trying the app
├── docker-compose.yml
├── .env.example
└── README.md
| Method | Path | Description |
|---|---|---|
POST |
/api/files/upload |
Upload and analyze a file |
GET |
/api/files/ |
List all uploaded files |
GET |
/api/files/{id} |
Get file metadata |
DELETE |
/api/files/{id} |
Delete a file |
GET |
/api/analysis/dashboard |
Aggregated dashboard data |
GET |
/api/analysis/file/{file_id} |
Analysis for a specific file |
GET |
/api/analysis/{id} |
Get analysis by analysis ID |
GET |
/api/health |
Health check |
| Variable | Default | Description |
|---|---|---|
ANTHROPIC_API_KEY |
— | Required. Your Anthropic API key |
CLAUDE_MODEL |
claude-sonnet-4-6 |
Claude model to use |
DATABASE_URL |
postgres://... | PostgreSQL connection string |
UPLOAD_DIR |
uploads |
Directory to store uploaded files |
MAX_FILE_SIZE_MB |
50 |
Maximum upload size in MB |
ALLOWED_ORIGINS |
http://localhost:3000 |
CORS allowed origins |
- PDF — extracted with pdfplumber (fallback: PyPDF2)
- CSV — parsed with pandas, formatted as readable table
- Excel (.xlsx / .xls) — all sheets extracted with pandas
- TXT — read directly as UTF-8
- No authentication — all data is shared in the same instance (V1 design)
- File processing is asynchronous — the UI polls for status updates
- Large files (>50 MB) are rejected; >60,000 characters are truncated before sending to Claude
- All analyses are stored in PostgreSQL and persist across restarts