From 5562a2386c8925a9d51462a1f15703ef2a7709c3 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Sun, 6 Jul 2025 00:14:14 -0400 Subject: [PATCH] Update documentation for Mapbox static maps and progressive enhancement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add MapImageService documentation to CLAUDE.md - Update environment variable requirements for unrestricted Mapbox tokens - Document new server-side routes (/table, /submit-report, /map-image.png) - Add progressive enhancement section explaining JavaScript vs non-JavaScript modes - Update technology stack to reflect accessibility-first approach - Document auto-fit static map generation with color-coded pins πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- CLAUDE.md | 50 +++++++++++++++++++++++++++++++++----------------- README.md | 26 ++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 19 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 5e95a60..ddfcb10 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -90,7 +90,8 @@ cp .env.example .env ``` Required environment variables: -- `MAPBOX_ACCESS_TOKEN`: MapBox API token for geocoding (get free token at https://account.mapbox.com/access-tokens/) +- `MAPBOX_ACCESS_TOKEN`: MapBox API token for geocoding and static map generation (get free token at https://account.mapbox.com/access-tokens/) + - **Important**: For server-side static map generation, use an unrestricted token (no URL restrictions) - `ADMIN_PASSWORD`: Password for admin panel access at /admin - `PORT`: Server port (default: 3000) @@ -116,6 +117,7 @@ Routes are organized as factory functions accepting dependencies with full TypeS - **src/models/ProfanityWord.ts**: Type-safe database operations for profanity words - **src/services/DatabaseService.ts**: Centralized database connection management - **src/services/ProfanityFilterService.ts**: Content moderation with type safety +- **src/services/MapImageService.ts**: Server-side static map generation using Mapbox Static Images API - **src/types/index.ts**: Shared TypeScript interfaces and type definitions ### Database Schema @@ -136,33 +138,45 @@ CREATE TABLE locations ( **Profanity Database (`profanity.db`)**: Managed by the `ProfanityFilter` class for content moderation. -### Frontend (Vanilla JavaScript) -Multiple map implementations for flexibility: +### Frontend (Progressive Enhancement) +The application uses progressive enhancement to work with and without JavaScript: +**JavaScript-Enhanced Experience:** - **public/app.js**: Main implementation using Leaflet.js - Auto-detects available geocoding services (MapBox preferred, Nominatim fallback) + - Interactive map with real-time updates + - Autocomplete and form validation - **public/app-mapbox.js**: MapBox GL JS implementation for enhanced features - - **public/app-google.js**: Google Maps implementation (alternative) - - **public/admin.js**: Admin panel functionality - - Location management (view, edit, delete) - - Persistent location toggle - - Profanity word management - - **public/utils.js**: Shared utilities across implementations +**Non-JavaScript Fallback:** +- **Server-side /table route**: Complete HTML table view of all locations +- **HTML form submission**: Works via POST to /submit-report endpoint +- **Static map generation**: Auto-fitted Mapbox static images showing all report locations +- **Progressive enhancement**: noscript tags and "Basic View" button for accessibility + ### API Endpoints **Public endpoints:** - `GET /api/config`: Returns MapBox token for frontend geocoding - `GET /api/locations`: Active locations (< 48 hours old or persistent) - `POST /api/locations`: Submit new location report (rate limited: 10/15min per IP) - - **Input Validation:** Address ≀500 chars, Description ≀1000 chars + - **Input Validation:** Address ≀500 chars, Description ≀1000 chars, coordinate validation - **Profanity Filtering:** Automatic content moderation with rejection - **Security:** Rate limiting prevents spam and DoS attacks +**Server-side routes (Progressive Enhancement):** +- `GET /`: Main application page with JavaScript-enhanced features +- `GET /table`: Non-JavaScript table view with static map and HTML forms +- `POST /submit-report`: Server-side form submission for non-JavaScript users +- `GET /map-image.png`: Dynamic static map generation using Mapbox Static Images API + - **Auto-fit positioning:** Centers on actual location coordinates + - **Numbered pins:** Color-coded markers (red=regular, orange=persistent) + - **Query parameters:** `?width=800&height=600&padding=50` for customization + **Admin endpoints (require Bearer token):** - `POST /api/admin/login`: Authenticate and receive token - `GET /api/admin/locations`: All locations including expired @@ -188,13 +202,15 @@ SCSS files are in `src/scss/`: ### Key Design Patterns 1. **TypeScript-First Architecture**: Full type safety with strict type checking -2. **Security-by-Design**: Rate limiting, input validation, and authentication built into core routes -3. **Modular Route Architecture**: Routes accept dependencies as parameters for testability -4. **Dual Database Design**: Separate databases for application data and content moderation -5. **Type-Safe Database Operations**: All database interactions use typed models -6. **Comprehensive Testing**: 125+ tests covering units, integration, and security scenarios -7. **Graceful Degradation**: Fallback geocoding providers and error handling -8. **Automated Maintenance**: Cron-based cleanup of expired reports +2. **Progressive Enhancement**: Works completely without JavaScript via server-side rendering +3. **Security-by-Design**: Rate limiting, input validation, and authentication built into core routes +4. **Modular Route Architecture**: Routes accept dependencies as parameters for testability +5. **Dual Database Design**: Separate databases for application data and content moderation +6. **Type-Safe Database Operations**: All database interactions use typed models +7. **Comprehensive Testing**: 125+ tests covering units, integration, and security scenarios +8. **Graceful Degradation**: Fallback geocoding providers and error handling +9. **Automated Maintenance**: Cron-based cleanup of expired reports +10. **Accessibility-First**: noscript fallbacks and server-side static map generation ### Deployment - Automated deployment script for Debian 12 ARM64 in `scripts/deploy.sh` diff --git a/README.md b/README.md index 0430af6..5dc9f06 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,12 @@ A community-driven web application for tracking winter road conditions and icy h - πŸ—ΊοΈ **Interactive Map** - Real-time location tracking centered on Grand Rapids - ⚑ **Fast Geocoding** - Lightning-fast address lookup with MapBox API +- 🚫 **JavaScript-Free Mode** - Complete functionality without JavaScript via server-side rendering +- πŸ–ΌοΈ **Static Maps** - Auto-generated Mapbox static images for non-JS users - πŸ”„ **Auto-Expiration** - Reports automatically removed after 48 hours - πŸ‘¨β€πŸ’Ό **Admin Panel** - Manage and moderate location reports - πŸ“± **Responsive Design** - Works on desktop and mobile devices +- β™Ώ **Accessibility First** - Progressive enhancement with noscript fallbacks - πŸ”’ **Privacy-Focused** - No user tracking, community safety oriented - πŸ›‘οΈ **Enhanced Security** - Coordinate validation, rate limiting, and content filtering @@ -17,6 +20,7 @@ A community-driven web application for tracking winter road conditions and icy h ### Prerequisites - Node.js 18+ - MapBox API token (free tier available) + - **Important**: For server-side static maps, use an unrestricted token (no URL restrictions) ### Local Development @@ -89,7 +93,7 @@ SCSS files are organized in `src/scss/`: ## Environment Variables ```bash -# Required for fast geocoding +# Required for geocoding and static map generation MAPBOX_ACCESS_TOKEN=pk.your_mapbox_token_here # Admin panel access @@ -99,6 +103,11 @@ ADMIN_PASSWORD=your_secure_password PORT=3000 ``` +**MapBox Token Requirements:** +- For interactive geocoding: Token can have URL restrictions +- For server-side static maps: Must use unrestricted token (no URL restrictions) +- Recommended: Use one unrestricted token for both features + ## Deployment ### Automated Deployment (Debian 12 ARM64) @@ -140,6 +149,15 @@ See `docs/deployment.md` for detailed manual deployment instructions. - `POST /api/locations` - Submit new location report (rate limited: 10/15min per IP) - `GET /api/config` - Get API configuration +### Progressive Enhancement Routes +- `GET /` - Main application page with JavaScript-enhanced features +- `GET /table` - Non-JavaScript table view with static map and HTML forms +- `POST /submit-report` - Server-side form submission for non-JavaScript users +- `GET /map-image.png` - Dynamic static map generation using Mapbox Static Images API + - Query parameters: `?width=800&height=600&padding=50` for customization + - Auto-fit positioning centers on actual location coordinates + - Color-coded pins: red for regular reports, orange for persistent + ### Admin Endpoints (Authentication Required) - `GET /admin` - Admin panel (password protected) - `GET /api/admin/locations` - Get all location reports @@ -157,12 +175,16 @@ Interactive API documentation available at `/api-docs` when running the server. ## Technology Stack - **Backend:** Node.js, Express.js, SQLite, TypeScript -- **Frontend:** Vanilla JavaScript, Leaflet.js +- **Frontend:** Progressive Enhancement (Vanilla JavaScript + Server-side rendering) + - **Enhanced:** Leaflet.js interactive maps with real-time updates + - **Fallback:** Server-side HTML tables with static Mapbox images - **Geocoding:** MapBox API (with Nominatim fallback) +- **Maps:** Leaflet.js (interactive) + Mapbox Static Images API (server-side) - **Security:** Rate limiting, input validation, authentication - **Testing:** Jest, TypeScript, 128+ tests with 76% coverage - **Reverse Proxy:** Caddy (automatic HTTPS) - **Database:** SQLite (lightweight, serverless) +- **Accessibility:** Full progressive enhancement with noscript support ## Contributing