Open-source civic infrastructure intelligence for cities.
OboApp helps residents stay informed about public infrastructure disruptions. It collects announcements about water shutoffs, heating maintenance, road repairs, municipal works, and similar incidents; turns them into structured geospatial events; and serves them through a PWA map, push notifications, and a public API.
Built for Sofia first, OboApp is designed so other cities can fork the platform, configure their own local sources, and operate an independent civic information service.
- A public map of active infrastructure disruptions
- Push notifications for user-defined areas
- A city-specific ingest pipeline for public notices
- A read-only public disruption API
- A local civic data platform backed by Firebase, MongoDB, and geospatial enrichment
flowchart LR
sources[Public sources] --> crawlers[Crawlers]
crawlers --> ingest[AI filtering and extraction]
ingest --> geocoding[Multi-provider geocoding]
geocoding --> events[Messages and events]
events --> web[PWA map]
events --> api[Public API]
events --> notifications[Push notifications]
Automated crawlers collect notices from public sources such as utility providers, heating companies, transport operators, and municipal sites. AI-powered filtering, categorization, location extraction, and multi-service geocoding convert raw text into map-ready GeoJSON. Event matching groups related disruptions, and the notification engine matches new events with user-defined interest areas.
The web app is a Next.js Progressive Web App with an interactive map. Users can browse current disruptions, define interest circles with a custom radius, and receive notifications when new issues affect their areas.
Choose the setup path that matches what you want to work on:
| Goal | Start here |
|---|---|
| Front-end development without Java or Docker | Quick Start: Front-End with MSW |
| Full-stack local development with emulators | Quick Start: Firebase Emulators |
| Production deployment | Production Setup Guide |
| API integration | Public API |
This is a pnpm workspace monorepo. Always install dependencies from the repository root:
pnpm installThe shared packages build automatically during postinstall.
If you modify shared schemas or database types, rebuild before running web/, ingest/, or api/ code:
pnpm build:shared
pnpm build:db| Package | Purpose |
|---|---|
| shared/ | Shared TypeScript schemas and source configuration used by the app, API, and ingest pipeline |
| db/ | Database abstraction layer, @oboapp/db, with dual-write support over Firestore and MongoDB |
| ingest/ | Crawlers, AI processing, geocoding, event matching, and notifications |
| web/ | Next.js PWA, map UI, onboarding, notifications UX, and BFF route handlers |
| api/ | Public REST API built with Hono, Zod, OpenAPI generation, and API key auth |
| Area | Stack |
|---|---|
| Web app | Next.js, React, TypeScript, Tailwind CSS, Google Maps API, Leaflet, TanStack React Query, MDX |
| BFF | Next.js Route Handlers, Firebase Auth |
| Public API | Hono (Node.js), Zod, OpenAPI auto-generation, API key auth |
| Pipeline | Node.js, Playwright, Google Cloud Run Jobs, Cloud Workflows |
| Database | Firebase Auth, Firestore, Cloud Messaging, MongoDB, @oboapp/db |
| AI | Google Gemini for filtering, categorization, location extraction, and embeddings; promptfoo for evaluation |
| Geospatial | Google Geocoding, OpenStreetMap Overpass, Bulgarian Cadastre, GTFS, Turf.js |
| Infrastructure | Google Cloud Run, Workflows, Scheduler, Storage, Terraform, Docker |
| Testing | Vitest, Testing Library, MSW, Playwright |
| Tooling | pnpm workspaces, ESLint, esbuild, TypeScript strict mode |
OboApp has several independent surfaces for contributors. Each area links to open issues where that kind of work is needed.
New contributors may want to start with good first issues or help wanted issues.
| Area | What you can work on | Open issues |
|---|---|---|
| Crawlers | Add or improve public disruption sources | crawler issues |
| Ingestion pipeline | Filtering, extraction, source cleanup, and pipeline reliability | ingestion issues |
| Geocoding | Address, street, locality, transit, and geometry resolution | geocoding issues |
| Event aggregation | Duplicate detection, event matching, and incident lifecycle | event aggregation issues |
| Notifications | Matching events to user zones and delivering push notifications | notification issues |
| Web app | Map UI, onboarding, installability, and interaction design | UI issues and UX issues |
| Public API | API contract, docs, client onboarding, and response shape | Public API issues |
| Multi-locality support | Making OboApp easier to run for other cities | multi-locality issues |
| Testing and tooling | Test coverage, mocks, CI, scripts, and local development workflow | testing issues and developer experience issues |
See CONTRIBUTING.md for the full contribution process.
Before opening a PR, run the checks that match the packages you changed. The broad workspace checks are:
pnpm build:all
pnpm lint:all
pnpm test:allFor TypeScript validation, run pnpm tsc --noEmit in the affected package, especially ingest/, web/, and api/.
Important project rules:
- Database operations go through
@oboapp/db; application code should not call Firestore directly. - Shared schema changes require rebuilding shared/ and db/ before running dependent packages.
- New crawlers should update the crawler implementation, Terraform crawler list, source definition, and source assembly together.
- Web UI text is Bulgarian in informal register.
- Documentation is concise, behavior-focused, and written for technical stakeholders, operators, and QA personnel.
Additional implementation standards live in AGENTS.md.
- Message Filtering - AI-powered content filtering, address extraction, geocoding, and time-based relevance
- Message URLs - Short, shareable URLs for deep-linking to messages
- Geocoding System - Multi-service geocoding with Google, OpenStreetMap, Bulgarian Cadastre, and GTFS APIs
- Onboarding Flow - User onboarding state machine for notifications and zone creation
- Database Layer - Dual-write database abstraction over Firestore and MongoDB
- Locality Configuration - Environment-based locality configuration for hosting in different cities
- Public API - Read-only
/api/v1API, API key auth, and client onboarding
- Ingest Overview - Data collection and processing pipeline architecture
- Message Processing - Filtering, extraction, geocoding, and GeoJSON conversion flow
- Crawlers - Data sources and web scraping implementations
- Notifications - Push notification matching and delivery
- Terraform - Cloud Run deployment and infrastructure
- Web App - PWA installation and browser support