{"id":43614626,"url":"https://github.com/pyrex41/weather-event","last_synced_at":"2026-02-04T12:23:47.687Z","repository":{"id":323072892,"uuid":"1092020538","full_name":"pyrex41/weather-event","owner":"pyrex41","description":null,"archived":false,"fork":false,"pushed_at":"2025-11-07T23:58:45.000Z","size":77,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-11-08T00:16:52.521Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pyrex41.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-07T21:40:44.000Z","updated_at":"2025-11-07T23:58:48.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pyrex41/weather-event","commit_stats":null,"previous_names":["pyrex41/weather-event"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/pyrex41/weather-event","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyrex41%2Fweather-event","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyrex41%2Fweather-event/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyrex41%2Fweather-event/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyrex41%2Fweather-event/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pyrex41","download_url":"https://codeload.github.com/pyrex41/weather-event/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyrex41%2Fweather-event/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29084188,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-04T03:31:03.593Z","status":"ssl_error","status_checked_at":"2026-02-04T03:29:50.742Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-04T12:23:47.618Z","updated_at":"2026-02-04T12:23:47.680Z","avatar_url":"https://github.com/pyrex41.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Weather Event Flight Scheduling System\n\nA flight scheduling application that automatically monitors weather conditions and cancels/reschedules flight lessons when weather becomes unsafe. Built with Rust (Axum), Elm, and SQLite.\n\n## Features\n\n- ✈️ **Automated Weather Monitoring**: Hourly checks of upcoming flights against weather conditions\n- 🌦️ **Training Level-Specific Safety**: Different weather minimums for student pilots, private pilots, and instrument-rated pilots\n- 🤖 **AI-Powered Rescheduling**: Uses OpenAI to suggest optimal alternative times\n- 📱 **Real-time Notifications**: WebSocket push notifications, email, and SMS alerts\n- 📊 **Full-Stack Dashboard**: Elm frontend with live updates\n\n## Architecture\n\n```\n┌─────────────┐\n│  Elm SPA    │ ← WebSocket + HTTP API\n└─────────────┘\n       ↓\n┌─────────────┐\n│ Axum Server │ → SQLite Database\n└─────────────┘\n       ↓\n┌─────────────────────────────────┐\n│  External APIs:                 │\n│  - OpenWeatherMap (weather)     │\n│  - OpenAI (AI rescheduling)     │\n│  - Resend (email)               │\n│  - Twilio (SMS, optional)       │\n└─────────────────────────────────┘\n```\n\n## Tech Stack\n\n- **Backend**: Rust 1.75+ with Axum web framework\n- **Frontend**: Elm 0.19 with Vite build tooling\n- **Database**: SQLite with sqlx for type-safe queries\n- **Scheduler**: tokio-cron-scheduler for background jobs\n- **Real-time**: WebSocket via Axum + tokio broadcast channels\n\n## Prerequisites\n\n- Rust 1.75 or higher\n- Node.js 20+ and npm\n- Elm 0.19\n- SQLite\n- API keys for:\n  - OpenWeatherMap (required)\n  - OpenAI (required)\n  - Resend (required for email)\n  - Twilio (optional for SMS)\n\n## Local Development\n\n### 1. Clone and Setup\n\n```bash\n# Clone repository\ngit clone \u003crepo-url\u003e\ncd weather-event\n\n# Copy environment template\ncp .env.template .env\n\n# Edit .env and add your API keys\nnano .env\n```\n\n### 2. Database Setup\n\n```bash\n# Database will be created automatically on first run\n# Migrations will be applied automatically\n```\n\n### 3. Run Backend\n\n```bash\n# Build and run the server\ncargo run --release\n\n# Server will start on http://localhost:3000\n```\n\n### 4. Run Frontend (Development)\n\n```bash\ncd elm\nnpm install\nnpm run dev\n\n# Frontend dev server will start on http://localhost:5173\n```\n\n### 5. Build Frontend for Production\n\n```bash\ncd elm\nnpm run build\n\n# Output will be in elm/dist/\n# Copy to server's dist/ directory:\nmkdir -p ../server/dist\ncp -r dist/* ../server/dist/\n```\n\n## Environment Variables\n\nCreate a `.env` file in the project root:\n\n```env\n# Database\nDATABASE_URL=sqlite:weather_app.db\n\n# OpenWeatherMap API\nWEATHER_API_KEY=your_key_here\nWEATHER_API_BASE_URL=https://api.openweathermap.org/data/2.5\n\n# OpenAI API\nOPENAI_API_KEY=sk-proj-...\n\n# Resend Email API\nRESEND_API_KEY=re_...\nFROM_EMAIL=alerts@flightschedulepro.com\n\n# Twilio SMS (optional)\nTWILIO_ACCOUNT_SID=AC...\nTWILIO_AUTH_TOKEN=...\nTWILIO_FROM_NUMBER=+1234567890\n\n# Logging\nRUST_LOG=info,server=debug\n```\n\n## API Documentation\n\n### REST Endpoints\n\n#### Health Check\n```bash\nGET /health\n# Response: {\"status\": \"ok\"}\n```\n\n#### Bookings\n\n```bash\n# List all bookings\nGET /api/bookings\n\n# Get specific booking\nGET /api/bookings/:id\n\n# Create booking\nPOST /api/bookings\nContent-Type: application/json\n\n{\n  \"student_id\": \"uuid\",\n  \"scheduled_date\": \"2024-01-15T14:00:00Z\",\n  \"departure_location\": {\n    \"lat\": 33.8113,\n    \"lon\": -118.1515,\n    \"name\": \"KTOA\"\n  }\n}\n```\n\n#### Students\n\n```bash\n# List all students\nGET /api/students\n\n# Create student\nPOST /api/students\nContent-Type: application/json\n\n{\n  \"name\": \"John Doe\",\n  \"email\": \"john@example.com\",\n  \"phone\": \"+1234567890\",\n  \"training_level\": \"STUDENT_PILOT\"\n}\n```\n\n### WebSocket\n\n```bash\n# Connect to WebSocket\nws://localhost:3000/ws\n\n# Notifications format:\n{\n  \"type\": \"WEATHER_CONFLICT\",\n  \"booking_id\": \"uuid\",\n  \"message\": \"Flight cancelled: High winds\",\n  \"student_name\": \"John Doe\",\n  \"original_date\": \"2024-01-15T14:00:00Z\"\n}\n```\n\n## Testing\n\n### Unit Tests\n\nRun unit tests for the core library:\n\n```bash\n# Run all tests\ncargo test\n\n# Run with output\ncargo test -- --nocapture\n\n# Run specific module tests\ncargo test weather::tests::test_unit_conversions\ncargo test weather::safety::tests\ncargo test ai::tests\n```\n\n### Integration Tests\n\nThe project includes comprehensive integration tests:\n\n```bash\n# Run all integration tests\ncargo test --test '*'\n\n# Run weather integration tests\ncargo test --test weather_integration_test\n\n# Run database integration tests\ncargo test --test database_integration_test\n\n# Run specific integration test\ncargo test --test weather_integration_test test_student_pilot_weather_safety_integration\n```\n\n**Integration Test Coverage:**\n- ✅ Weather safety logic for all training levels\n- ✅ Training level progression (Student → Private → Instrument)\n- ✅ Weather scoring consistency\n- ✅ Edge cases (at minimums, below minimums, unlimited ceiling)\n- ✅ Multiple violation handling\n- ✅ Database CRUD operations (students, bookings)\n- ✅ Foreign key constraints and cascade deletes\n- ✅ Concurrent write safety (10 concurrent operations)\n- ✅ JSON serialization for complex types\n- ✅ Status transitions for bookings\n\n### Frontend Testing\n\n```bash\ncd elm\n\n# Install dependencies (if not already done)\nnpm install\n\n# Run Elm in dev mode with hot reload\nnpm run dev\n\n# Build for production\nnpm run build\n\n# The built files will be in elm/dist/\n```\n\n### E2E Testing\n\nThe project includes comprehensive E2E tests using Playwright to ensure the full application works end-to-end:\n\n```bash\n# Install E2E test dependencies\ncd e2e\nnpm install\n\n# Install Playwright browsers\nnpx playwright install\n\n# Run E2E tests locally\n./run-tests.sh\n\n# Or run directly\nnpm run test\n\n# Run tests in headed mode (visible browser)\nnpm run test:headed\n\n# Run tests with UI mode (interactive)\nnpm run test:ui\n\n# Debug tests\nnpm run test:debug\n\n# View test reports\nnpm run report\n```\n\n**E2E Test Coverage:**\n- ✅ Booking creation flow (happy path + validation + loading states)\n- ✅ Real-time weather alerts via WebSocket\n- ✅ WebSocket connection status and reconnection\n- ✅ AI-powered reschedule flow with availability badges\n- ✅ Student management with dashboard stats\n- ✅ Error scenarios (API failures, timeouts, validation)\n- ✅ Multi-browser support (Chromium, Firefox, WebKit)\n\n**Test Execution Time:** \u003c 30 seconds with aggressive mocking\n\n**CI Integration:** Tests run automatically on GitHub Actions for all PRs and pushes to main/develop branches.\n\n### Manual Testing\n\n1. Start the backend server:\n   ```bash\n   cargo run --release\n   ```\n\n2. In another terminal, start the Elm dev server:\n   ```bash\n   cd elm \u0026\u0026 npm run dev\n   ```\n\n3. Open http://localhost:5173 in your browser\n\n4. Test the WebSocket connection:\n   - Check the status indicator in the header (should show \"● Live\")\n   - Create a booking and watch for real-time updates\n   - Open browser console to see WebSocket messages\n\n5. Test API endpoints:\n   ```bash\n   # Health check\n   curl http://localhost:3000/health\n\n   # List bookings\n   curl http://localhost:3000/api/bookings\n\n   # List students\n   curl http://localhost:3000/api/students\n   ```\n\n## Project Structure\n\n```\nweather-event/\n├── core/                    # Core business logic library\n│   ├── src/\n│   │   ├── models.rs       # Database models and enums\n│   │   ├── weather/\n│   │   │   ├── api.rs      # OpenWeatherMap client\n│   │   │   └── safety.rs   # Weather safety logic\n│   │   ├── ai/\n│   │   │   └── reschedule.rs  # AI rescheduling\n│   │   └── notifications/\n│   │       ├── email.rs    # Resend email\n│   │       └── sms.rs      # Twilio/Mock SMS\n│   └── Cargo.toml\n├── server/                  # Axum web server\n│   ├── src/\n│   │   ├── main.rs         # Server entry point\n│   │   ├── routes/         # API route handlers\n│   │   └── scheduler.rs    # Background weather monitor\n│   └── Cargo.toml\n├── elm/                     # Elm frontend SPA\n│   ├── src/\n│   │   ├── Main.elm        # Main application entry\n│   │   ├── Types.elm       # Type definitions\n│   │   ├── Api.elm         # HTTP API client\n│   │   ├── WebSocket.elm   # WebSocket ports\n│   │   ├── main.js         # JS entry with WebSocket\n│   │   └── style.css       # Styles\n│   ├── elm.json\n│   ├── package.json\n│   ├── vite.config.js\n│   └── index.html\n├── tests/                   # Integration tests\n│   ├── weather_integration_test.rs\n│   ├── database_integration_test.rs\n│   └── Cargo.toml\n├── migrations/              # SQL database migrations\n│   └── 001_init.sql\n├── .env.template            # Environment variables template\n└── Cargo.toml              # Workspace configuration\n```\n\n## How It Works\n\n### Weather Monitoring Flow\n\n1. **Scheduler** runs every hour\n2. Queries all bookings in next 48 hours with status `SCHEDULED`\n3. For each booking:\n   - Fetches student's training level\n   - Gets current weather for departure location\n   - Checks if weather meets safety minimums\n   - If unsafe:\n     - Updates booking status to `CANCELLED`\n     - Creates reschedule event record\n     - Sends WebSocket notification to dashboard\n     - Sends email with AI-generated reschedule options\n     - Sends SMS alert\n\n### Training Level Weather Minimums\n\n| Level | Min Visibility | Max Wind | Min Ceiling | IMC Allowed |\n|-------|---------------|----------|-------------|-------------|\n| Student Pilot | 5 SM | 12 kt | 3000 ft | No |\n| Private Pilot | 3 SM | 20 kt | 1000 ft | No |\n| Instrument Rated | 1 SM | 30 kt | None | Yes |\n\nAll levels prohibit: Thunderstorms, Icing conditions\n\n## Development Roadmap\n\n- [x] Core backend with Axum\n- [x] Database schema and migrations\n- [x] Weather API integration\n- [x] Safety checking logic\n- [x] WebSocket notifications\n- [x] Scheduler for automated checks\n- [x] Elm frontend UI with real-time updates\n- [x] AI reschedule integration with caching\n- [x] Email/SMS notification infrastructure\n- [x] Unit and integration tests (15+ test cases)\n- [x] E2E tests with Playwright (25+ scenarios, \u003c30s execution)\n- [ ] Frontend npm package installation fixes\n- [ ] Deployment configuration (Fly.io)\n- [ ] Demo video\n\n## Deployment\n\nSee deployment instructions in `docs/DEPLOY.md` (coming soon)\n\n## License\n\nMIT\n\n## Support\n\nFor issues and questions, please open a GitHub issue.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpyrex41%2Fweather-event","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpyrex41%2Fweather-event","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpyrex41%2Fweather-event/lists"}