freealberta/free-alberta-prompt.md

5.0 KiB

Free Alberta Food Resources - Project Documentation

Original Requirements

Build a webapp for freealberta.org to display free food resources in Alberta. Pull data from various sources, store in PostgreSQL, and serve via Cloudflare tunnel at food.freealberta.org.

Data Sources

  • InformAlberta (5 zones - North, Edmonton, Calgary, Central, South)
  • Edmonton's Food Bank PDF (community meals)
  • 211 Alberta (Cloudflare protected - requires manual data or API access)

Implementation Status: COMPLETE

Technology Stack

  • Backend: Express.js (Node.js)
  • Frontend: HTML, CSS, vanilla JavaScript
  • Database: PostgreSQL 17 (dedicated container)
  • Maps: Leaflet.js with OpenStreetMap (100% FOSS)
  • Routing: OSRM (Open Source Routing Machine)
  • Geocoding: Nominatim + Photon (OpenStreetMap-based)
  • Containerization: Docker

Project Structure

freealberta-food/
├── app/
│   ├── public/
│   │   ├── css/styles.css
│   │   ├── js/app.js
│   │   └── index.html
│   ├── routes/api.js
│   ├── controllers/
│   │   ├── resourceController.js
│   │   ├── scraperController.js
│   │   ├── geocodingController.js
│   │   └── routingController.js
│   ├── models/
│   │   ├── db.js
│   │   └── init-db.js
│   ├── services/
│   │   ├── geocoding.js
│   │   └── routing.js
│   ├── scrapers/
│   │   ├── informalberta.js
│   │   ├── ab211.js
│   │   ├── pdf-parser.js
│   │   └── run-all.js
│   ├── utils/logger.js
│   ├── server.js
│   ├── package.json
│   └── Dockerfile
├── docker-compose.yml
├── .env
└── .env.example

Features Implemented

  • Full-featured frontend with map view and list view
  • Search functionality (by name, address, services)
  • Filters by city and resource type
  • Geolocation support (find nearby resources)
  • Turn-by-turn directions from user location to any resource
  • Multiple travel modes: Driving, Walking, Cycling
  • Printable directions with step-by-step instructions
  • Automatic geocoding of addresses during data scrape
  • Resource detail modal
  • Pagination
  • Mobile responsive design

Mapping Features (100% FOSS)

  • Base Map: OpenStreetMap tiles via Leaflet.js
  • Geocoding: Multi-provider with Nominatim and Photon fallback
  • Routing: OSRM (Open Source Routing Machine) for directions
  • Directions: Turn-by-turn navigation with distance/duration
  • Print: Printable directions with full step list

Resource Types

  • Food Bank
  • Community Meal
  • Food Hamper
  • Food Pantry
  • Soup Kitchen
  • Mobile Food
  • Grocery Program

API Endpoints

Resources

  • GET /api/resources - List resources with filters
  • GET /api/resources/search - Text search
  • GET /api/resources/nearby - Location-based search
  • GET /api/resources/:id - Single resource details
  • GET /api/cities - Available cities
  • GET /api/types - Resource types
  • GET /api/stats - Statistics

Geocoding

  • GET /api/geocode?address=... - Forward geocode address to coordinates
  • GET /api/geocode/reverse?lat=...&lng=... - Reverse geocode coordinates

Routing/Directions

  • GET /api/directions?startLat=...&startLng=...&endLat=...&endLng=...&profile=driving - Get turn-by-turn directions

Admin

  • POST /api/scrape - Trigger manual scrape
  • GET /api/scrape/status - Scrape status
  • GET /api/scrape/logs - Scrape history

Data Refresh

  • Weekly automated scrape (Sundays at 2 AM)
  • Manual trigger via /api/scrape
  • Automatic geocoding of new addresses during scrape

Deployment Instructions

1. Start the Application

cd freealberta-food
docker compose up -d

2. Initialize the Database

docker exec -it freealberta-food-app npm run db:init

3. Run Initial Data Scrape

docker exec -it freealberta-food-app npm run scrape

4. Configure Cloudflare Tunnel

Add to your Cloudflare tunnel configuration:

- hostname: food.freealberta.org
  service: http://freealberta-food-app:3003

Port Configuration

  • Application: 3003 (configured in main .env as FOOD_PORT)
  • Database: Internal only (within Docker network)

Known Limitations

  1. 211 Alberta: Cloudflare protection blocks automated scraping. Data must be entered manually or via API access request.
  2. PDF Parsing: The Edmonton Food Bank PDF structure may vary; manual review recommended.
  3. Geocoding Rate Limits: Nominatim has a 1 request/second limit. Scraping with geocoding takes longer.
  4. OSRM Public Server: Using the public demo server which has rate limits. For production, consider self-hosting OSRM.

Future Enhancements

  • Request API access from 211 Alberta
  • Self-host OSRM for faster routing
  • Add admin panel for manual data management
  • Connect to NocoDB for form-based data entry
  • Add analytics tracking
  • Cache route calculations

Environment Variables

See .env.example for all configuration options.