vccs
Vue 3용 차트 컴포넌트 모음, Recharts에서 포팅
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A futuristic dashboard visualizing the impact of AI on the workforce. This application combines 3D visualization, live economic data, and generative AI to provide a comprehensive look at how jobs are evolving.README 전문 보기 ↗A futuristic dashboard visualizing the impact of AI on the workforce. This application combines 3D visualization, live economic data, and generative AI to provide a comprehensive look at how jobs are evolving.
Install Dependencies
npm install
Environment Configuration
Create a .env file in the root directory:
ANTHROPIC_API_KEY=your_server_default_claude_key_here
VITE_BLS_API_KEY=your_bls_api_key_here
VITE_SUPABASE_URL=your_supabase_project_url_here
VITE_SUPABASE_ANON_KEY=your_supabase_anon_key_here
Notes:
ANTHROPIC_API_KEY is used server-side by the proxy as the default Claude key.VITE_SUPABASE_URL / VITE_SUPABASE_ANON_KEY are optional. Omit them and
the app runs exactly as before — no account button, no persistence, nothing
broken. See Individual User Activity to set
these up. The anon key is a publishable identifier, not a secret — see that
section for why it's safe to ship in the client bundle.Run Locally
npm run dev
This app is a Vite SPA and uses server-side proxy endpoints in production.
The local Vite proxy in vite.config.ts is dev-only and does not run on Vercel.
Set these in Vercel Project Settings -> Environment Variables:
ANTHROPIC_API_KEY=your_server_default_claude_key_here
VITE_BLS_API_KEY=your_bls_api_key_here
VITE_SUPABASE_URL=your_supabase_project_url_here
VITE_SUPABASE_ANON_KEY=your_supabase_anon_key_here
Notes:
ANTHROPIC_API_KEY enables default Claude key mode.VITE_BLS_API_KEY is optional but recommended for higher BLS rate limits.VITE_SUPABASE_* are optional — omit to deploy without accounts/persistence.From the repo root:
npx vercel
Follow prompts to create/link the project, then add env vars above.
After env vars are configured:
npx vercel --prod
Production uses Vercel serverless functions under:
/api/claude/messages -> Anthropic proxy/api/bls and /api/bls/:seriesId -> BLS proxyThese endpoints preserve the same runtime behavior expected by the frontend:
Landscape.tsx: Main 3D scene controller.Terrain.tsx: Custom shader-based terrain generation using BLS data.MapView.tsx: Interactive SVG/Dom-based world map for geographic insights.UI.tsx: The main "Glassmorphism" overlay dashboard.Employment/headcount data comes from BLS's Occupational Employment and Wage Statistics program, in two separate extracts refreshed independently — check each one's own source note before assuming a number is current, since they can drift apart between refreshes:
| Extract | File | Drives | Current vintage |
|---|---|---|---|
| National, per role | src/data.ts | 3D terrain height, the Workers stat, the "OES" badge | May 2025 |
| State-level | src/data/geo_real.json | 2D US map employment + Location Quotient | May 2025 |
# 1. Get a free BLS registration key (unregistered tier is 25 req/day, not
# enough to cover the ~5,000 series a full refresh needs):
# https://data.bls.gov/registrationEngine/
export VITE_BLS_API_KEY=your_key_here
# 2. Preview the change with no files written:
node scripts/refresh_oes_data.mjs --dry-run
# 3. Apply it (both national and state-level; add --national-only for just
# the smaller national pass, e.g. while iterating without spending quota
# on the full state-level fetch):
node scripts/refresh_oes_data.mjs
This pulls directly from api.bls.gov — www.bls.gov/download.bls.gov block
automated downloads (Akamai bot protection), so the classic "download the OEWS
workbook" path (scripts/extract_bls_data.py) can no longer be refreshed
programmatically for a new vintage. scripts/refresh_oes_data.mjs rewrites, in
one pass: src/data.ts employment values, all 50 dataSources literals in
that file, DATA_SOURCES.BLS_OES in src/config/constants.ts,
src/data/national_employment.json, and (unless --national-only)
src/data/geo_real.json. src/__tests__/oesVintage.test.ts and
scripts/audit.mjs (T65–T67) both guard
that DATA_SOURCES.BLS_OES and the literals in data.ts never drift apart.
src/utils/onet.ts's MAP_TITLE_TO_SOC is the single source of truth for
which SOC code each role uses, for both extracts. If BLS retires or
consolidates a SOC code (as happened to 13-1022/13-1023, now the broad
code 13-1020), update that map first — the refresh script and
scripts/audit.mjs T64/T57/T58 both key off it.
Signed-in users (anonymous by default, upgradeable to email) get their saved roles, view history, upskill progress, and saved AI reports persisted and kept private to them. This is entirely optional infrastructure — without it configured, the app behaves exactly as a stateless, anonymous SPA.
api/*.ts serverless functions do
not run under npm run dev (see AGENTS.md).localStorage['foj_user_claude_key'], sent as an x-user-api-key header)
is untouched by any of this. Signing out does not clear it; it is never
written to a user record; auth uses a completely different transport
(Supabase's own session bearer token, to a different origin).resumeCacheKey in src/lib/userData.ts) so a
saved report can be found again without ever storing the source text.supabase/migrations/, in
order — read each file's own header comment for what it does before running
it:
0001_user_activity.sql — creates the tables and RLS policies.0002_grant_authenticated_privileges.sql — required. RLS decides
which rows a role may touch, but Postgres needs a separate, more basic
GRANT before a role may query a table at all. Skipping this leaves every
request from a signed-in (including anonymous) user failing with a 403
before RLS is ever evaluated — the app looks completely broken while the
policies themselves are perfectly correct.http://localhost:3000. Set it to your deployed
origin (e.g. https://your-app.vercel.app), or every emailed link points
at a dev server that isn't running.emailRedirectTo and
falls back to the Site URL. Add your origins with a wildcard so any path
(the app requests /dashboard) is permitted:
https://your-app.vercel.app/**
http://localhost:5173/**
VITE_SUPABASE_URL / VITE_SUPABASE_ANON_KEY — locally in .env.local
and in Vercel Project Settings → Environment Variables for production.
The anon key is meant to be public: it carries no privileges of its own,
and every table denies all access until RLS explicitly grants it.VITE_SUPABASE_URL=... VITE_SUPABASE_ANON_KEY=... node scripts/verify_rls.mjs
This creates two real anonymous users and asserts neither can read, write,
update, or delete the other's rows — the thing a mocked-client unit test
cannot prove, since RLS is enforced by Postgres itself.