Know before you go.
A bilingual citizen-service platform for Lumbini Province, connecting citizens with local government offices, hospitals, water providers, agricultural cooperatives and verified employers.
Overview · Problem · Features · Screenshots · Architecture · Technology · Installation · Testing · Research · Roadmap
Sajilo Lumbini is a bilingual (English and Nepali) mobile platform that helps citizens of Lumbini Province find out whether a public service is actually available before they travel to get it. It connects citizens with ward offices, municipalities, hospitals, water committees, agricultural cooperatives and verified local employers through a single mobile app.
The platform does not replace any government system. It is designed as a citizen-facing information and coordination layer above them: local institutions publish status, availability and schedule information, and citizens check it before spending time and money on a trip that might turn out to be unnecessary.
The mobile app is a React Native and Expo application backed by a FastAPI service with role-based authentication, PostgreSQL-ready data models and a provider/admin web console. Three of the seven citizen modules, Aaja Chha, Ek Choti and Aspatal Aaja, are fully wired to this backend today. The remaining four modules have complete backend routers and business logic, but the mobile app still displays them with local demo data pending their own integration phase.
Lumbini Province spans dense Terai cities, remote hill settlements and mountain communities. Citizens frequently travel long distances only to find that a service was not available in the way they expected. The problems this project targets, drawn from research.md, include:
In every case, the underlying information already exists somewhere. It is simply scattered across notice boards, phone calls, social media posts and verbal communication rather than being available in one predictable place.
Sajilo Lumbini gives citizens one place to check current information before making a trip, and gives institutions one place to publish it. Depending on the module and its current integration status, capabilities include:
Capabilities described in this README are limited to what the current repository implements. Where a feature is still local-only demo data in the mobile app, this is stated explicitly.
| Module | Purpose | Core capability | Mobile integration |
|---|---|---|---|
| Aaja Chha | Check public-office availability | Office status, queue, tokens, opening hours | Real backend data when signed in |
| Paani Palo | View local water schedules | Delays, outages, repair progress, tanker information | Demo data in the mobile app; backend router implemented |
| Aspatal Aaja | View hospital and OPD availability | Departments, doctors, OPD sessions, booking | Real backend data when signed in |
| Ek Choti | Prepare official documents | Personalised checklist, fees, witnesses, readiness score | Real backend data when signed in |
| Kaam Ko Din | Discover verified local work | Job listings, applications, attendance | Demo data in the mobile app; backend router implemented |
| Sahayata Patra | Discover public support schemes | Eligibility screening, deadlines, application tracking | Demo data in the mobile app; backend router implemented |
| Khad Nyaya | Track fertiliser stock and allocation | Stock visibility, calculated allocation, pickup token | Demo data in the mobile app; backend router implemented |
Primary users
Institutional users
Splash Screen |
Onboarding |
Profile Setup |
Location Setup |
Ward Selection |
Setup Complete |
Login |
Register |
Citizen Dashboard |
Personalised Recommendations |
Khad Nyaya |
Paani Palo |
Aaja Chha |
Aspatal Aaja |
Ek Choti |
Kaam Ko Din |
Sahayata Patra |
Notifications and Messages |
Citizen Profile |
flowchart LR
Citizen[Citizen Mobile App<br/>React Native + Expo Router]
Provider[Provider / Admin Web Console<br/>served by FastAPI]
API[FastAPI Backend]
Auth[JWT Auth + Role-Based Permissions]
Services[Feature Routers<br/>Aaja Chha, Ek Choti, Aspatal Aaja,<br/>Paani Palo, Kaam Ko Din, Sahayata Patra, Khad Nyaya]
DB[(PostgreSQL / SQLite)]
Citizen -->|Authenticated API client| API
Provider -->|Session token, in-page only| API
API --> Auth
API --> Services
Auth --> DB
Services --> DB
The mobile app talks to the backend through a single centralised API client (mobile/src/lib/api.ts) that attaches the access token, applies a request timeout, and performs one refresh-and-retry cycle on an expired token. The backend exposes its feature routers under /api/v1, enforces role-based permissions (citizen, provider, municipality admin, platform admin) on every protected endpoint, and serves a lightweight provider/admin console directly as server-rendered HTML at /admin. SQLite is used for local development with automatic schema creation; PostgreSQL with Alembic migrations is the supported path for anything beyond a single developer’s machine.
Mobile
| Technology | Role |
|---|---|
| React Native 0.76 | Application framework |
| Expo SDK 52 | Managed build and runtime tooling |
| Expo Router | File-based navigation |
| TypeScript | Static typing |
| expo-secure-store | Secure storage for access and refresh tokens |
| @expo/vector-icons (Ionicons) | Iconography |
Backend
| Technology | Role |
|---|---|
| FastAPI | API framework |
| Python | Backend language |
| SQLAlchemy 2.0 | ORM |
| Pydantic | Request/response validation |
| python-jose | JWT access/refresh token handling |
Database and infrastructure
| Technology | Role |
|---|---|
| PostgreSQL | Supported production database |
| SQLite | Default local development database |
| Alembic | Schema migrations |
| Environment-driven configuration | app/core/config.py, with production fail-fasts |
Testing
| Tool | Scope |
|---|---|
| Pytest | Backend unit and integration tests |
Jest (jest-expo preset) |
Mobile unit tests |
| ESLint | Mobile linting |
| TypeScript compiler | Mobile type checking |
sajilo-lumbini/
├── backend/
│ ├── alembic/ # Migration environment and versions
│ ├── app/
│ │ ├── core/ # Config, database, security, logging, errors
│ │ ├── routers/ # One router per module (auth, availability, tokens, ...)
│ │ ├── schemas/ # Pydantic request/response models
│ │ ├── static/ # Provider/admin console (admin.html)
│ │ ├── models.py
│ │ ├── seed.py
│ │ └── main.py
│ └── tests/ # Pytest suite
├── mobile/
│ ├── app/ # Expo Router screens (tabs, auth, onboarding, modules)
│ └── src/
│ ├── api/ # Typed backend endpoint wrappers
│ ├── auth/ # Secure token storage
│ ├── components/ # Design-system primitives
│ ├── hooks/ # Per-module data/loading/error hooks
│ ├── lib/ # Centralised API client and error types
│ ├── store/ # App, onboarding and auth context providers
│ └── theme/ # Design tokens
├── docs/
│ ├── screenshots/
│ └── backend_e2e_test.py # Full-stack end-to-end smoke test
├── project_map.md
├── research.md
└── README.md
Prerequisites
Exact Node.js and Python versions are not pinned in this repository; use a current stable release of each.
git clone <repository-url>
cd sajilo-lumbini
cd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements-dev.txt # or requirements.txt if you do not need pytest
cp .env.example .env
uvicorn app.main:app --reload
With the default SQLite .env, the schema is created and demo data seeded automatically on first start. For PostgreSQL, run alembic upgrade head instead of relying on auto-create.
cd mobile
npm install
cp .env.example .env
npx expo start
The mobile app runs in demo mode out of the box, with no backend required to explore the interface. To exercise real authentication and the three backend-integrated modules, set EXPO_PUBLIC_API_URL in mobile/.env to a URL reachable from your device or emulator:
http://10.0.2.2:8000/api/v1, not localhost.http://192.168.x.x:8000/api/v1.http://localhost:8000/api/v1 works as-is.Never commit a real .env file. Both mobile/.env.example and backend/.env.example are templates only; copy them and adjust locally.
Backend (backend/.env.example)
| Variable | Purpose | Required |
|---|---|---|
APP_ENV |
development or production; controls fail-fast checks |
Yes |
DEBUG |
Enables debug behaviour | Yes |
API_V1_PREFIX |
API route prefix | Yes |
DATABASE_URL |
SQLAlchemy database connection string | Yes |
JWT_SECRET_KEY |
Secret used to sign access tokens | Yes |
JWT_ALGORITHM |
JWT signing algorithm | Yes |
ACCESS_TOKEN_EXPIRE_MINUTES |
Access token lifetime | Yes |
REFRESH_TOKEN_EXPIRE_DAYS |
Refresh token lifetime | Yes |
CORS_ORIGINS |
Comma-separated allowed origins; must not be * in production |
Yes |
OTP_EXPIRY_MINUTES |
OTP validity window | Yes |
OTP_PROVIDER_MODE |
demo echoes OTPs in the API response; must be production with a real SMS provider in production |
Yes |
LOG_LEVEL |
Logging verbosity | Yes |
Mobile (mobile/.env.example)
| Variable | Purpose | Required |
|---|---|---|
EXPO_PUBLIC_API_URL |
Base URL of the FastAPI backend | Required for real backend features |
EXPO_PUBLIC_SUPABASE_URL |
Present in the example file; not currently used by any active code path | No |
EXPO_PUBLIC_SUPABASE_ANON_KEY |
Present in the example file; not currently used by any active code path | No |
All EXPO_PUBLIC_* variables are bundled into the client at build time and are visible to anyone who inspects the app. Do not place secrets in them.
The backend supports two modes:
Base.metadata.create_all() run automatically at startup, followed by seeding a demo dataset. No migration step is required.alembic upgrade head # apply all pending migrations
alembic downgrade -1 # roll back the last migration
alembic revision --autogenerate -m "message" # generate a migration from model changes; inspect it before committing
APP_ENV=production fails fast at startup if JWT_SECRET_KEY is left at its development default, DATABASE_URL still points at SQLite, CORS_ORIGINS is still *, or OTP_PROVIDER_MODE is not production.
http://localhost:8000/docshttp://localhost:8000/adminhttp://localhost:8000/healthhttp://localhost:8000/readyFull endpoint-level documentation, the authentication lifecycle and the standard API error contract are described in backend/README.md.
Run the following checks before submitting changes.
Backend
cd backend
pytest
Mobile
cd mobile
npm run lint
npx tsc --noEmit
npm test
npx expo-doctor
The backend suite covers health/readiness, the full authentication lifecycle, role and permission boundaries, and the Aaja Chha, Ek Choti and Aspatal Aaja modules. The mobile suite covers the API error helpers, secure token storage, the API client’s refresh-and-retry behaviour, the Aaja Chha data hook, the relative-time formatter and the notification-to-module mapping. A full-stack end-to-end smoke test covering all seven modules is available at docs/backend_e2e_test.py.
Full research, methodology and sourcing are documented in research.md. Baseline figures below come from cited government and provincial sources; impact figures are modelled estimates.
Verified baseline
| Indicator | Value |
|---|---|
| Population of Lumbini Province | 5,122,078 |
| Households | 1,141,902 |
| Local governments | 109 |
| Wards | 983 |
Pilot target (not yet executed)
| Indicator | Target |
|---|---|
| Municipalities | 5 |
| Wards | 50 |
| Registered citizens | 100,000 |
Modelled estimate, five-municipality pilot scope
Based on 40,000 monthly active citizens avoiding 2 unnecessary trips per year on average: approximately 80,000 avoided trips per year and approximately NPR 30,000,000 in modelled annual citizen value.
Projected impact figures are modelled estimates and must be validated through a real pilot. They are not measured results.
| Area | Status |
|---|---|
| Mobile foundation (splash, onboarding, navigation, theming) | Completed |
| Authentication (register, OTP, login, refresh, roles) | Completed, backend-integrated |
| Aaja Chha | Completed, backend-integrated |
| Ek Choti | Completed, backend-integrated |
| Aspatal Aaja | Completed, backend-integrated |
| Paani Palo | Backend router implemented; mobile app still uses demo data |
| Kaam Ko Din | Backend router implemented; mobile app still uses demo data |
| Sahayata Patra | Backend router implemented; mobile app still uses demo data |
| Khad Nyaya | Backend router implemented; mobile app still uses demo data |
| Provider/admin web console | Completed for the three integrated modules |
| Production deployment | Not yet performed |
This reflects a working prototype with a substantial share of the backend already built, rather than a production-deployed product.
Development has followed a phased, full-stack approach, based on repository history:
expo-secure-store, never AsyncStorage.APP_ENV=production fails fast if development defaults are still in place.This project has not undergone a formal security review or compliance certification. A full security review is recommended before any production deployment.
This repository currently follows a straightforward development workflow:
.env files or real credentials.No licence file is currently present in this repository. Licensing terms have not yet been defined.
Built by Team Dobermans.