A weather application for iOS and Android that queries multiple independent forecast providers and tells the user how much they agree β a per-variable consensus with an honest confidence readout. Free as shipped: no ads, no subscription, no account required. See ROADMAP.md for what still blocks a store release.
- β Current conditions, hourly and daily forecasts
- β Multi-source consensus: median, minβmax range and a high/medium/low confidence rating computed from cross-provider disagreement; hidden when fewer than two sources respond
- β Precipitation radar with real timestamped frames (RainViewer)
- β Air Quality Index with pollutant breakdown (PM2.5, PM10, NOβ, Oβ, β¦) and UV
- β Pollen counts β Europe only (CAMS domain); an explicit no-data state elsewhere
- β Home-screen widgets and a Wear OS app (tile + complications) that mirror the phone's last real synced reading β no-data state before first sync
- β Optional notifications: daily summary, rain alerts
- β Multi-location support with Nominatim search
- β Location auto-detect, light/dark mode
- β Optional account (syncs saved locations); deletable in-app
- π€ AI insights (outfit/activity/health text via OpenAI):
ENABLE_AI_INSIGHTS=falseand no API key in the shipped backend config. The code exists; the store listing must not claim it while it is off. - π€ Monetization (subscriptions, paywall):
MONETIZATION_ENABLED=falseis compiled into both Android build types. Flip conditions are listed in ROADMAP.md β the Open-Meteo licensing constraint in docs/WEATHER_APIS.md is the hard one.
clima-ai/
βββ backend/ # Backend services
β βββ api/ # FastAPI main service
β β βββ app/
β β β βββ models/ # SQLAlchemy models
β β β βββ routers/ # API endpoints
β β β βββ services/ # Business logic
β β β βββ schemas/ # Pydantic schemas
β β βββ Dockerfile
β β βββ requirements.txt
β βββ payment-service/ # Node.js payment webhooks
β β βββ src/
β β β βββ routes/ # Apple & Google webhooks
β β β βββ index.js
β β βββ Dockerfile
β β βββ package.json
β βββ docker-compose.yml # Full stack orchestration
β βββ init.sql # Database schema (v1)
β βββ 002_add_features.sql # Schema v2: locations, device tokens, alerts
βββ android/ # Android Jetpack Compose app + Wear OS module
βββ ios/ # iOS SwiftUI app + Watch app + widgets
βββ web-demo/ # Static browser demo
βββ docs/ # Documentation
-
Backend:
- Docker & Docker Compose
- Python 3.11+
- Node.js 18+
- PostgreSQL 15+
- Redis 7+
-
Mobile:
- iOS: Xcode 15+, Swift 5.9+
- Android: Android Studio, Kotlin 1.9+
-
API Keys:
- Apple Developer Account (for iOS)
- Google Play Developer Account (for Android)
- Optional: OpenAI API key β only if enabling the flag-gated AI insights
- Optional: extra weather-source keys (each source is skipped when blank)
- Clone the repository:
git clone <repository-url>
cd clima-ai/backend- Configure environment:
cd api
cp .env.example .env
# Edit .env with your OpenAI API key and other settings- Start all services:
cd ..
docker-compose up -d- Verify services:
# API health check
curl http://localhost:8000/health
# Payment service health check
curl http://localhost:3000/health- Access API documentation:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
Runs the API against a native Postgres. Redis is optional β the services catch connection errors and skip caching, so the API works with no Redis running.
- Create the role and database (Postgres 15+ already running locally):
psql -d postgres -c "CREATE ROLE climaai WITH LOGIN PASSWORD 'climaai123';" -c "CREATE DATABASE climaai OWNER climaai;"- Apply the schema, in order. Both files are idempotent, so re-running them against an existing database is safe:
cd backend && PGPASSWORD=climaai123 psql -h localhost -U climaai -d climaai -v ON_ERROR_STOP=1 -f init.sql -f 002_add_features.sql- Create the virtualenv and install dependencies:
cd backend/api && python3.11 -m venv .venv && .venv/bin/pip install -r requirements.txt- Configure and run:
cp .env.example .envSet DATABASE_URL=postgresql+asyncpg://climaai:climaai123@localhost:5432/climaai
(the default in .env.example points at the postgres Docker host), then:
cd backend/api && .venv/bin/python -m uvicorn app.main:app --reload --port 8000- Verify:
curl http://localhost:8000/health- Navigate to iOS project:
cd ios- Open in Xcode:
open ClimaAI.xcodeproj- Configure:
- Set your signing team and change the
com.climaai.*bundle identifier prefix in ios/project.yml, thenxcodegen generate - Configure StoreKit products in App Store Connect
- Update product IDs in
SubscriptionManager.swift - Add required capabilities: Location, In-App Purchase
- Run on simulator or device
- Navigate to Android project:
cd android- Open in Android Studio:
studio .- Configure:
- Update
applicationIdinbuild.gradle - Configure Google Play Billing products
- Update product IDs in billing configuration
- Add required permissions in
AndroidManifest.xml
- Run on emulator or device
# Database
DATABASE_URL=postgresql+asyncpg://climaai:password@postgres:5432/climaai
# Redis
REDIS_URL=redis://redis:6379/0
# OpenAI
OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4-turbo-preview
# JWT
JWT_SECRET=your-super-secret-key-min-32-chars
# App IDs
APPLE_BUNDLE_ID=com.climaai.app
GOOGLE_PACKAGE_NAME=com.climaai.app
# Optional extra weather sources β each is skipped when its key is blank
OPENWEATHERMAP_API_KEY=
WEATHERBIT_API_KEY=
STORMGLASS_API_KEY=
OPENUV_API_KEY=
# Mounts /demo endpoints backed by generated mock data. Leave false in production.
DEMO_MODE=falseSee backend/api/.env.example for the full annotated list.
Update the following in Xcode:
- Bundle Identifier:
com.yourcompany.climaai - Team: Your Apple Developer Team
- Product IDs:
- Monthly:
com.yourcompany.climaai.monthly - Annual:
com.yourcompany.climaai.annual
- Monthly:
Update in build.gradle:
applicationId "com.yourcompany.climaai"Update product IDs in billing configuration to match Google Play Console.
GET /api/weather/current- Current weatherGET /api/weather/hourly- Hourly forecastGET /api/weather/daily- Daily forecastGET /api/weather/air-quality- Air quality dataGET /api/weather/multi-source- Multi-source forecast with the consensus block
GET /api/insights- Complete AI insightsGET /api/summary- Daily summary
POST /api/auth/register- Register new userPOST /api/auth/login- LoginGET /api/auth/me- Get current userPUT /api/auth/me- Update userDELETE /api/auth/me- Delete account and, by cascade, all attached data (see docs/delete-account.html)
GET /api/subscriptions/status- Check subscriptionPOST /api/subscriptions/activate- Activate subscriptionGET /api/subscriptions/plans- Get available plans
The authoritative list is the OpenAPI schema at /docs on a running API.
- Native SwiftUI interface
- StoreKit 2 integration
- CoreLocation for geolocation
- Offline caching
- Background weather updates
- Push notifications support
- Dark mode support
- Accessibility (VoiceOver, Dynamic Type)
- Material 3 design
- Google Play Billing Library 5
- FusedLocationProvider
- Room database for caching
- WorkManager for background updates
- Firebase Cloud Messaging
- Dark theme support
- TalkBack accessibility
β οΈ The backend has a 116-test suite; Android has no test sources, and the iOS suite cannot run until an Xcode project exists. See ROADMAP.md.
The suite runs against a real Postgres rather than SQLite, because several
handlers use Postgres-only SQL (jsonb casts, = ANY(:array)) that SQLite cannot
execute β a SQLite run would pass while testing something other than production.
The test database is created and migrated automatically; it is separate from your development database and its tables are truncated between tests.
cd backend/api && .venv/bin/python -m pytest tests/ -vPoint it elsewhere with TEST_DATABASE_URL (default
postgresql://climaai:climaai123@localhost:5432/climaai_test). The role needs
CREATEDB:
psql -d postgres -c "ALTER ROLE climaai CREATEDB;"Tests needing no database (weather parsing, for instance) run without Postgres.
Database-backed tests skip locally when it is unreachable, but fail rather than
skip when CI is set.
ios/ClimaAI.xcodeproj is committed; see ios/XCODE_SETUP.md.
The suite has never been executed β expect to fix compile errors on the first run.
cd ios && xcodebuild test -scheme ClimaAI -destination 'platform=iOS Simulator,name=iPhone 15'./scripts/run-android.shBoots an Android emulator with a window, builds and installs the debug app, grants its permissions and launches it. Re-running reuses a running emulator.
Start the backend first or the app runs with no weather:
cd backend/api && .venv/bin/python -m uvicorn app.main:app --port 8000The debug build targets http://10.0.2.2:8000, which is how the emulator reaches
a server on the host.
Built apps are collected into dist/, split by platform and variant:
cd android && ./gradlew assembleDebug bundleRelease
./scripts/collect-artifacts.sh androidLayout and rationale: dist/README.md. CI publishes the same structure as workflow artifacts.
cd android && ./gradlew testDocker Compose (Production):
docker-compose -f docker-compose.prod.yml up -dIndividual Services:
# API
cd backend/api
docker build -t climaai-api .
docker run -p 8000:8000 --env-file .env climaai-api
# Payment Service
cd backend/payment-service
docker build -t climaai-payment .
docker run -p 3000:3000 --env-file .env climaai-paymentCloud Deployment:
- AWS: ECS/Fargate, RDS PostgreSQL, ElastiCache Redis
- Google Cloud: Cloud Run, Cloud SQL, Memorystore
- Azure: Container Apps, Azure Database, Azure Cache
-
Archive the app:
- Product β Archive in Xcode
-
Upload to App Store Connect:
- Distribute App β App Store Connect
-
Configure in App Store Connect:
- App metadata
- Screenshots
- Privacy information
- In-App Purchase products
-
Submit for review
- Generate signed APK/AAB:
cd android
./gradlew bundleRelease-
Upload to Google Play Console:
- Production track or Internal testing
-
Configure:
- Store listing
- Content rating
- Pricing & distribution
- In-app products
-
Submit for review
users
βββ id (UUID, PK)
βββ email (VARCHAR, UNIQUE)
βββ password_hash (VARCHAR)
βββ full_name (VARCHAR)
βββ preferences (JSONB)
βββ timestamps
subscriptions
βββ id (UUID, PK)
βββ user_id (UUID, FK)
βββ platform (VARCHAR)
βββ plan (VARCHAR)
βββ status (VARCHAR)
βββ trial_dates
βββ subscription_dates
βββ platform_specific_ids- JWT-based authentication
- Bcrypt password hashing
- HTTPS only in production
- Receipt validation (Apple & Google)
- Rate limiting
- SQL injection prevention (SQLAlchemy)
- XSS protection
- CORS configuration
- Request latency
- Error rates
- Cache hit rates
- API usage by endpoint
- User acquisition
- Subscription conversion
- Feature usage
- Crash reports
Recommended Tools:
- Backend: Prometheus + Grafana, Sentry
- Mobile: Firebase Analytics, Crashlytics
Compiled out. MONETIZATION_ENABLED=false in both Android build types: the
shipped app is free, with no ads, no paywall, and nothing purchasable. The
subscription stack (backend plans, payment-service webhooks, billing client)
exists but is inert. Do not flip the flag before the conditions in
ROADMAP.md are met β the Open-Meteo licensing constraint in
docs/WEATHER_APIS.md is the hard one.
Proprietary - All rights reserved
This is a production application. For contributions, please contact the development team.
- Email: singhaditya21@gmail.com
- Legal & policy pages (GitHub Pages, served from
docs/): privacy Β· terms Β· account deletion
v1.0.0 (unreleased β see ROADMAP.md for blockers)
- β Multi-source weather with consensus confidence readout
- β Radar, air quality, Europe-only pollen
- β Widgets, Apple Watch and Wear OS apps with synced real data
- β Offline caching and background updates
- π€ AI insights and subscriptions present in code, off by configuration
See ROADMAP.md for current status, release blockers, and the competitor-parity backlog.
Widgets, the Apple Watch app, the Wear OS app, the radar overlay, multi-location support, alert push notifications, and historical weather data are already implemented β earlier versions of this file listed them as planned.
- Weather Data: Open-Meteo (CC BY 4.0), MET Norway, US NWS and others β see docs/WEATHER_APIS.md for the full list and the attribution obligations
- Radar: RainViewer
- Geocoding: Nominatim / Β© OpenStreetMap contributors (ODbL)
- Icons: SF Symbols (iOS), Material Icons (Android)
- Backend: FastAPI, Express.js
- Mobile: SwiftUI, Jetpack Compose
Built with β€οΈ by the ClimaAI Team
