RainUSE Nexus is an autonomous water-opportunity intelligence system for Grundfos: it discovers, evaluates, and acts on commercial building prospects (scheduled rescoring, threshold crossings, deep research, and rep routing) with explainable viability scores and a map-first command center. This is not a generic CRUD dashboard; the product centers on an automation engine, auditable scores, and modular city adapters.
Authoritative specs
- Product and UX depth: RainUSE_Nexus_Complete_Outline (1).md
- Build order and phase details: Claude Phases/ (start with
PHASE_00_PROJECT_FOUNDATION.md)
Hackathon / demo note: The demo is DFW-first with pre-seeded buildings and automation history (see Phase 00 seed strategy). Seed implementation lives in Phase 01 (backend/seed/seed_dfw.py).
-
Data plane (Docker)
Install Docker Desktop for Mac and start Docker Desktop once so the
dockerCLI is on yourPATH. Then from the repo root:docker compose up -d
If you see
command not found: docker, Docker is not installed or not running—open Docker Desktop from Applications, wait until it says “running,” then try again in a new terminal window.On first boot, Postgres runs scripts in
db/init/(schema + PostGIS). To verify PostGIS and tables after containers are healthy:docker compose exec db psql -U rainuse -d rainuse -c "SELECT PostGIS_Version();" docker compose exec db psql -U rainuse -d rainuse -c "\dt"
Without Docker: you need PostgreSQL 15 + PostGIS and Redis installed by some other means (for example Homebrew formulas and manual
psql -f db/init/001_schema.sql). The compose file is the supported path for this repo. -
Environment
cp .env.example .env
Fill in secrets (Auth0, Mapbox, AI keys) when you implement later phases.
-
Frontend (from repo root)
cd frontend && npm install && npm run dev
-
Backend (Phase 01 — FastAPI, PostGIS, seed)
On macOS, Homebrew’s Python is PEP 668 “externally managed”: use a venv in
backend/beforepip install.cd backend python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt
Ensure
.envat the repo root definesDATABASE_URL(see .env.example). The default uses thepostgresql+psycopg_async://driver (works on Python 3.13 with the pinnedpsycopg[binary]package).Alembic + Docker init: Tables are created by Docker’s
db/init/001_schema.sql. Align Alembic’s version table once (no DDL run):cd backend && source .venv/bin/activate && alembic stamp 5712fbf55610
Load demo data:
cd backend && source .venv/bin/activate && python -m seed.seed_dfw
The seed script truncates and re-inserts demo rows (5 anchor buildings + 50 DFW + 10 PA, alerts, adapters, automation, inbox).
Run the API:
uvicorn main:app --reload --host 0.0.0.0 --port 8000
Smoke checks:
curl -s "http://localhost:8000/health" | jq . # expect: "service": "rainuse-nexus", "api_version": "1.0.0" # If you only see {"status":"ok"} or api_version is missing, another process owns :8000 — see troubleshooting below. curl "http://localhost:8000/api/buildings?state=TX" | jq '.count' # expect 55 curl "http://localhost:8000/api/alerts?state=TX" | jq '.count' # expect 15+ curl "http://localhost:8000/api/states/TX/vs/PA" | jq '.TX.avg_viability_score' curl -s "http://localhost:8000/api/debrief?user_id=demo-local-user" | jq .
Troubleshooting:
404on/api/debrief,/api/settings/…, etc.That almost always means the browser is not talking to this repo’s FastAPI app (missing API keys would not produce route-level
404). Check:curl -s "http://localhost:8000/health" curl -s "http://localhost:8000/openapi.json" | jq '.info.version, (.paths | keys | length)'
You should see
rainuse-nexusin/healthand many paths (not1). If not, find what is bound to the port and stop it, then startuvicornagain frombackend/:lsof -nP -iTCP:8000 -sTCP:LISTEN
Portfolio example (ticker slug):
curl "http://localhost:8000/api/portfolio/amzn"Set
CORS_ORIGINSin.envif the frontend runs on a host other thanhttp://localhost:3000.
Create these roles in the Auth0 dashboard (see Phase 00 §9):
| Role key | Access level |
|---|---|
grundfos_rep |
Full access to their territory; inbox, memos, approve outreach. |
grundfos_manager |
Full access to all territories; all reps’ inboxes. |
partner_view |
Read-only, assigned state’s buildings only. |
demo_judge |
Read-only across features; sample data on auth-gated pages. |
Roles live in app_metadata.roles[] and should appear on the JWT as https://rainuse.io/roles via a custom Auth0 Action. user_metadata holds territory, cadence, score threshold, onboarding flags, voice model, rep ZIP.
frontend/— Next.js 14 App Router, design tokens, route stubsbackend/— FastAPI + async SQLAlchemy (Phase 01: models,/api/*routes,seed_dfw.py, Alembic baseline)db/init/— PostgreSQL + PostGIS DDL (matches Phase 00 schema)docker-compose.yml— Postgres 15 + PostGIS, Redis 7