init commit
This commit is contained in:
20
docs/CLAUDE.md
Normal file
20
docs/CLAUDE.md
Normal 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
120
docs/code_guidelines.md
Normal 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**
|
||||
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
|
||||
46
docs/security.md
Normal file
46
docs/security.md
Normal 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.
|
||||
Reference in New Issue
Block a user