freealberta/free-alberta-prompt.md

175 lines
5.0 KiB
Markdown

# 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
```bash
cd freealberta-food
docker compose up -d
```
### 2. Initialize the Database
```bash
docker exec -it freealberta-food-app npm run db:init
```
### 3. Run Initial Data Scrape
```bash
docker exec -it freealberta-food-app npm run scrape
```
### 4. Configure Cloudflare Tunnel
Add to your Cloudflare tunnel configuration:
```yaml
- 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.