one stop shop Tanzania
# gov-registry — Tanzania government-services discovery layer
A registry-driven, GOV.UK-style discovery site for Tanzanian government
services. **The product is discovery + SEO — not payment.** People already pay
via M-Pesa the moment they hold a control number; the unsolved pain is finding
and reading the obligation across six scattered government sites.
Every page generates from the registry. **Never hand-author a page. Never
bypass the schema.** See BUILD_PLAN.md for the roadmap.
## How it works
```
schema.ts zod single source of truth (tier drives the only UX branch)
services.ts 23 services, bilingual sw/en, Tiers A/B/C
lib/registry.ts parse-once loader + servicePaths()/entityPaths()/intentPaths()
lib/taxonomy.ts regions (all 31) + councils (sample) for entity pages
lib/obligation.ts normalized read-only result of a Tier-A lookup
lib/adapters.ts per-service upstream→Obligation mappers (traffic-fines worked example)
lib/seo.ts metadata, hreflang/canonical, GovernmentService + FAQPage JSON-LD
lib/i18n.ts locales (sw default, en) + UI chrome strings
```
### The tier model
- **A `transact`** — in-app **read-only** lookup: show the obligation and the
control number as plain text (+ copy button). No payment, ever.
- **B `assisted`** — consent note + handoff to the official portal.
- **C `listing`** — clean redirect + verified how-to. Never a dead end.
Every service sits on a C→B→A conveyor tracked in `migration`. A Tier-A
service whose endpoint hasn't been captured (`lookup.recon: "pending"`) gets an
honest 501 from `/api/lookup/[id]` — never a fake result.
### Routes (all locale-prefixed, sw default / en)
| Route | Source |
| --- | --- |
| `/[lang]` | all services, grouped by category |
| `/[lang]/huduma/[id]` | core service page — `servicePaths()` |
| `/[lang]/huduma/[id]/[dimension]/[value]` | entity pages (e.g. property tax × 31 regions) — `entityPaths()` |
| `/[lang]/maswali/[id]/[slug]` | question pages with FAQPage JSON-LD — ` …