ice/README.md
Claude Code 56c846a44b Update documentation for TypeScript frontend build system
- README.md: Add comprehensive build system section explaining TypeScript backend/frontend compilation, esbuild usage, and development commands
- CLAUDE.md: Update architecture documentation to reflect TypeScript frontend with shared components and esbuild compilation
- scripts/deploy.sh: Update deployment instructions to use new unified build command

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-07 20:36:58 -04:00

317 lines
10 KiB
Markdown

# Great Lakes Ice Report
A community-driven web application for tracking winter road conditions and icy hazards in the Great Lakes region. Reports automatically expire after 48 hours to maintain current information.
## Features
- 🗺️ **Interactive Map** - Real-time location tracking centered on Grand Rapids
-**Fast Geocoding** - Lightning-fast address lookup with Mapbox API
- 📱 **Progressive Web App** - Install on mobile home screen, works offline
- 🚫 **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
- 🌐 **Internationalization** - Full i18n support with English and Spanish (Mexico) languages
## Quick Start
### 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
1. **Clone the repository:**
```bash
git clone https://git.deco.sh/deco/ice.git
cd ice
```
2. **Install dependencies:**
```bash
npm install
```
*Note: CSS is automatically built via the `postinstall` script*
3. **Configure environment variables:**
```bash
cp .env.example .env
# Edit .env with your Mapbox token
```
4. **Start the server:**
```bash
npm start # Production mode (builds everything)
npm run dev:ts # TypeScript development mode
npm run dev-with-css:ts # TypeScript + CSS watching (recommended)
npm run dev:full # Full development (TypeScript + frontend + CSS)
```
## Development Commands
### Code Quality
```bash
# Run ESLint to check code style and quality
npm run lint
# Auto-fix ESLint issues where possible
npm run lint:fix
```
### Testing
```bash
# Run all tests (128+ tests with TypeScript)
npm test
# Run tests with coverage report (76% overall coverage)
npm run test:coverage
```
5. **Visit the application:**
```
http://localhost:3000
```
### Build System
This project uses TypeScript for both backend and frontend code, with SCSS for styling.
**Backend (TypeScript → Node.js):**
```bash
npm run build:ts # Compile TypeScript backend
npm run dev:ts # TypeScript development with auto-reload
```
**Frontend (TypeScript → Browser JavaScript):**
```bash
npm run build:frontend # Compile frontend TypeScript with esbuild
npm run watch:frontend # Watch frontend TypeScript for changes
```
**CSS (SCSS → CSS):**
```bash
npm run build-css # Build CSS once (production)
npm run build-css:dev # Build CSS with source maps
npm run watch-css # Watch SCSS files for changes
```
**Development Commands:**
```bash
npm run dev:full # Watch all: TypeScript backend + frontend + CSS
npm run dev-with-css:ts # Watch TypeScript backend + CSS
npm run build # Build everything for production
```
**File Organization:**
- `src/` - TypeScript backend code
- `src/frontend/` - TypeScript frontend code (compiled to `public/dist/`)
- `src/scss/` - SCSS stylesheets (compiled to `public/style.css`)
- `dist/` - Compiled backend JavaScript
- `public/dist/` - Compiled frontend JavaScript
**Note:** Generated files (`dist/`, `public/dist/`, `public/style.css`) should not be committed to git.
## Environment Variables
```bash
# Required for geocoding and static map generation
MAPBOX_ACCESS_TOKEN=pk.your_mapbox_token_here
# Admin panel access
ADMIN_PASSWORD=your_secure_password
# Server configuration
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
### Deployment Scripts
The `scripts/` directory contains all deployment-related files:
- `deploy.sh` - Automated deployment script for Debian 12 (ARM64/x86_64)
- `icewatch.service` - Systemd service file for the application
- `Caddyfile` - Caddy reverse proxy configuration
- `generate-icons.js` - Script to generate PWA icons
### Quick Deployment (Recommended)
See `docs/deployment-quickstart.md` for a simplified deployment guide.
### Automated Deployment (Debian 12 ARM64/x86_64)
1. **Run the deployment script on your server:**
**Option A: Use the local deployment script (Recommended)**
```bash
# Clone the repository first
git clone https://git.deco.sh/deco/ice.git
cd ice
# Run the local deployment script
sudo bash scripts/deploy.sh
```
**Option B: Download from S3**
```bash
# Default: Downloads config from S3
curl -sSL https://ice-puremichigan-lol.s3.amazonaws.com/scripts/deploy.sh | bash
# Alternative: Use local files only (no S3)
curl -sSL https://ice-puremichigan-lol.s3.amazonaws.com/scripts/deploy.sh | S3_BUCKET_NAME=none bash
```
The deployment script (`scripts/deploy.sh`) automates the entire setup process including:
- Installing required dependencies (Node.js, Git, Caddy)
- Creating system user and directories
- Setting up systemd services
- Configuring Caddy reverse proxy
2. **Deploy your application:**
```bash
sudo git clone https://git.deco.sh/deco/ice.git /opt/icewatch
cd /opt/icewatch
sudo chown -R $USER:$USER /opt/icewatch
npm install # This automatically builds CSS via postinstall
npm run build # Build everything: TypeScript backend + frontend + CSS
```
3. **Configure environment:**
```bash
cp .env.example .env
nano .env # Add your API keys
```
4. **Create databases and set permissions:**
```bash
touch icewatch.db profanity.db
sudo chown -R icewatch:icewatch /opt/icewatch
```
5. **Start services:**
```bash
sudo systemctl enable icewatch
sudo systemctl start icewatch
sudo systemctl enable caddy
sudo systemctl start caddy
```
### Manual Deployment
See `docs/deployment.md` for detailed manual deployment instructions.
## API Endpoints
### Public Endpoints
- `GET /api/locations` - Get active location reports
- `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
- `PUT /api/admin/locations/:id` - Update location report
- `PATCH /api/admin/locations/:id/persistent` - Toggle persistent status
- `DELETE /api/admin/locations/:id` - Delete location report
- `GET /api/admin/profanity-words` - Manage profanity filter
- `POST /api/admin/profanity-words` - Add custom profanity word
- `PUT /api/admin/profanity-words/:id` - Update profanity word
- `DELETE /api/admin/profanity-words/:id` - Delete profanity word
### API Documentation
Interactive API documentation available at `/api-docs` when running the server.
## PWA Installation
### Mobile Devices
1. Open the app in your mobile browser
2. Look for the "Add to Home Screen" prompt
3. Tap "Add" to install the app on your home screen
4. The app will work offline and behave like a native app
### Desktop Browsers
1. Visit the app in Chrome, Edge, or Safari
2. Look for the install icon in the address bar
3. Click "Install" to add the app to your desktop
4. Launch from your applications folder or start menu
### PWA Features
- **Offline Access:** View cached reports when disconnected
- **App-like Experience:** Standalone window, no browser UI
- **Home Screen Icon:** Quick access like native apps
- **Automatic Updates:** Always stay current when online
## Technology Stack
- **Backend:** Node.js, Express.js, SQLite, TypeScript
- **Frontend:** Progressive Web App with Progressive Enhancement
- **PWA:** Installable, offline-capable, service worker caching
- **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
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Test thoroughly
5. Submit a pull request
## Security
- **Authentication:** Admin routes protected with bearer token authentication
- **Rate Limiting:** Public endpoints limited to prevent abuse (10 requests/15min per IP)
- **Input Validation:** Strict length limits and type checking on all user inputs
- **Data Protection:** API keys stored in environment variables only
- **Database Security:** Parameterized queries prevent SQL injection
- **Content Filtering:** Built-in profanity filter with custom word management
- **HTTPS:** Enforced in production via Caddy reverse proxy
- **Audit Logging:** Suspicious activity and abuse attempts are logged
### Input Limits
- **Address:** Maximum 500 characters
- **Description:** Maximum 1000 characters
- **Latitude:** Must be between -90 and 90 degrees
- **Longitude:** Must be between -180 and 180 degrees
- **Submissions:** 10 per 15 minutes per IP address
## License
MIT License - see LICENSE file for details
## Support
This is a community safety tool. For issues or questions:
- Create an issue on our git repository
- Check existing documentation
- Review security guidelines
---
**⚠️ Safety Notice:** This tool is for community awareness. Always prioritize personal safety and know your rights.