# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Watchdog Docker - OPNsense monitoring system with web dashboard and email notifications. Monitors DHCP leases, new devices (ARP), interface status changes, and gateway status changes. **Current Version:** See [VERSION](VERSION) file **Changelog:** [CHANGELOG.md](CHANGELOG.md) ## Tech Stack - **Backend:** Python 3.11, Flask, Flask-Login - **Scheduling:** APScheduler (background polling) - **Database:** SQLite - **Frontend:** Bootstrap 5, Vanilla JavaScript - **API:** OPNsense REST API - **Email:** SMTP with TLS - **Deployment:** Docker + Docker Compose ## Commands ### Docker ```bash # Build and start docker-compose up -d --build # View logs docker-compose logs -f # Stop docker-compose down # Restart docker-compose restart ``` ### Local Development ```bash # Create virtual environment python3 -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate # Install dependencies pip install -r requirements.txt # Run app python app/main.py ``` ### Testing ```bash # Test OPNsense API connection python -c "from app.opnsense_api import OPNsenseAPI; import yaml; config = yaml.safe_load(open('config/config.yaml')); api = OPNsenseAPI(**config['opnsense']); print(api.test_connection())" # Generate password hash python -c "from werkzeug.security import generate_password_hash; print(generate_password_hash('your_password'))" ``` ## Architecture ### Application Flow 1. **main.py** - Flask app initialization, routes, APScheduler setup 2. **monitor.py** - OPNsenseMonitor class runs periodic checks (check_all) 3. **opnsense_api.py** - OPNsenseAPI client handles all API communication 4. **database.py** - Database class manages SQLite operations 5. **email_handler.py** - EmailHandler sends SMTP notifications ### Monitoring Cycle - APScheduler triggers `monitor.check_all()` every N seconds (configurable) - Each check method compares current state vs previous state - On changes: log to database + send email (if enabled) - State stored in memory (resets on restart) ### Database Schema - **events** - All monitored events (id, timestamp, type, interface, details, data JSON) - **known_devices** - MAC addresses of known devices (auto-populated on first detection) ### Web Interface - Login required (Flask-Login) - Dashboard shows stats + filterable event table - AJAX auto-refresh every 10s via /api/events endpoint ## Key Files - **VERSION** - Current version number (single source of truth) - **CHANGELOG.md** - Complete version history and changes - **config/config.yaml** - ALL settings (OPNsense, monitoring, web, email, database) - **app/main.py** - Flask app entry point (loads VERSION file) - **app/monitor.py** - Core monitoring logic with state tracking - **app/database.py** - SQLite operations - **app/email_handler.py** - Email notifications with HTML templates - **app/opnsense_api.py** - OPNsense API wrapper - **app/templates/** - Jinja2 templates (login.html, dashboard.html) ## Configuration All settings in `config/config.yaml`: - OPNsense host, API credentials, SSL verification - Monitoring interval, monitored interfaces, event toggles - Web port, secret key, admin password hash - SMTP settings, recipients - Database path, retention days - **Logging:** level (DEBUG/INFO/WARNING/ERROR), file paths, rotation settings ## Important Notes - **State Tracking:** Monitor uses previous_* dicts to detect changes (DHCP leases, devices, interfaces, gateways) - **Interface Filtering:** If `monitored_interfaces` is empty, monitor ALL interfaces - **Known Devices:** New devices are auto-added to known_devices table on first detection - **Email Logic:** Only send emails for unknown devices (new_device event with known=False) - **Retention:** Old events auto-cleanup based on retention_days (default 90) - **Password:** Admin password must be werkzeug scrypt hash in config.yaml - **Logging:** Uses RotatingFileHandler with separate main log and error log, auto-rotation at 10MB ## Versioning ### Version Schema - **Big changes** (new features, breaking changes): +0.1 (e.g., 0.1.0 → 0.2.0) - **Small changes** (bugfixes, minor improvements): +0.0.1 (e.g., 0.1.0 → 0.1.1) - **Major release** (1.x): Only on instruction ### Git Workflow - **main** - Stable releases only - **develop** - Active development (current working branch) - Feature branches for larger features ### Making Changes 1. Work in `develop` branch 2. Update VERSION file with new version number 3. Update CHANGELOG.md with changes (follow Keep a Changelog format) 4. Commit changes with descriptive message 5. Push to develop 6. Merge to main when stable and tested ## Code Style - German language in UI/emails (Deutsch) - Docstrings in English - Logging: logger.info for important events, logger.debug for routine operations - Error handling: try/except with logger.error(..., exc_info=True) - Type hints where applicable (Dict, List, Optional) ## Common Tasks ### Add new event type 1. Add check method to `monitor.py` (check_xyz) 2. Add toggle to config.yaml under events 3. Call from check_all() if enabled 4. Update email_handler colors/formatting if needed ### Modify OPNsense API calls - All API methods in `opnsense_api.py` - Use requests with basic auth (key:secret) - SSL warnings suppressed if verify_ssl=false ### Change database schema - Update initialize() in database.py - Add migration logic if needed (or recreate DB)