Public dashboard for tracking state-level performance across the 50 states plus DC using official federal data.
Next.js 15+ TypeScript + App RouterPostgres+PrismaTailwind CSSTanStack TableRechartsreact-simple-mapsVercel Cron
- Unemployment rate
- Payroll job growth
- Real GDP growth
- Population growth
- Median household income
- Poverty rate
- Bachelor's attainment
- Cost of living index
- Homelessness rate
- State spending per capita
- Taxes per capita
- Gasoline cost
- Copy
.env.exampleto.env. - Install dependencies with
npm install. - Start Postgres locally.
You can use the included Docker helper with
docker compose up -d. - Generate Prisma with
npm run prisma:generate. - Bootstrap the database and load data with
npm run bootstrap:data. - Start the app with
npm run dev.
DATABASE_URLCRON_SECRET
BEA_API_KEY and CENSUS_API_KEY are not required by the current ingest pipeline.
- Create a new GitHub repository.
- Push this project to that repository.
- Confirm GitHub Actions is enabled for the repo.
This repo includes a CI workflow at .github/workflows/ci.yml that runs lint, tests, and build on every push and pull request.
After publishing the repo, these settings are worth turning on:
- Protect
main. Require pull requests before merging, require the CI workflow to pass, and block force pushes. - Enable auto-delete for head branches after merge.
- Allow squash merges. This works well for the small, reviewable PRs this project will likely use.
- Add repository secrets only if you later move any deploy or data bootstrap tasks into GitHub Actions. The current setup does not require production secrets in GitHub.
- In Vercel, choose
Add New...->Project. - Import the GitHub repository for this app.
For this repo, select
danielmcauley/ephor. - Attach a Postgres database. Recommended: Neon via the Vercel Marketplace.
- Add these production environment variables in Vercel:
DATABASE_URLCRON_SECRET
- Deploy the project.
These are the exact settings to use for the published GitHub repo:
- In Vercel, import
danielmcauley/ephor. - Keep the framework preset as
Next.js. - Set the production branch to
main. - Leave preview deployments enabled so PRs and feature branches get shareable preview URLs.
- Add the production environment variables before the first production deployment:
DATABASE_URLCRON_SECRET
- Attach the Postgres integration and confirm the resulting
DATABASE_URLpoints at the production database. - Deploy once, then run the one-time bootstrap command against the production database.
- After bootstrap finishes, open the site,
/methodology, and/api/metadatato confirm production data loaded correctly.
After the first deployment, run the data bootstrap once against the production database:
DATABASE_URL="your-production-database-url" npm run bootstrap:dataThat will:
- apply the Prisma schema
- seed jurisdictions and metric definitions
- ingest the latest source data
Daily refresh is already configured in vercel.json:
- path:
/api/cron/ingest - schedule:
0 13 * * *
The ingest route expects Authorization: Bearer <CRON_SECRET> when CRON_SECRET is set. Vercel cron can send that automatically when the secret is configured in the project environment.
- Open the deployed site and verify the homepage loads.
- Check
/methodologyfor refresh status across metrics. - Check
/api/metadatafor machine-readable refresh output. - Add a custom domain in Vercel.
- Trigger a manual redeploy after any environment variable changes.
- This app is public and read-only in the MVP.
- Rankings are metric-specific. There is no overall composite score in v1.
- The app serves the latest available period per metric rather than forcing one shared reporting date.