Noesis is a React/TypeScript PWA backed by Django REST Framework. It displays NASA EONET natural-event observations that match the Philippine Area of Responsibility (PAR), a case-insensitive Philippines title search, or the selected outside-PAR categories severeStorms, landslides, and floods.
This is an educational/local tool, not an official emergency-warning system.
- Python 3.10 or newer
- Node.js and npm
- Network access to NASA EONET and OpenStreetMap tiles
cd backend
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python manage.py runserverThe API is available at http://localhost:8000/api/events/.
Swagger documentation is available at http://localhost:8000/api/docs/, with the raw OpenAPI schema at http://localhost:8000/api/schema/.
The category catalog is available at http://localhost:8000/api/categories/.
cd frontend
npm install
npm run devOpen http://localhost:5173. Vite proxies /api requests to the local Django server.
Copy .env.example to .env when custom settings are needed. Important backend settings are DJANGO_SECRET_KEY, DJANGO_DEBUG, DJANGO_ALLOWED_HOSTS, FRONTEND_ORIGIN, NASA_REQUEST_TIMEOUT_SECONDS, and EVENT_CACHE_SECONDS. The frontend can use VITE_API_BASE_URL when the API is not available through the local Vite proxy.
- NASA EONET is queried by the backend, not directly by the browser.
- The PAR polygon is a fixed approximation and is not an official emergency-warning boundary.
- Every valid coordinate observation inside the polygon is displayed.
- Events with a case-insensitive
Philippinestitle match are also displayed, even when outside the PAR approximation. Each popup explains whether it matched by PAR, title, or both. severeStorms,landslides, andfloodsare also displayed outside PAR, withcategoryshown as the match reason.- The event cache is versioned after filtering-rule changes (
noesis:events:v2on the backend,noesis-events-v2in the browser,noesis-events-v2for the service worker). If an older service worker remains installed, reload the app once after stopping the old dev server or clear site data. - The first frontend load forces a cache-busting backend request with a
?refresh=1&t=<timestamp>query so an old service-worker response cannot hide newly included events. - The map resets to a PAR-centered view after each fresh response; if more than one observation is rendered, the viewport auto-fits to the observation extent so outside-PAR matches are immediately visible. Users can zoom or pan manually after that.
- The frontend caches the last successful response and labels cached data when offline.
- Browser notifications are permission-based and occur after a refresh; they are not guaranteed emergency alerts.
- Category checkboxes control which categories may trigger browser notifications. Leaving them empty allows all categories.
- The Event categories section lists the categories currently returned by NASA EONET through
/api/categories/. - OpenStreetMap attribution is displayed in the map and NASA attribution is displayed in the page footer.
The frontend is an ops-console layout: a header strip with brand mark and four labeled instrument readouts (Station, Zone, Uplink, Observations), a live noesis> status ticker, a two-pane workbench (Leaflet map on the left, event log sidebar on the right), the alert-category settings panel, the EONET category catalog panel, and a thin attribution footer.
The PAR polygon is rendered on the map as a cyan dashed outline with a SCOPE · PAR V1 scope tag and corner brackets framing the tile area, so the page reads at a glance as an instrument scope over a defined operating zone. The sidebar event log is a tabular readout sorted by observation time, with each row leading to the NASA source when one is available.
Typography is JetBrains Mono for display, captions, and readouts and IBM Plex Sans for body prose. The palette is instrument-room navy #0A1118, panel surfaces, and signal cyan #3FD2FF as the primary accent — chosen for the operational-monitoring subject rather than for a generic editorial look.
The backend retrieves and normalizes NASA data, applies the PAR/category/title inclusion rules, and returns a stable JSON contract. The frontend renders that contract with Leaflet, stores the last successful response, and handles browser notification preferences. See docs/architecture.md for the data flow and API contract.
For a simple containerized run, create a local environment file and start both services:
cp .env.docker.example .env
docker compose up --buildOpen http://localhost:8080. Nginx serves the frontend and proxies /api requests to Django. Stop the services with Ctrl+C; remove containers with docker compose down.
Do not commit .env. Use a strong secret for DJANGO_SECRET_KEY outside local experiments.
Backend:
.venv/bin/python manage.py testFrontend:
npm run test
npm run lint
npm run build- If the API returns an upstream error, confirm the backend has network access to NASA EONET and retry after a short delay.
- If old event data appears after a filtering change, stop old dev servers, restart both applications from this finalization output, and hard-refresh the browser.
- The initial map is centered on PAR; if multiple observations arrive the viewport auto-fits to the observation extent. Zoom or pan manually to inspect specific markers afterward.
- Browser notifications require a user permission action and may be unavailable on some origins or browsers.
- If Django refuses to start with
DJANGO_DEBUG=false, set a non-defaultDJANGO_SECRET_KEY.