freealberta/CLAUDE.md

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 .env file contains all service credentials (generated by config.sh)
  • Each app has its own .env for 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.