No description
Find a file
Claude Code 6c2be648c0 Fix dependency review workflow for missing build tools
- Install devDependencies (including sass) with --include=dev flag
- Add proper error handling for missing main branch files
- Skip bundle size analysis if no frontend changes detected
- Improve git diff logic for changed files detection

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-07 20:17:34 -04:00
.forgejo/workflows Fix dependency review workflow for missing build tools 2025-07-07 20:17:34 -04:00
.github Add GitHub mirror README and remove workflows 2025-07-07 19:30:05 -04:00
docs Sync all deployment documentation and remove manual database creation 2025-07-06 18:37:48 -04:00
public Add TypeScript frontend build system with shared components 2025-07-07 19:46:19 -04:00
scripts Add TypeScript frontend build system with shared components 2025-07-07 19:46:19 -04:00
src Fix ESLint issues in TypeScript codebase 2025-07-07 20:05:27 -04:00
tests Clean up unused imports and variables to improve code quality 2025-07-05 22:41:14 -04:00
.env.example Update HTML files to use Bunny.net CDN for static assets 2025-07-03 20:44:16 -04:00
.gitignore Add TypeScript frontend build system with shared components 2025-07-07 19:46:19 -04:00
CLAUDE.md Update deployment script and documentation 2025-07-06 18:08:44 -04:00
eslint.config.mjs Fix ESLint issues in TypeScript codebase 2025-07-07 20:05:27 -04:00
jest.config.js Add comprehensive TypeScript test suite with Jest 2025-07-05 21:30:07 -04:00
original-style.css Remove unused Sass/SCSS setup 2025-07-03 21:56:26 -04:00
package-lock.json Add TypeScript frontend build system with shared components 2025-07-07 19:46:19 -04:00
package.json Add TypeScript frontend build system with shared components 2025-07-07 19:46:19 -04:00
README.md Fix i18n for form placeholders and make snowflake emoji clickable 2025-07-07 19:10:02 -04:00
s3-bucket-policy.json Update HTML files to use Bunny.net CDN for static assets 2025-07-03 20:44:16 -04:00
tsconfig.json Add comprehensive TypeScript support and conversion 2025-07-05 21:15:29 -04:00

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:

    git clone https://git.deco.sh/deco/ice.git
    cd ice
    
  2. Install dependencies:

    npm install
    

    Note: CSS is automatically built via the postinstall script

  3. Configure environment variables:

    cp .env.example .env
    # Edit .env with your Mapbox token
    
  4. Start the server:

    npm start              # Production mode
    npm run dev            # Development mode
    npm run dev-with-css   # Development with CSS watching
    

Development Commands

Code Quality

# Run ESLint to check code style and quality
npm run lint

# Auto-fix ESLint issues where possible
npm run lint:fix

Testing

# Run all tests (128+ tests with TypeScript)
npm test

# Run tests with coverage report (76% overall coverage)
npm run test:coverage
  1. Visit the application:
    http://localhost:3000
    

CSS Development

This project uses SCSS for styling. The CSS is generated and should not be committed to git.

  • Build CSS once: npm run build-css
  • Build CSS (dev mode): npm run build-css:dev
  • Watch CSS changes: npm run watch-css
  • Dev with CSS watching: npm run dev-with-css

SCSS files are organized in src/scss/:

  • main.scss - Main entry point
  • _variables.scss - Theme variables and colors
  • _mixins.scss - Reusable SCSS mixins
  • pages/ - Page-specific styles
  • components/ - Component-specific styles

Environment Variables

# 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

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)

    # 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

    # 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:

    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:ts  # Compile TypeScript to JavaScript
    
  3. Configure environment:

    cp .env.example .env
    nano .env  # Add your API keys
    
  4. Create databases and set permissions:

    touch icewatch.db profanity.db
    sudo chown -R icewatch:icewatch /opt/icewatch
    
  5. Start services:

    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.