init commit

This commit is contained in:
2026-01-26 15:08:24 -06:00
commit 67225a725a
33 changed files with 3350 additions and 0 deletions

20
docs/CLAUDE.md Normal file
View File

@@ -0,0 +1,20 @@
# Documentation Folder
This folder contains business planning, architecture decisions, and documentation.
**No application code belongs here.**
## Contents
| Document | Purpose |
|----------|---------|
| `code_guidelinees.md` | Code creation guidelines and Git strategy |
| `security.md` | Python focused security code suggestions |
## Guidelines
- Keep documents focused and concise
- Update docs when architecture decisions change
- Use markdown tables for structured information
- Include links to external documentation where relevant

120
docs/code_guidelines.md Normal file
View File

@@ -0,0 +1,120 @@
### Coding Standards
**Style & Structure**
- Prefer longer, explicit code over compact one-liners
- Always include docstrings for functions/classes + inline comments
- Strongly prefer OOP-style code (classes over functional/nested functions)
- Strong typing throughout (dataclasses, TypedDict, Enums, type hints)
- Value future-proofing and expanded usage insights
**Data Design**
- Use dataclasses for internal data modeling
- Typed JSON structures
- Functions return fully typed objects (no loose dicts)
- Snapshot files in JSON or YAML
- Human-readable fields (e.g., `scan_duration`)
**Templates & UI**
- Don't mix large HTML/CSS blocks in Python code
- Prefer Jinja templates for HTML rendering
- Clean CSS, minimal inline clutter, readable template logic
**Writing & Documentation**
- Markdown documentation
- Clear section headers
- Roadmap/Phase/Feature-Session style documents
- Boilerplate templates first, then refinements
**Logging**
- Use structlog (pip package)
- Setup logging at app start: `logger = logging.get_logger(__file__)`
**Preferred Pip Packages**
- API/Web Server: Flask
- HTTP: Requests
- Logging: Structlog
- Scheduling: APScheduler
### Error Handling
- Custom exception classes for domain-specific errors
- Consistent error response formats (JSON structure)
- Logging severity levels (ERROR vs WARNING)
### Configuration
- Each component has environment-specific configs in its own `/config/*.yaml`
- API: `/api/config/development.yaml`, `/api/config/production.yaml`
- Web: `/public_web/config/development.yaml`, `/public_web/config/production.yaml`
- `.env` for secrets (never committed)
- Maintain `.env.example` in each component for documentation
- Typed config loaders using dataclasses
- Validation on startup
### Containerization & Deployment
- Explicit Dockerfiles
- Production-friendly hardening (distroless/slim when meaningful)
- Clear build/push scripts that:
- Use git branch as tag
- Ask whether to tag `:latest`
- Ask whether to push
- Support private registries
### API Design
- RESTful conventions
- Versioning strategy (`/api/v1/...`)
- Standardized response format:
```json
{
"app": "<APP NAME>",
"version": "<APP VERSION>",
"status": <HTTP STATUS CODE>,
"timestamp": "<UTC ISO8601>",
"request_id": "<optional request id>",
"result": <data OR null>,
"error": {
"code": "<optional machine code>",
"message": "<human message>",
"details": {}
},
"meta": {}
}
```
### Dependency Management
- Use `requirements.txt` and virtual environments (`python3 -m venv venv`)
- Use path `venv` for all virtual environments
- Pin versions to version ranges
- Activate venv before running code (unless in Docker)
### Testing Standards
- Manual testing preferred for applications
- **API Backend:** Maintain `api/docs/API_TESTING.md` with endpoint examples, curl/httpie commands, expected responses
- **Unit tests:** Use pytest for API backend (`api/tests/`)
- **Web Frontend:** If using a web frontend, Manual testing checklist are created in `public_web/docs`
### Git Standards
**Branch Strategy:**
- `master` - Production-ready code only
- `dev` - Main development branch, integration point
- `beta` - (Optional) Public pre-release testing
**Workflow:**
- Feature work branches off `dev` (e.g., `feature/add-scheduler`)
- Merge features back to `dev` for testing
- Promote `dev``beta` for public testing (when applicable)
- Promote `beta` (or `dev`) → `master` for production
**Commit Messages:**
- Use conventional commit format: `feat:`, `fix:`, `docs:`, `refactor:`, etc.
- Keep commits atomic and focused
- Write clear, descriptive messages
**Tagging:**
- Tag releases on `master` with semantic versioning (e.g., `v1.2.3`)
- Optionally tag beta releases (e.g., `v1.2.3-beta.1`)
---
## Workflow Preference
I follow a pattern: **brainstorm → design → code → revise**

View 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

46
docs/security.md Normal file
View File

@@ -0,0 +1,46 @@
## Foundational Security Instructions
- Act as a security-aware software engineer generating secure Python code.
- Produce implementations that are **secure-by-design and secure-by-default**, not merely cosmetically "secured."
- Focus on **preventing vulnerabilities**, not renaming functions or adding superficial security wrappers.
- Explicitly identify **trust boundaries** (user input, external systems, internal components) and apply stricter controls at all boundary crossings.
- Treat **all external input as untrusted by default**, regardless of source, and validate or sanitize it before use.
- Explicitly consider **data sensitivity** (e.g., public, internal, confidential, regulated) and enforce controls appropriate to the highest sensitivity level involved.
- Clearly distinguish between **authentication**, **authorization**, and **session management**, and never conflate their responsibilities.
- Ensure implementations **fail securely**: errors, exceptions, and edge cases MUST NOT expose sensitive data or weaken security guarantees.
- Use inline comments (when generating code) to clearly highlight critical security controls, assumptions, and security-relevant design decisions.
- Adhere strictly to OWASP best practices, with particular consideration for the OWASP ASVS.
- **Avoid slopsquatting and dependency confusion**: never guess package names or APIs; only reference well-known, reputable, and maintained libraries. Explicitly note any uncommon or low-reputation dependencies.
- Do not hardcode secrets, credentials, tokens, or cryptographic material. Always require secure external configuration or secret management mechanisms.
---
## Common Weaknesses for Python
### CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
**Summary:** Failure to properly sanitize or encode user input can lead to injection of malicious scripts into web pages, enabling XSS attacks.
**Mitigation Rule:** All user input rendered in web pages MUST be sanitized and contextually encoded using a secure library such as `bleach` or `html.escape`.
### CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
**Summary:** Unsanitized user input in SQL queries can allow attackers to execute arbitrary SQL commands, compromising data integrity and confidentiality.
**Mitigation Rule:** SQL queries MUST use parameterized statements or prepared statements provided by libraries such as `sqlite3` or `SQLAlchemy`. Direct concatenation of user input into queries MUST NOT be used.
### CWE-327: Use of a Broken or Risky Cryptographic Algorithm
**Summary:** Using outdated or insecure cryptographic algorithms can compromise data confidentiality and integrity.
**Mitigation Rule:** Cryptographic operations MUST use secure algorithms provided by the `cryptography` library. Deprecated algorithms such as MD5 or SHA-1 MUST NOT be used.
### CWE-798: Use of Hard-coded Credentials
**Summary:** Hardcoding credentials in source code can lead to unauthorized access if the code is exposed or leaked.
**Mitigation Rule:** Secrets, credentials, and tokens MUST be stored securely using environment variables, secret management tools, or configuration files outside the source code repository.
### CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
**Summary:** Improper error handling or logging can expose sensitive data to unauthorized users.
**Mitigation Rule:** Error messages and logs MUST NOT include sensitive information such as stack traces, database connection strings, or user credentials. Use logging libraries such as `logging` with appropriate log levels and sanitization.
### CWE-502: Deserialization of Untrusted Data
**Summary:** Deserializing untrusted data can lead to arbitrary code execution or data tampering.
**Mitigation Rule:** Deserialization MUST only be performed on trusted data sources. Unsafe libraries such as `pickle` MUST NOT be used for deserialization of untrusted input.
### CWE-829: Inclusion of Functionality from Untrusted Control Sphere
**Summary:** Using dependencies or code from untrusted sources can introduce malicious functionality or vulnerabilities.
**Mitigation Rule:** Dependencies MUST be sourced from reputable package repositories such as PyPI. Verify the integrity and reputation of packages before use, and pin dependency versions to avoid supply chain attacks.