factcircuit
FactCircuit는 불변 출처와 단계별 검증, 제한된 검색, 재현 가능한 평가를 제공하는 감사 가능한 주장·증거 검증 루프입니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Track the immigration, visa, enforcement, and workforce numbers shaping America.
A public, mobile-first, fact-based U.S. immigration and workforce data dashboard —
inspired by usdebtclock.org, rebuilt with a modern,
dark, animated UI. ImmigrationClock makes enforcement, visa approvals, deportations,
border encounters, H-1B sponsorship, layoffs, and wage trends easy for ordinary
people to understand — neutrally, with a source on every number.
Facts first. Trends live. Sources included.README 전문 보기 ↗Track the immigration, visa, enforcement, and workforce numbers shaping America.
A public, mobile-first, fact-based U.S. immigration and workforce data dashboard — inspired by usdebtclock.org, rebuilt with a modern, dark, animated UI. ImmigrationClock makes enforcement, visa approvals, deportations, border encounters, H-1B sponsorship, layoffs, and wage trends easy for ordinary people to understand — neutrally, with a source on every number.
Facts first. Trends live. Sources included.
🔴 Live: https://immigrationclock.vercel.app
Go live in 3 steps: (1) merge the open PR into
main; (2) import the repo at vercel.com/new — Next.js is auto-detected andvercel.jsonsets the security headers; (3) setNEXT_PUBLIC_SITE_URLto your Vercel URL (optionallyNEXT_PUBLIC_NEWSLETTER_ENDPOINTfor the Pulse signup). Every push tomainthen auto-deploys, and the daily GitHub Action keeps data fresh — rebuilding only when it actually changes, to stay within the free tier.
Data: Headline figures are real, sourced U.S. government numbers (USCIS, ICE,
CBP, the State Department, BLS) — e.g. FY2024 H-1B 399,395 approvals (India 283,397),
ICE removals 271,484, real top-10 employers. FY2024 is the latest complete year for
most series; FY2025 is preliminary and detention is a dated point-in-time figure.
Fine-grained per-state / per-country splits are clearly-labeled estimates derived
from those real totals (see /methodology).
/company/[slug]) — H-1B approvals/denials, approval rate,
LCA filings, offered wages, top job titles, worksites, year-over-year trend, and
layoffs./state/[code]) and Country pages (/country/[slug])./h1b/employers) — search the real USCIS H-1B
Employer Data Hub (thousands of sponsors) by name for reported approvals,
denials, and approval rate./for-you) — pick your situation (H-1B worker, F-1 student,
employer, employment-based green-card applicant) and get the data that affects
you, labelled and framed as context, not advice — plus the services that fit it./resources) — a curated, honestly-labelled directory of the
services newcomers actually use (immigration legal help, money transfer,
nonresident tax, newcomer banking, insurance, eSIM). Contextual "Helpful
services" modules also appear on the homepage, company, country, and state pages.
This is the site's primary revenue layer — see Monetization below./pulse page, and an
auto-generated weekly email (preview/copy at /admin/pulse-email)./search) + a persistent navbar lookup — find any employer, state,
country, visa type, or job./data) — which sources are live vs curated and
how far behind each is.| Layer | Choice |
|---|---|
| Framework | Next.js 14 (App Router) + TypeScript |
| Styling | Tailwind CSS |
| Charts | Recharts |
| Animation | Framer Motion (animated counters) |
| Database | PostgreSQL + Prisma ORM |
| Ingestion | Python (pandas + SQLAlchemy) |
| Hosting | Vercel-ready |
npm install
npm run dev
Open http://localhost:3000. The homepage, all section trackers, and every
employer/state/country page render from the generated dataset snapshot
(src/lib/generated/dataset.json, read via src/lib/dataset.ts). That snapshot
is produced at build time by scripts/build-dataset.ts from the curated +
modeled source in src/lib/source-data.ts — run npm run build:data to
regenerate it. This is the fastest way to see the product.
npm installrunsprisma generateautomatically (postinstall). It does not need a database connection.
npm run build
npm run start
The app reads from the sample dataset by default. To use PostgreSQL:
cp .env.example .env
Set DATABASE_URL (and DIRECT_URL if you use a pooled connection). Examples:
# Local PostgreSQL
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/immigration_clock?schema=public"
DIRECT_URL="postgresql://postgres:postgres@localhost:5432/immigration_clock?schema=public"
Create the database locally:
createdb immigration_clock # or use Docker / Neon / Supabase
Hosted Postgres (recommended for Vercel): create a free database on Neon or Supabase, paste the pooled connection string into
DATABASE_URL, and the direct string intoDIRECT_URL.
npx prisma generate
npx prisma migrate dev --name init
npm run seed
This loads the same sample dataset the static MVP uses, so the database path matches the UI exactly. Inspect it with:
npx prisma studio
Set USE_DATABASE="true" in .env. (The data-access layer in src/lib/data.ts
is the single place to wire Prisma queries behind the existing selectors.)
Located in data_pipeline/. They download/normalize public
datasets and load them into PostgreSQL. See
data_pipeline/README.md for details.
python -m venv .venv
# Windows: .venv\Scripts\activate | macOS/Linux: source .venv/bin/activate
pip install -r data_pipeline/requirements.txt
# run the full pipeline (uses DATABASE_URL; DRY-RUN if unset)
python data_pipeline/run_all_ingestions.py
# or one source
python data_pipeline/ingest_uscis_h1b.py
Each script downloads-or-reads public data, cleans column names, normalizes dates,
employer names and state codes, attaches the source URL + refresh timestamp, loads
into Postgres, writes a RefreshLog, logs row counts, and fails gracefully.
npm install # install deps (+ prisma generate)
npm run dev # start dev server (reads generated/dataset.json)
npm run build # prebuild (refresh + build:data) + next build
npm run start # run the production build
npm run lint # eslint
npm run refresh # fetch near-live feeds (BLS, CBP) → refresh.json + history.json
npm run build:data # rebuild generated/dataset.json from source-data.ts
npm run backfill:history # (re)seed the historical archive from CBP's monthly CSVs
npx prisma studio # browse the (legacy) database
python data_pipeline/run_all_ingestions.py # legacy Postgres ingestion (not used by the site)
The app builds as a fully static export (next.config.js → output: "export"),
so the host just serves the generated out/ directory — no Next.js server runtime,
serverless functions, image optimization, or database required at runtime. That
makes it cheap to run and keeps usage inside the Vercel Free (Hobby) tier.
Live on Vercel: https://immigrationclock.vercel.app
Deploy by importing the GitHub repo in Vercel — the Next.js framework preset is
auto-detected and vercel.json sets the security headers. Every push to main
auto-deploys. Set NEXT_PUBLIC_SITE_URL to your deployed URL so
sitemap/canonical/OG links are correct. The export also works on GitHub Pages,
Cloudflare Pages, or npx serve out — anywhere static files are hosted.
The site reads exactly one file at runtime: src/lib/generated/dataset.json. It is
produced at build time by the prebuild step, which runs two scripts:
scripts/refresh-data.mjs — fetches the near-live feeds:
src/lib/generated/refresh.json + public/data-manifest.json, and
appends the latest CBP month to the growing archive
src/lib/generated/history.json. On any fetch failure it keeps the last good
value (never fabricates, never crashes the build).scripts/build-dataset.ts — runs the curated + modeled source
(src/lib/source-data.ts), which prefers the live-fetched values when present,
and serializes the full dataset to dataset.json.Everything is labelled reported / projected / estimated, and CBP figures that came from a real fetch are shown as reported with the actual reporting month.
.github/workflows/refresh-data.yml runs
once daily: it executes the same pipeline, and only when the underlying data
actually changed (ignoring timestamps) commits the refreshed snapshot + archive
back to the repo. That push to main triggers Vercel's git integration to rebuild.
Because the data moves at most weekly/monthly, this keeps Vercel builds to a handful
per month — comfortably within the free tier. To enable it:
main).VERCEL_DEPLOY_HOOK and the workflow
will also ping it on a data change.)CBP, BLS, and Texas WARN now flow in automatically. To wire additional sources (more
WARN states, …), add a fetcher to refresh-data.mjs and consume it in source-data.ts.
(The Prisma schema + seed + Python data_pipeline/ remain in the repo as a legacy
DB path but are not used by the live site, which is fully static + JSON-backed.)
ImmigrationClock sits in one of the highest-intent verticals on the web — people making real immigration, money, and tax decisions. There are four revenue levers, in rough order of revenue-per-visitor for this niche. All work on the static export; none require a backend.
➡️ To turn revenue on, follow
MONETIZATION.md— a step-by-step activation playbook (which affiliate programs to join, which env vars to set, and how to read the data). Everything below is already built; the playbook is how you switch it from $0 to earning.
Contextual "Helpful services" modules sit beside (never inside) the data on the
highest-intent pages — the homepage + /for-you persona switcher, every company,
country, and state page — plus a dedicated /resources
hub. They link to services newcomers genuinely use (immigration legal help,
certified document translation, foreign-degree evaluation, visa-sponsor job search,
international money transfer, nonresident tax filing, newcomer banking & credit,
student insurance, eSIMs, and international moving). In this niche an affiliate
signup/lead is worth far more than a display impression.
src/lib/partners.ts. Out of the box
links point to each service's homepage, so the modules are useful immediately.NEXT_PUBLIC_PARTNER_LINKS={"wise":"https://wise.com/invite/abc","sprintax":"https://www.sprintax.com/?ref=you"}
Ids: boundless, attorney-match, wise, remitly, sprintax, resident-tax,
newcomer-credit, newcomer-insurance, esim, citizenship-prep,
credential-evaluation, document-translation, visa-jobs, credit-builder,
intl-moving, english-prep. Sign up for each program (Wise, Remitly, Airalo,
Sprintax, Boundless, WES, RushTranslate, insurance/banking affiliates, etc.), or
add/replace partners by editing partners.ts.rel="sponsored nofollow noopener", labelled Partner, and
carries a ?subid=ic-<placement> so your affiliate dashboard attributes revenue to the
exact module (for-you-h1b-worker, company, country, state, resources-legal, …)./disclosure page (FTC/AdSense-compliant) is
linked from every module and the footer. Trust is what keeps this earning.Ad slots render labelled placeholders (a newsletter signup) until you provide a publisher id.
NEXT_PUBLIC_ADSENSE_CLIENT_ID="ca-pub-XXXXXXXXXXXXXXXX".src/app/layout.tsx, and AdSlot.tsx renders
real <ins class="adsbygoogle"> units (top banner, sidebar, in-content, bottom
banner). Optionally set per-slot ids:
NEXT_PUBLIC_ADSENSE_SLOT_TOP, ..._SIDEBAR, ..._INCONTENT, ..._BOTTOM.The weekly Pulse signup (PulseSignup.tsx) builds an email list you can later
monetize with sponsorships. Wire it up with NEXT_PUBLIC_NEWSLETTER_ENDPOINT
(Buttondown, ConvertKit, Mailchimp, …). Until then the ad slots double as list-builders.
Set NEXT_PUBLIC_SUPPORT_URL to a Buy Me a Coffee / Ko-fi / GitHub Sponsors link to
show a ♥ Support this project button in the footer. Hidden until configured.
Partner-click analytics: the modules fire a
partner_clickevent to GA4 (gtag) or Plausible if present, so you can see which placements convert and tune the catalog. No analytics library is required — it's a no-op when none is loaded.
sitemap.xml (src/app/sitemap.ts) and robots.txt (src/app/robots.ts).src/lib/seo.ts)./api/og?title=…)./h1b/top-sponsors, /h1b/salaries/[jobTitle],
/h1b/state/[stateCode], /immigration/enforcement-trends, /border/encounters,
/visa/f1-student-visas, /layoffs-vs-h1b, /company/[slug].src/
app/ # App Router pages, sitemap, robots, /api/og
components/ # AnimatedCounter, MetricCard, charts, AdSlot, …
lib/
source-data.ts # build-time curated + modeled source (NOT imported by the app)
generated/dataset.json # build-time snapshot the app actually reads
dataset.ts # single runtime data source (reads generated/dataset.json)
data.ts # selectors / derived metrics over dataset.ts
chart-data.ts # Recharts row transforms
sources.ts, seo.ts, site.ts, format.ts, refresh.ts, seo-pages.ts
prisma/
schema.prisma # full data model
seed.ts # loads sample data into Postgres
data_pipeline/ # Python ingestion scripts
ImmigrationClock is built to be urgent and emotionally engaging but neutral, factual, and legally safe. It:
Footer disclaimer (shown site-wide): This platform uses public datasets for informational and research purposes only. It does not provide legal, immigration, employment, or financial advice. Data may lag official reporting schedules.
See /methodology for how each metric is
defined and why some counters are estimated, and /sources
for the full list of datasets.
Provided for informational and research use. Underlying government datasets are in the public domain; verify any figure against its linked source.
sitemap.xml / robots.txt, OpenGraph, full metadata. Ad slots fall back to a
newsletter signup until AdSense is configured.npm run dev — no database required.