5.0 KiB
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 filtersGET /api/resources/search- Text searchGET /api/resources/nearby- Location-based searchGET /api/resources/:id- Single resource detailsGET /api/cities- Available citiesGET /api/types- Resource typesGET /api/stats- Statistics
Geocoding
GET /api/geocode?address=...- Forward geocode address to coordinatesGET /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 scrapeGET /api/scrape/status- Scrape statusGET /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
- 211 Alberta: Cloudflare protection blocks automated scraping. Data must be entered manually or via API access request.
- PDF Parsing: The Edmonton Food Bank PDF structure may vary; manual review recommended.
- Geocoding Rate Limits: Nominatim has a 1 request/second limit. Scraping with geocoding takes longer.
- 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.