Monorepo for an agronomic field dashboard: a FastAPI backend that aggregates NASA POWER weather, SoilGrids soil properties, and a mocked SMAP soil moisture signal, plus a Nuxt 4 desktop-style UI with a map, metrics, agronomic alerts, and 7-day charts.
| Path | Description |
|---|---|
backend/ |
FastAPI app (app/), Python dependencies in backend/requirements.txt |
frontend/ |
Nuxt 4 app using the app/ directory structure, Nuxt UI, Leaflet, vue-chartjs |
- Backend (local): Python 3.11 or newer (3.12 recommended)
- Frontend: Node.js and pnpm
- Optional: Docker and Docker Compose, for running the API in a container
Copy .env.example to frontend/.env and adjust if needed:
NUXT_PUBLIC_API_BASE— Base URL of the FastAPI service (defaulthttp://127.0.0.1:8000). The browser calls this URL; keep it aligned with wherever the API is listening.
Copy backend/.env.example to backend/.env when running uvicorn from backend/ (optional; defaults match local dev).
| Variable | Purpose |
|---|---|
ENVIRONMENT |
development (default) or production. In production, interactive API docs (/docs) and the OpenAPI JSON are disabled. |
CORS_ORIGINS |
Comma-separated browser origins allowed to call the API (no spaces). Set this to your deployed frontend origin in production. |
TRUSTED_HOSTS |
Optional comma-separated Host values when the API is behind a reverse proxy. Leave empty to disable host checking. |
RATE_LIMIT_ANALYZE |
Limit for POST /analyze (slowapi format, default 60/minute). |
Never commit real secrets. .env files are listed in .gitignore.
From the repository root:
cd backend
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8000- Health check:
GET http://127.0.0.1:8000/health - Analysis:
POST http://127.0.0.1:8000/analyzewith JSON body{ "lat": <number>, "lng": <number> }
The API applies baseline security headers, configurable CORS, optional trusted hosts, and rate limiting on /analyze. See backend/app/main.py and backend/app/core/config.py.
Build and run the API in a consistent environment (see backend/Dockerfile; the image runs as a non-root user):
docker build -t opendss-backend ./backend
docker run --rm -p 8000:8000 \
-e ENVIRONMENT=production \
-e CORS_ORIGINS=https://your-frontend.example \
opendss-backendOr from the repo root with Compose (see docker-compose.yml for optional environment overrides):
docker compose up --buildUse the same NUXT_PUBLIC_API_BASE=http://127.0.0.1:8000 when the frontend runs on your machine and the API is published on port 8000.
cd frontend
pnpm install
pnpm devThe dev server defaults to port 3000. Open the app in the browser; the field dashboard lives at /field-dashboard (the home route redirects there).
Units: On the field dashboard, use Measurements (Metric vs Standard US) for wind and precipitation, and Temperature (Celsius vs Fahrenheit) for soil temperature. Choices are stored in the browser (localStorage); the API still returns metric data and the UI converts for display.
Production build:
pnpm build
pnpm preview # optional local preview of the production buildThe POST /analyze response includes location, weather (including wind, humidity, short-range precipitation context), mocked soil moisture with a 7-day series, soil temperature series, SoilGrids-derived properties when the upstream service is available, and agronomic fields (plant readiness and spray window classification).
External data services may be unavailable or rate-limited; the backend is written to degrade gracefully (for example, fallback weather data or null soil properties).
- CORS: Restrict
CORS_ORIGINSto known frontend origins. Do not use*with credentials. - Docs: With
ENVIRONMENT=production,/docs,/redoc, and/openapi.jsonare disabled to reduce attack surface. - Secrets: Do not commit
.envfiles; use your host or orchestrator’s secret store in production. - Third-party APIs: The backend calls external HTTP APIs only (NASA POWER, SoilGrids). It does not proxy arbitrary URLs from clients.
- Reporting issues: See SECURITY.md.
See CONTRIBUTING.md.
- Confirm the backend is running (
curl http://127.0.0.1:8000/healthshould return{"status":"ok"}). - Set
NUXT_PUBLIC_API_BASEinfrontend/.envto the exact origin the browser must use (including scheme and port), e.g.http://127.0.0.1:8000. Restartpnpm devafter changing env vars. - If the UI is opened as
http://localhost:3000butNUXT_PUBLIC_API_BASEuses127.0.0.1, that is usually still fine for same-machine dev; if you see CORS errors, align origins or add your dev origin toCORS_ORIGINSinbackend/.env.example(copied tobackend/.env).
- Ensure your frontend origin is included in
CORS_ORIGINS(comma-separated, no spaces). Restart the API after changes.
- The API rate-limits
POST /analyze(default60/minuteper client IP). IncreaseRATE_LIMIT_ANALYZEinbackend/.envfor local testing if needed, or wait before retrying.
- The ISRIC SoilGrids API can return errors or maintenance responses (for example HTTP 503). The backend catches failures and leaves soil property fields null. Retry later or verify the service status; coordinates far offshore may also return sparse data.
- NASA POWER may be slow or temporarily unavailable; the backend falls back to synthetic weather so the API still responds. Check backend logs for HTTP errors from the POWER endpoints.
- Another process may be using port 8000. Stop the conflicting service, or map a different host port:
docker run --rm -p 9000:8000 opendss-backendand setNUXT_PUBLIC_API_BASE=http://127.0.0.1:9000. - For Compose, adjust the
portsmapping indocker-compose.ymlsimilarly.
- Start Docker Desktop (or your container runtime) and retry
docker build/docker compose up.
This project is licensed under the MIT License.