How Nigraan's parts fit together, from the two apps and the shared Supabase backend to the scheduled data jobs and hosting.
Nigraan is two front ends over one backend. The website (a React single-page app) and the mobile app (Flutter) both talk directly to the same Supabase project. Scheduled jobs on GitHub Actions keep the official data and the facility map fresh. The website is served as static files from Vercel.
Website (React, Vercel) Mobile app (Flutter)
│ │
│ HTTPS — publishable key │
│ + the signed-in user's token │
└──────────────┬──────────────────┘
▼
Supabase: PostgreSQL + PostgREST + Auth
(row-level security decides who sees what)
▲
│ service key (GitHub secret)
GitHub Actions: NDMA/PDMA ingest (3×/day)
OpenStreetMap facilities (daily)
Browsers also call Open-Meteo directly for the weather forecast,
and load map tiles from Esri and OpenStreetMap.
| Part | Technology | Documentation |
|---|---|---|
| Website | React 18, TypeScript, Vite, Tailwind CSS, Leaflet | Frontend |
| Backend | Supabase: PostgreSQL, PostgREST, Supabase Auth | Backend |
| Tooling and scripts | Node.js, npm, Vitest, ESLint | JavaScript stack and tooling |
| Official data and facilities | Node.js jobs on GitHub Actions | Data pipeline |
| Hosting and search engines | Vercel, prerendered HTML, sitemap | Hosting, deployment and SEO |
| Who may do what | Roles enforced in the database | Roles and security |
| Quality | Unit, browser and load tests | Testing and quality |
map_records table with no review decision.reviewed_at and reviewed_by; or refuses it, which records a reason and keeps it hidden.The review gate lives in the database, not in either app, so the two clients cannot disagree about what is public.