A pipeline management tool for site acquisition professionals working in telecom, fiber, and renewable energy. SiteTracker helps users identify candidate sites, track landowner outreach, and manage lease negotiations from initial identification through executed agreement.
Live Demo: sitetrackermws.netlify.app
Pipeline Management — Kanban board with drag-and-drop, tracking sites through seven stages: Identified → Landowner Research → Initial Contact → Site Visit → LOI Sent → Lease Negotiation → Executed.
Interactive Map — Leaflet-powered map view with markers color-coded by pipeline stage. Click any marker to view site details.
Geocoding — Enter a street address and convert it to coordinates with one click using the Geoapify API. Markers appear on the map automatically.
Site Scoring — Configurable weighted scoring model at the project level. Define your own criteria (proximity to infrastructure, zoning, environmental constraints, etc.), set importance weights, and rate each site on a 1–5 scale. The app calculates a weighted viability score.
Vertical-Specific Templates — Pre-populated scoring criteria when creating telecom, fiber, or renewable energy projects, reflecting the factors that actually drive site viability in each vertical.
Lease Comparison — Side-by-side comparison of deal terms across candidate sites: rent, escalation, term length, renewal options, co-location rights, and exclusivity.
Landowner Management — Contact records linked to one or more sites, with full communication history through the activity log.
Activity Tracking — Log outreach activities (calls, emails, meetings, site visits, letters) with follow-up dates that surface on the dashboard.
Dashboard — Pipeline summary, upcoming follow-ups, and recent activity feed across all projects.
| Layer | Technology |
|---|---|
| Frontend | React, Vite, TypeScript, Tailwind CSS |
| Maps | Leaflet, react-leaflet, OpenStreetMap tiles |
| Drag & Drop | dnd-kit |
| Backend | Python, FastAPI, SQLAlchemy, Alembic |
| Database | PostgreSQL |
| Auth | JWT (access + refresh tokens), bcrypt |
| Geocoding | Geoapify API |
| Deployment | Netlify (frontend), Render (backend + database) |
This is a monorepo with the frontend and backend as separate applications.
sitetracker/
├── frontend/ # React + Vite app
│ └── src/
│ ├── components/ # Reusable UI components
│ ├── pages/ # Route-level page components
│ ├── hooks/ # Custom React hooks
│ ├── context/ # Auth context
│ └── api/ # API client with auth header injection
├── backend/ # FastAPI app
│ ├── app/
│ │ ├── models/ # SQLAlchemy models (10 tables)
│ │ ├── schemas/ # Pydantic request/response validation
│ │ ├── routes/ # API endpoint routers
│ │ ├── services/ # Business logic
│ │ └── auth/ # JWT utilities, password hashing
│ └── alembic/ # Database migrations
└── docker-compose.yml # Local Postgres for development
The database has 10 tables: users, projects, sites, landowners, site_landowners, activities, lease_terms, vertical_fields, scoring_criteria, and site_scores. Projects are scoped to a user and contain sites. Everything else — landowners, activities, lease terms, scores — hangs off of sites. The architecture supports a future upgrade to multi-user collaboration via a project_members junction table.
- Python 3.12+
- Node.js 18+
- Docker (for local PostgreSQL)
docker compose up -dThis starts a PostgreSQL container on port 5432 with a persistent volume.
cd backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtCreate a .env file in the backend directory:
DATABASE_URL=postgresql://sitetracker:devpassword@localhost:5432/sitetracker
SECRET_KEY=any-random-string-for-dev
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=7
FRONTEND_URL=http://localhost:5173
Run migrations and start the server:
alembic upgrade head
uvicorn app.main:app --reloadThe API is available at http://localhost:8000 with interactive docs at http://localhost:8000/docs.
cd frontend
npm installCreate a .env file in the frontend directory:
VITE_API_URL=http://localhost:8000
VITE_GEOAPIFY_KEY=your-geoapify-api-key
Start the dev server:
npm run devThe app is available at http://localhost:5173.
FastAPI auto-generates interactive API documentation. With the backend running, visit /docs for the Swagger UI. Key endpoint groups:
/auth— Register, login, token refresh/projects— CRUD for projects/projects/{id}/sites— CRUD for sites within a project, search and filter/sites/{id}/stage— Pipeline stage updates (kanban drag)/landowners— Contact management with site linking/sites/{id}/activities— Outreach activity log/sites/{id}/lease-terms— Lease term entry/projects/{id}/lease-comparison— Side-by-side lease comparison/projects/{id}/scoring-criteria— Weighted scoring configuration/sites/{id}/scores— Site ratings per criterion/dashboard— Pipeline summary, follow-ups, recent activity
The app includes rate limiting on auth endpoints (via SlowAPI), bcrypt password hashing, JWT token expiration, CORS restricted to the frontend origin, input validation on all endpoints, and a sort-column whitelist to prevent injection.
This app was designed, built, and deployed using Claude Code as an AI coding agent. The spec document (SPEC.md) served as the application blueprint. I iteratively prompted Claude to generate code for each feature, iterateively integrating it into the larger codebase. The commit history reflects the incremental development process guided by the AI agent.