init commit
This commit is contained in:
164
docs/implementation_roadmap.md
Normal file
164
docs/implementation_roadmap.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# Weather Alerts - Implementation Roadmap
|
||||
|
||||
## Overview
|
||||
This document captures the implementation plan and decisions for the weather alerts application.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Directory Structure
|
||||
```
|
||||
weather_alerts/
|
||||
├── app/
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py # Entry point - orchestration
|
||||
│ ├── config/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── loader.py # Typed YAML config loader
|
||||
│ │ ├── settings.yaml # Main configuration
|
||||
│ │ └── settings.example.yaml # Example (no secrets)
|
||||
│ ├── models/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── weather.py # Weather data models
|
||||
│ │ ├── alerts.py # Alert rule/triggered alert models
|
||||
│ │ └── state.py # Deduplication state models
|
||||
│ ├── services/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── weather_service.py # VisualCrossing API client
|
||||
│ │ ├── notification_service.py # ntfy sender
|
||||
│ │ ├── rule_engine.py # Alert rule evaluation
|
||||
│ │ └── state_manager.py # Deduplication persistence
|
||||
│ └── utils/
|
||||
│ ├── __init__.py
|
||||
│ ├── http_client.py # Centralized HTTP wrapper
|
||||
│ └── logging_config.py # Structlog setup
|
||||
├── tests/
|
||||
├── data/ # State files (gitignored)
|
||||
├── .env.example
|
||||
├── .gitignore
|
||||
├── requirements.txt
|
||||
└── run.py # Simple runner
|
||||
```
|
||||
|
||||
## Key Design Decisions
|
||||
|
||||
### 1. One-Shot Execution
|
||||
The application is designed for cron-based scheduling rather than internal scheduling. Each run:
|
||||
1. Fetches current forecast
|
||||
2. Evaluates rules
|
||||
3. Sends new alerts
|
||||
4. Exits
|
||||
|
||||
### 2. Secrets Management
|
||||
- API keys and tokens stored in environment variables only
|
||||
- `.env` file for local development (gitignored)
|
||||
- No secrets in YAML configuration
|
||||
|
||||
### 3. Atomic State Persistence
|
||||
State file writes use write-to-temp-then-rename pattern for crash safety:
|
||||
```python
|
||||
fd, temp_path = tempfile.mkstemp(...)
|
||||
# Write to temp file
|
||||
os.replace(temp_path, actual_path) # Atomic rename
|
||||
```
|
||||
|
||||
### 4. Deduplication Strategy
|
||||
Alerts are deduplicated using the key format: `{alert_type}:{forecast_hour}`
|
||||
|
||||
This allows:
|
||||
- Re-alerting for different forecast hours
|
||||
- Preventing duplicate alerts for the same condition/hour
|
||||
- Configurable deduplication window (default 24 hours)
|
||||
|
||||
### 5. Typed Throughout
|
||||
- Dataclasses for all data models
|
||||
- Type hints on all functions
|
||||
- Configuration loaded into typed dataclasses
|
||||
|
||||
### 6. Centralized HTTP
|
||||
Single `HttpClient` wrapper provides:
|
||||
- Consistent timeouts
|
||||
- Automatic retries with exponential backoff
|
||||
- Structured logging
|
||||
- Shared across services
|
||||
|
||||
## Alert Rules
|
||||
|
||||
### Temperature
|
||||
- **Low temperature**: Alert when forecast drops below threshold (default: 32°F)
|
||||
- **High temperature**: Alert when forecast exceeds threshold (default: 100°F)
|
||||
|
||||
### Precipitation
|
||||
- Alert when precipitation probability exceeds threshold (default: 70%)
|
||||
|
||||
### Wind
|
||||
- **Sustained wind**: Alert when speed exceeds threshold (default: 25 mph)
|
||||
- **Wind gusts**: Alert when gusts exceed threshold (default: 40 mph)
|
||||
|
||||
### Severe Weather
|
||||
- Forwards any severe weather alerts from the VisualCrossing API
|
||||
|
||||
## Execution Flow
|
||||
|
||||
```
|
||||
1. Load configuration (YAML + environment)
|
||||
2. Configure logging (structlog)
|
||||
3. Initialize services
|
||||
4. Fetch weather forecast
|
||||
5. Evaluate alert rules
|
||||
6. Filter duplicate alerts
|
||||
7. Send new alerts via ntfy
|
||||
8. Record sent alerts
|
||||
9. Purge old records
|
||||
10. Save state
|
||||
11. Exit (0=success, 1=error)
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Package | Purpose |
|
||||
|---------|---------|
|
||||
| requests | HTTP client |
|
||||
| structlog | Structured logging |
|
||||
| python-dotenv | Environment variable loading |
|
||||
| PyYAML | Configuration parsing |
|
||||
| pytest | Testing |
|
||||
| responses | HTTP mocking for tests |
|
||||
|
||||
## Testing
|
||||
|
||||
Run tests with:
|
||||
```bash
|
||||
pytest tests/ -v
|
||||
```
|
||||
|
||||
Test coverage:
|
||||
- Rule engine: Temperature, precipitation, wind, severe weather rules
|
||||
- Weather service: API parsing, error handling
|
||||
- State manager: Persistence, deduplication, purging
|
||||
|
||||
## Usage
|
||||
|
||||
### Setup
|
||||
1. Copy `.env.example` to `.env` and fill in API keys
|
||||
2. Copy `app/config/settings.example.yaml` to `app/config/settings.yaml` (optional customization)
|
||||
3. Install dependencies: `pip install -r requirements.txt`
|
||||
|
||||
### Running
|
||||
```bash
|
||||
python run.py
|
||||
```
|
||||
|
||||
### Cron Integration
|
||||
Add to crontab for hourly checks:
|
||||
```cron
|
||||
0 * * * * cd /path/to/weather_alerts && /path/to/python run.py >> /var/log/weather-alerts.log 2>&1
|
||||
```
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Potential additions if needed:
|
||||
- Additional alert types (UV index, humidity, etc.)
|
||||
- Multiple location support
|
||||
- Alert cooldown periods
|
||||
- Notification channels beyond ntfy
|
||||
- Web dashboard for status
|
||||
Reference in New Issue
Block a user