5.6 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Free Alberta is a political campaign and advocacy platform built on the Changemaker Lite framework. It's a self-hosted, Docker-based system for political organizing and constituent engagement in Alberta, featuring campaign tools, interactive maps, and food resource directories.
Architecture
Service Structure
This is a Docker Compose monorepo with 28+ services. The four main applications are:
| Service | Port | Stack | Purpose |
|---|---|---|---|
| influence/ | 3333 | Express.js + NocoDB | Campaign & constituent engagement tool - representative lookup, email advocacy, response walls |
| map/ | 3000 | Express.js + Leaflet.js | Geographic organizing with walk sheets, QR codes, routing |
| freealberta-food/ | 3003 | Express.js + PostgreSQL | Food resource directory with scraping from InformAlberta, 211, and PDF sources |
| freealberta-lander/ | 3020 | Nginx static | Landing page |
Infrastructure Services
- NocoDB (8090): No-code database used by influence and map apps
- Redis (6379): Shared caching and sessions
- PostgreSQL: Separate instances for Listmonk and Food Resources
- Listmonk (9001): Email campaign management
- n8n (5678): Workflow automation
- Code Server (8888): Browser-based VS Code
- Gitea (3030): Self-hosted git
- MkDocs (4000 dev / 4001 built): Documentation
- MailHog (SMTP 1025, UI 8025): Development email testing
Monitoring Stack (profile: monitoring)
Prometheus (9090), Grafana (3001), cAdvisor, Node Exporter, Alertmanager, Gotify (8889)
Common Commands
Root Level (Docker Infrastructure)
# Start all core services
docker compose up -d
# Start with monitoring stack
docker compose --profile monitoring up -d
# Initial configuration wizard (creates .env)
./config.sh
# Fix container directory permissions (EACCES errors)
./fix-permissions.sh
# Production deployment with Cloudflare tunnel
./start-production.sh
# View logs for a specific service
docker compose logs -f <service-name>
Influence App (influence/app/)
npm start # Production
npm run dev # Development with nodemon
Map App (map/app/)
npm start # Production
npm run dev # Development with nodemon
Food Resources App (freealberta-food/app/)
npm start # Production
npm run dev # Development with nodemon
npm run db:init # Initialize database schema
npm run scrape # Run all scrapers
npm run scrape:informalberta # Scrape InformAlberta only
npm run scrape:211 # Scrape 211 Alberta only
npm run scrape:pdf # Parse Edmonton's Food Bank PDF
MkDocs Documentation
# From mkdocs/ directory
mkdocs serve # Development server with live reload
mkdocs build # Build static site
Key Architectural Patterns
Data Flow
- Influence & Map apps use NocoDB as their backend database via REST API
- Food Resources app uses direct PostgreSQL connection
- Representative data in Influence comes from Represent OpenNorth Canada API with NocoDB caching fallback
Mapping Stack (100% FOSS)
All mapping uses open-source alternatives to Google Maps:
- Tiles: OpenStreetMap
- Frontend: Leaflet.js
- Geocoding: Nominatim + Photon (with fallback chain)
- Routing: OSRM (Open Source Routing Machine)
Common Backend Patterns
All Express apps use:
- Helmet.js for security headers
- express-rate-limit for API protection
- Winston for logging with daily rotation
- Compression middleware
- CORS enabled
Environment Configuration
- Root
.envfile contains all service credentials (generated byconfig.sh) - Each app has its own
.envfor app-specific settings - Email testing routes through MailHog in development (SMTP port 1025)
Service Interconnections
┌─────────────┐ ┌─────────────┐
│ Influence │────▶│ NocoDB │◀────│ Map │
│ :3333 │ │ :8090 │ │ :3000 │
└─────────────┘ └─────────────┘ └────────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Redis │ │ PostgreSQL │◀────│ Food │
│ :6379 │ │ (shared) │ │ :3003 │
└─────────────┘ └─────────────┘ └────────────┘
File Structure Conventions
Each Express app follows this structure:
app/
├── controllers/ # Route handlers
├── routes/ # API endpoint definitions
├── middleware/ # Auth, rate limiting, CSRF
├── services/ # External API integrations
├── public/ # Frontend assets (HTML, CSS, JS)
├── utils/ # Logger, helpers
├── server.js # Entry point
└── package.json
External API Dependencies
- Represent OpenNorth (represent.opennorth.ca): Canadian elected representative data
- Nominatim/Photon: OpenStreetMap geocoding
- OSRM: Open source routing
Cloudflare Tunnel
Production uses Cloudflare tunnel for HTTPS. Configuration at configs/cloudflare/tunnel-config.yml.