Know what to do next.
A free, source-linked guide to getting set up in the United States as a newcomer. You pick a goal, BridgePath asks only what changes the answer, and it shows the likely requirements, what to bring, what to verify, and which official page says so.
Live: bridgepath.lovable.app
BridgePath is a navigation and education layer over fragmented official information. Its value is organizing confusing processes, putting them in the right order, linking the actual government form, and separating what a rule says from what a bank actually does at the counter.
It is not an immigration eligibility engine, a law firm, a financial advisor, or a government agency.
It must never tell someone they qualify for a visa, are eligible, hold legal status, may work, or have a particular immigration right. This is not a stylistic preference. It is enforced by a test that fails the build (see Content rules).
Where the product line sits:
| BridgePath does | BridgePath does not |
|---|---|
| Explain what a status category generally refers to | Determine what status someone holds |
| List documents commonly associated with a process | Assert a document list is complete or required |
| Show what a rule permits and what a provider requires, separately | Decide whether an individual qualifies |
| Point at the official source and when it was last checked | Replace the official source |
Intake never leaves the browser. The guide asks about status, documents and location. That is a sensitive profile. runPipeline() is pure and local, the PDF is generated client-side, and nothing is persisted, logged, or sent anywhere. Closing the tab loses the answers, which is the intended trade. Any change that moves scoring server-side destroys the main privacy claim.
Verification dates are earned, not generated. A source shows "Last checked " only when a maintainer actually opened it. Everything else reads "Verification pending". A provenance feature that invents its own provenance is worse than not having one.
npm install
npm run devThen open http://localhost:8080.
| Command | What it does |
|---|---|
npm run dev |
Dev server on :8080 |
npm run build |
Production build |
npm test |
Full test suite |
npm run test:watch |
Tests in watch mode |
npm run lint |
ESLint |
.env is committed on purpose. It holds only public client-side values, and Vite inlines VITE_* at build time, so without it the build still succeeds but ships undefined credentials and fails in the browser. See Environment.
A Vite + React + TypeScript SPA. The scoring engine is pure TypeScript with no I/O. Supabase provides Postgres and three edge functions.
Browser
├── Guide → runPipeline() → result workspace → PDF
│ Entirely local. No network, no persistence.
│
└── Network (four calls in the whole app)
├── forum_posts / forum_replies RLS-guarded reads and inserts
├── functions/forum-upvote service_role → RPC
├── functions/doc-checker → AI gateway
└── functions/dawn-chat → AI gateway (streaming)
| Route | Purpose |
|---|---|
/ |
Goal-first landing |
/guide, /guide/result |
Adaptive intake and the result workspace |
/explore |
Browse by task |
/explore/:topicId |
Evergreen guides (banking, credit, identity-tax, transfers) |
/explore/status, /explore/status/:slug |
Status and visa reference (17 categories) |
/forms |
Official forms grouped by life task |
/near-me |
Local official resources by city |
/updates |
What changed |
/methodology |
How BridgePath ranks, labels and verifies |
/path, /lines, /hubs, /sources and /forum redirect to their replacements.
| Path | Role |
|---|---|
src/lib/pipeline.ts |
The scoring engine. Pure, deterministic, no I/O |
src/lib/trust.ts |
Trust model: SourceRecord, Claim, labels, source hierarchy |
src/lib/guideState.tsx |
In-memory guide answers, and the mapping onto the engine |
src/lib/resultView.ts |
Turns engine output into the result workspace shape |
src/data/sources.ts |
Source registry. Every citation resolves to one of these |
src/data/statuses.ts |
Status and visa reference content |
src/data/forms.ts |
Official forms by life task |
src/components/trust/ |
TrustBadge, SourceList, LegalDisclaimer |
src/components/status/ |
Status cards, drawer, inline chips, "where the lines sit" |
Colour carries meaning. Each family maps to exactly one trust level and is never used decoratively.
| Label | Colour | Means |
|---|---|---|
Official |
Blue #3E6FA8 |
A government rule, agency page, or a provider's own published requirements |
Status reference |
Indigo #6558A6 |
Information about an immigration or visa category. Never an eligibility determination |
BridgePath guidance |
Green #1F6B5B |
Our plain-language reading of the sources, with assumptions shown |
Verify |
Amber #B7791F |
Varies by provider or circumstance. Check before relying on it |
Community |
Clay #A66A4F |
A Reddit thread or user report. Never promoted into fact |
Important |
Coral #B7534B |
A genuine blocker or safety issue. Used sparingly |
Two rules that matter:
- Individual visas are never colour-coded. F-1, H-1B and J-1 all use the same indigo. Per-visa colours would turn a reference list into a legend nobody memorises. Meaning comes from text.
- Every label carries text and an icon, so it still reads correctly without colour vision or in high-contrast mode.
Source hierarchy. Government primary source, then a provider's published requirements, then a recognized institutional source, then BridgePath interpretation, then community reports. When sources disagree, show the disagreement. A community report never silently overrides an official one.
Anything added to src/data/statuses.ts or src/data/forms.ts must follow these. They are checked by src/test/trust-content.test.ts.
Use hedged language: "generally refers to", "may affect", "commonly associated with", "a provider may request", "verify with the official source", "requirements may depend on your circumstances".
Never write: "you are eligible", "you qualify", "you are authorized", "you can legally", "guaranteed", "approved for", "eligibility score".
The test distinguishes BridgePath's own voice from reported speech, so warning about a notario "promising guaranteed status" is fine. Asserting it yourself is not.
Every claim needs at least one sourceId resolving to a record in src/data/sources.ts. Official sources must be https and on a .gov host.
npm testThe suite guards behaviour, not implementation:
pipeline.test.ts: engine invariants. Savings never changes which pathways appear. SSN status is never a proxy for immigration status. Visa type alone is not a banking determinant. Same input always produces the same output. Exactly one pathway is ever recommended.trust-content.test.ts: the language guardrail, source provenance, and that every official source is an https.govURL.guideState.test.tsx: the guide-to-engine mapping, including that savings is fixed and SSN is derived from documents rather than visa type.routes.test.ts: every internal link resolves to a declared route.trust.test.ts: verification-date formatting, staleness, and that a community source can never sort above an official one.
The project is developed in Lovable and synced to this repo. Three things deploy separately, and the order matters.
1. Code sync. Lovable syncs one branch at a time, by default main. Pushing to any other branch will not appear until you either merge it or switch branches in the project's GitHub settings.
2. Supabase. Edge functions and migrations do not deploy from a Git push. Changes under supabase/ are just files until Lovable deploys the functions and you approve the migration SQL in chat. Deploy these before publishing a frontend that depends on them, or the new client will call the old function signature.
3. Publish. Publishing is a snapshot, not continuous deployment. After syncing, open Publish and click "Publish changes". A dot on the Publish button means the live site is behind.
.env holds only public client-side values. Anything prefixed VITE_ is compiled into the browser bundle and readable by anyone.
The Supabase publishable (anon) key belongs there because it is public by design. It is safe only because row-level security is enforced on every table.
Server-side secrets (LOVABLE_API_KEY, SUPABASE_SERVICE_ROLE_KEY) go in Supabase edge function secrets and must never become a VITE_ variable.
The edge functions are reachable by anyone who reads the anon key out of the bundle, so verify_jwt is a speed bump rather than a gate. Real protection is in the functions:
- Roles are whitelisted on chat input. A caller-supplied
systemmessage would otherwise override every safety rule in the prompt. - Inputs are validated against fixed allow-lists, and message count and length are capped.
- Per-IP rate limiting is backed by Postgres, because edge isolates are ephemeral and an in-memory counter protects nothing. It fails closed.
- Errors are generic. Exception text goes to the function log, never to the caller.
- CORS is an origin allow-list.
Forum content supports soft-delete so anything harmful can be removed. Community contributions are intentionally not wired to a backend until a moderation queue exists.
- Interface copy is English only. The language toggle sets the document language and the language the assistant replies in, but the pages are not translated yet. Translations exist for the previous IA in
src/i18n/translations.tsand need a new key set. - Most sources read "Verification pending". Government hosts sit behind bot protection that blocks automated link checking, so a first human pass is needed.
- Community Pulse is illustrative. Signals are seeded data until moderation is built.
No licence has been chosen yet, which means default copyright applies and others may not reuse the code. Pick one before promoting the project.