rvaHelp
Richmond civic intake proof-of-concept: route plain-language issues to 86+ service categories, file trackable requests entirely inside rvaHelp, and triage from a staff queue, with bilingual UI and first-class accessibility. No forwarding to RVA311.
Friction before the right request
Residents describe non-emergency issues in everyday language and often do not know which service category or department applies. Vague intake creates misrouting, repeat contacts, and confusion when status updates use internal jargon.
rvaHelp is a self-contained proof-of-concept: it does not forward residents to RVA311. Instead it routes the issue, then captures a structured in-app request with location, transcript, and staff workflow.
End-to-end in rvaHelp
Chat intake maps wording to RVA311-style categories using deterministic retrieval, with no external AI. Residents submit through Submit a Request; staff manage the queue with internal notes and resident-visible updates. Emergency language is flagged; legal and predictive answers are refused.
[Input] "Street light out near the park" [Router] Repair Existing Streetlight [Resident] Submit a Request → ticket in MongoDB [Staff] Triage queue (not sent to RVA311)
Accessibility and English / Spanish
Civic tools fail when language, literacy, vision, or motion needs are treated as polish. rvaHelp puts inclusion in the header from day one.
English and Spanish: full UI copy, clarify questions, guidance, and emergency messaging are generated server-side in the resident's chosen locale (EN or ES), switchable from the header.
Accessibility drawer: adjustable text size (slider), high contrast, reduced motion, and simple language mode (shorter strings). Theme follows system light/dark preference.
Visible focus and labels: interactive controls use focus rings and text labels, not color alone.
How it is built
Monorepo for a one-day sprint: deploy beside joshuaphilip.com with PM2 (Next :3002, API :4001) and nginx on a subdomain.
Frontend — Next.js 16 + React 19
App Router chat UI, TanStack Query, Zustand (chat, locale, accessibility), Tailwind, Radix. Route handlers proxy to the API; optional Google Maps for request location.
Backend — Fastify 5 + TypeScript
Intake, help, explain-status, tickets, sources, and examples. Shared Zod schemas keep client and server aligned.
MongoDB
All demo requests live here: category, transcript, map pin, staff notes, public updates. No sync to external 311 systems.
Deterministic router
86+ service types in rva311-catalog.ts with synonyms and match patterns. Token retrieval and lexical detectors, no OpenAI.
Status & help
Plain-language status explainer from a curated lexicon. Help answers only from retrieved snippets; refuses eligibility and live-ticket claims.
Hackathon scope
Built in roughly 24 hours: credible resident path end-to-end, honest limits on the About page, and judge-visible bilingual + accessibility support.
Post-sprint: full RVA311 category catalog, removal of outbound 311 links, and production deploy as a standalone proof-of-concept.
Service categories
Intake covers roads, lights, trees, parks, collection, stormwater, sewer, taxes, zoning, parking, investigations, animals, and social-service referrals, each routed to a structured category inside the app.
Ambiguous wording triggers a targeted clarify step (for example road surface vs streetlight) instead of guessing.
Proof-of-concept value
Requests & tickets
Initial build
+ a11y drawer
“A closed-loop demo: residents file and track requests in rvaHelp; staff triage in the same system, showing how structured intake could work without sending people away to another portal.”— rvaHelp About page
Summary & core learnings
Closed loop, not a handoff
Residents never need to leave for RVA311 in this demo. The value is routing plus an in-app ticket queue that staff can actually work.
Accessibility as a requirement
Bilingual UI plus adjustable type, contrast, motion, and simple language modes make equity visible to reviewers, not buried in a README.
Explainable beats opaque
Deterministic routing, confidence bands, and reference citations support verification without a black-box chatbot.