vccs
Vue 3용 차트 컴포넌트 모음, Recharts에서 포팅
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Consumer price intelligence. Scan a product, get the source price, the asking
price, and the exact distance between them.
The app runs without any keys configured. Every external dependency degrades
to a documented no-op rather than an error, so an unconfigured environment
returns UNRESOLVED results instead of crashing.README 전문 보기 ↗Consumer price intelligence. Scan a product, get the source price, the asking price, and the exact distance between them.
npm install
npm run dev
The app runs without any keys configured. Every external dependency degrades
to a documented no-op rather than an error, so an unconfigured environment
returns UNRESOLVED results instead of crashing.
npm run build # production build
npx tsc --noEmit # typecheck
npx eslint . # lint (next build no longer runs it)
src/app/page.tsx Landing, scan entry, counters
src/app/api/scan/route.ts Scan endpoint: access, rate limits, cache, ledger
src/app/api/notify/route.ts Intent capture: the product update list
src/app/api/event/route.ts Analytics beacon (3 browser events, allowlisted)
src/app/api/stats/route.ts The funnel, and what the CSP blocked. Token-protected.
src/app/api/preflight/ Launch readiness: every blocker, by name. Token-protected.
src/app/api/diagnose/ Real calls to every provider, per-layer pass/fail. Token-protected.
src/lib/model-rules.ts Per-model Claude request rules; replies read by block type
src/lib/scan-trace.ts Provider error vs "nothing found"; loud, per-scan failure record
src/lib/fx.ts Daily exchange rates; asking prices compared in USD
src/proxy.ts Enforced Content-Security-Policy, fresh nonce per request
src/lib/analytics.ts Six events, daily counters, no third parties
src/app/scan/[id]/ Permanent page + per-scan OG image for one verdict
src/app/the-index/ The public index: ranked, filterable, all real records
src/app/api/leaderboard/ The three boards, edge-cached
src/app/sitemap.ts Hands the crawler the ledger
src/app/api/checkout/route.ts Resolves the payment link from configuration
src/app/api/webhook/route.ts Purchase webhook: Gumroad / Lemon Squeezy / Paddle
src/app/api/auth/route.ts Magic-link auth
src/app/api/proxy-image Same-origin image relay (SSRF-guarded)
src/app/api/cleanup-blobs Daily backstop for orphaned scan uploads
src/lib/scan.ts The scan engine
src/lib/redis.ts Counters, access, sessions, scan cache, THE LEDGER
src/components/VerdictCard The card. The product's entire growth loop.
Nothing below is required to run the app; each one enables a capability.
| Variable | Enables |
|---|---|
ANTHROPIC_API_KEY | Vision extraction and visual verification |
SERPER_API_KEY | Primary shopping, Lens and organic search |
SERPAPI_KEY | Backup search and merchant-link resolution |
BLOB_READ_WRITE_TOKEN | Temporary uploads for reverse-image search |
UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN | Rate limits, sessions, counters, scan cache |
IDENTITY_SALT | Salt for hashed rate-limit keys. Set this in production. |
RESEND_API_KEY | Sign-in and purchase emails |
EMAIL_FROM | From line on those emails. Its domain must be verified in Resend. Defaults to BustedLab <[email protected]>. |
NEXT_PUBLIC_BASE_URL | Absolute URLs in emails and metadata |
CRON_SECRET | Authorizes the blob cleanup cron. Without it the cron rejects everything. |
CHECKOUT_URL | The live payment link. A Lemon Squeezy link opens as an in-page overlay. Without it, or without its provider's webhook secret, checkout renders an honest closed state. |
LEMONSQUEEZY_WEBHOOK_SECRET | Signature verification for Lemon Squeezy, the live provider |
LEMONSQUEEZY_ACCEPT_TEST_ORDERS | true only during an end-to-end test on production. Test-mode orders are otherwise not granted there. |
PAYMENT_PROVIDER | Leave unset. The provider is read from CHECKOUT_URL; a contradicting value keeps checkout offline. |
GUMROAD_WEBHOOK_SECRET / PADDLE_WEBHOOK_SECRET | Signature verification for those providers |
GUMROAD_SELLER_ID / GUMROAD_PRODUCT_PERMALINK | Gumroad only. Narrow which pings grant access. No effect on Lemon Squeezy. |
GLOBAL_DAILY_SCAN_CAP | Daily ceiling on uncached scans. Defaults to 25000. |
SCAN_BURST_PER_MINUTE |
.env.example documents every variable in full.
Every confirmed verdict is written permanently to scan:rec:<id>, indexed by
time, by verdict and by markup, with a rolling per-product aggregate. This is
separate from the 24-hour result cache and it does not expire.
It is the only part of this codebase that cannot be rebuilt by a competitor. The scanner is roughly $0.009 a scan and a weekend of work; a few hundred million measurements of what things cost against what they are sold for is obtainable only by having run for years.
A record describes a product, never a person: no IP, no email, no session, no
uploaded image, and deliberately not the retail URL that was scanned. That is
what makes it publishable at /scan/<id> and what keeps it outside the scope
of a subject access request.
Six events as daily counters in Redis. No third-party script, no cookie, no
identifier: a row says "on this date, this many scans finished" and nothing
more. scan_completed, the three verdict counters and email_captured are
counted server-side and cannot be forged; share_tapped, paywall_shown and
checkout_clicked arrive from the browser through an allowlisted beacon and
are labelled client in the output so nobody mistakes them for evidence.
curl -H "Authorization: Bearer $ANALYTICS_TOKEN" https://bustedlab.com/api/stats?days=30
The number that matters is sharesPerScan. It is the loop coefficient, and
the entire growth model is a function of it.
The public index lives at /the-index, not /index. Next.js normalizes the
request path /index to / before routing, inherited from the Pages Router
where pages/index.js was the root. An app/index/page.tsx builds cleanly,
appears in the route manifest, and is unreachable forever: every request
silently renders the home page instead.
INDEXING. The only fixed figure is the scan baseline.translateY on hover, nothing that
borrows the physics of a physical object.VerdictCard's sound prop defaults to false for
exactly that reason.FINDER.| Scans per browser per minute. Defaults to 12; one IP address gets five times this. |
FREE_SCANS_PER_IP_PER_DAY | Ceiling on free scans from one IP address across all its browsers. Defaults to 40. The 2-a-day allowance itself is per browser. |
ANALYTICS_TOKEN | Bearer token for GET /api/stats. Unset means the endpoint is closed entirely. |
EVENT_BURST_PER_MINUTE | Per-IP limit on the analytics beacon. Defaults to 60. |
NOTIFY_PER_IP_PER_HOUR | Product update sign-ups accepted per IP per hour. Defaults to 20. |
CSP_REPORT_ONLY | Leave unset. true downgrades the enforced Content-Security-Policy to report-only while a fix ships. |
UNSUBSCRIBE_SECRET | Signs unsubscribe links. Set before the first list email and never change it. Falls back to IDENTITY_SALT. |
PAID_DAILY_SCAN_CEILING | Fair-use scans per paid account per day. Defaults to 500. |
DAILY_MODEL_BUDGET_USD / MODEL_BREAKER_COOLDOWN | Daily model spend ceiling and circuit-breaker cooldown. |
IMAGE_PROXY_SECRET | Signs image-proxy URLs. Falls back to IDENTITY_SALT. |
IDENTITY_CACHE_TTL | Seconds a product identification is reused. |