No description
Find a file
Claude Code 45bb95fd43 Update repository URLs to new Gitea location
- Update all git clone commands to use git.deco.sh/deco/ice
- Update API documentation contact URL to Gitea repository
- Change from github.com/derekslenk/ice to git.deco.sh/deco/ice
- Rebuild TypeScript to update compiled swagger.js

All documentation and scripts now point to the correct Gitea repository.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-06 13:09:00 -04:00
.github/workflows Update deploy scripts to create a PR 2025-07-03 22:53:53 -04:00
docs Update repository URLs to new Gitea location 2025-07-06 13:09:00 -04:00
models Refactor architecture: Add models/services layer and refactor frontend 2025-07-05 19:21:51 -04:00
public Add Progressive Web App functionality 2025-07-06 00:46:00 -04:00
routes Refactor architecture: Add models/services layer and refactor frontend 2025-07-05 19:21:51 -04:00
scripts Fix deployment documentation and scripts for TypeScript setup 2025-07-06 12:56:48 -04:00
services Refactor architecture: Add models/services layer and refactor frontend 2025-07-05 19:21:51 -04:00
src Update repository URLs to new Gitea location 2025-07-06 13:09:00 -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 Complete comprehensive test suite implementation 2025-07-05 21:43:09 -04:00
CLAUDE.md Add Progressive Web App functionality 2025-07-06 00:46:00 -04:00
eslint.config.mjs Add coordinate validation and ESLint integration 2025-07-05 22:12:37 -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 Mapbox static map generation for non-JavaScript users 2025-07-06 00:09:23 -04:00
package.json Apply suggestions from code review 2025-07-06 00:13:37 -04:00
profanity-filter.js Update profanity-filter.js 2025-07-04 14:17:49 -04:00
README.md Update repository URLs to new Gitea location 2025-07-06 13:09:00 -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
server.js Refactor architecture: Add models/services layer and refactor frontend 2025-07-05 19:21:51 -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

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 git@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

See docs/deployment-quickstart.md for a simplified deployment guide.

Automated Deployment (Debian 12 ARM64)

  1. Run the deployment script on your server:

    curl -sSL https://ice-puremichigan-lol.s3.amazonaws.com/scripts/deploy.sh | bash
    
  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.