Skip to content

Repository files navigation

Casecomp logo Casecomp

VersionCIDeployLicenseAPISLSA 3SigstoreSBOM

casecomp.xyz | API Docs | Admin | Changelog

Search any Pokemon card across four marketplaces in one query. Get live prices, AI condition estimates, and PSA grading signals instead of manually checking eBay, magi.camp, Yahoo Auctions, and SNKRDUNK separately.

eBay Pokémon card search demo

Features

  • Multi-source search - eBay, magi.camp, Yahoo Auctions JP, SNKRDUNK in one query
  • Cross-source arbitrage - compares lowest prices across sources, highlights spread
  • Condition detection - auto-detects card condition across sources (EN: NM/LP/MP, JP: 状態A/美品)
  • AI pre-grading - 8-subgrade front/back analysis with card detection, tilt correction, grade distribution, shareable reports
  • Grade history - track your graded cards, view results, share as social cards
  • Price history - sold comp tracking over time with line charts and stats
  • PSA grading signals - population data, difficulty, gem 10%, recommended submission tier
  • Slab comparison - compare PSA 10 / BGS 9.5 / TAG 10 prices across sources
  • Portfolio - track cards, ROI, value over time, grading opportunities
  • Admin - API key management, analytics dashboard, error monitoring with type filters, user funnel tracking at /admin
  • Set browser - browse 353 sets with logos, rarity filters, language filter (EN/JP), collection tracking (owned/missing)
  • REST API - authenticated endpoints with rate limiting, per-key caching, OpenAPI spec
  • Claude Code skill - /casecomp for plain-English card search
  • Chrome extension - queue auto-join for Pokemon Center, Walmart, Costco, Target drops

Quick start

yarn install
yarn playwright-install
cp .env.example .env # add keys (see Environment below)
yarn api # API on localhost:3000

Scripts

CommandWhat
yarn apiStart API on :3000
yarn startCLI search (node index.js)
yarn testFull suite: syntax, unit, secrets, API
yarn test:unitUnit tests only (no server)
yarn test:apiAPI tests against localhost
yarn test:liveAPI tests against api.casecomp.xyz
yarn deployBuild + deploy to Cloud Run
yarn scanEvent & release scanner

Architecture

See docs/internals.md for project layout, caching, security pipeline, multi-region deployment, and AI grading pipeline.

Frontend

casecomp.xyz — search, set browser, portfolio, AI grading. Built with TanStack Start, deployed on Cloud Run + Cloudflare.

Three sample cards work without sign-in (?demo=true):

  • Pikachu ex SAR PSA 10 (multi-source slab: eBay + magi + Yahoo)
  • Mega Greninja ex SAR (SNKRDUNK + AI grade)
  • Umbreon ex SAR 217/187 (eBay + magi + Yahoo + AI grade)

REST API

All endpoints except health and sample data require a CC_LIVE_ API key.

# Auth: header or query param
-H "Authorization: Bearer CC_LIVE_xxxxx"# or?key=CC_LIVE_xxxxx

Full reference: api.casecomp.xyz/docs

# ── Public (no key) ──────────────────────────────────────────
curl "https://api.casecomp.xyz/api/sets"# browse 353 sets
curl "https://api.casecomp.xyz/api/sets?lang=en"# EN sets only
curl "https://api.casecomp.xyz/api/sets/sv06"# cards in a set
curl "https://api.casecomp.xyz/api/autocomplete?q=umbreon"# card search (29K cards)
curl "https://api.casecomp.xyz/api/health"# service status# ── Sample data (no key, ?demo=true) ─────────────────────────
curl "https://api.casecomp.xyz/api/search?q=Umbreon+ex+SAR+217/187&demo=true"
curl "https://api.casecomp.xyz/api/card/view/sv8a/217-187?demo=true"
curl "https://api.casecomp.xyz/api/arbitrage?q=Pikachu+ex+SAR+234/193+PSA+10&demo=true"
curl "https://api.casecomp.xyz/api/price-history?q=Umbreon+ex+SAR+217/187&days=90&demo=true"
curl "https://api.casecomp.xyz/api/portfolio?demo=true"
curl "https://api.casecomp.xyz/api/portfolio/set/sv8a?demo=true"# ── Authenticated (CC_LIVE_ key) ─────────────────────────────
curl -H "Authorization: Bearer $CASECOMP_KEY" \
"https://api.casecomp.xyz/api/search?q=Pikachu+ex+SAR&source=magi&format=slab&slab_provider=PSA&slab_grade=10"
curl -X POST -H "Authorization: Bearer $CASECOMP_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"you@email.com","query":"Umbreon ex SAR 217/187","type":"arbitrage","spreadThreshold":10}' \
"https://api.casecomp.xyz/api/alerts"

Rate limits

EndpointLimit
Authenticated (CC_LIVE_ key)60 req/min
Sample data (?demo=true)360 req/min
Health, docs, staticNo limit

Public endpoints (no key)

GET /api/health | GET /api/demo | GET /api/sitemap | GET /api/autocomplete | GET /api/sets | GET /api/sets/:setCode | GET /api/funnel | GET /docs | GET /docs/spec.json | ?demo=true (sample data) on search/sold/arbitrage/price-history

Security

  • Container signing - Sigstore cosign keyless signing via GitHub OIDC, logged to Rekor transparency log
  • Deploy by digest - immutable image SHA, not mutable :latest tag
  • SBOM attestation - Syft SPDX JSON generated from built container image, cosign-attested to image digest, also uploaded as build artifact
  • Vulnerability scanning - Grype scans SBOM for CVEs, SARIF uploaded to GitHub Security tab
  • SAST - CodeQL static analysis on every PR + weekly schedule
  • Binary Authorization - GCP policy enforced on both Cloud Run services
  • Reproducible builds - Kaniko --reproducible flag, pinned version
  • Multi-region - Cloud Run in asia-south1 + us-central1, global LB auto geo-routes to nearest
  • Custom base image - Wolfi + apko Node 24 image, manual rebuild, zero CVEs by design
  • RASP - runtime request inspection for SQLi, XSS, command injection, path traversal, NoSQL injection, prototype pollution. Per-IP anomaly scoring, bot fingerprinting, Firestore event logging
  • Supply chain - SLSA provenance attestation, Dependabot, lockfile-lint, Socket.dev, pre-commit secret blocking

Claude Code Skills

/casecomp - search for cards in plain English. Claude parses intent and runs the CLI with the right flags.

/casecomp Umbreon ex 217/187 PSA 10 japanese
/casecomp compare Pikachu VMAX alt art and Espeon VMAX alt art
/casecomp should I grade Mega Greninja ex SAR?
/casecomp Charizard ex on magi, condition A, 10 results

CLI

node index.js "Charizard ex"# raw eBay search
node index.js --format slab --slab-provider PSA "Pikachu VMAX"# PSA 10 slabs
node index.js --source magi --lang jp "Umbreon ex 217/187"# magi.camp JP
node index.js --grade "Mega Greninja ex SAR"# AI pre-grading
node index.js --grade-decision "Umbreon ex 217/187"# PSA break-even table

Flags

FlagExampleWhat
--formatslab / rawSlab vs raw (default: raw)
--slab-providerPSA, BGS, CGC, TAGGrading company
--slab-grade10, 9.5Grade number
--langeng, jp, eng,jpCard language filter
--sourcemagi, yahoo, snkrdunkListing source
--countriesUS,INShip-to countries
--results10Active listings count
--sold10Sold comps count
--gradeAI pre-grading
--grade-decisionPSA break-even table
--conditionA, nm, lp, mpCondition filter (SNKRDUNK A/B/C/D, eBay NM/LP, magi 状態A/美品)
--refreshClear cache
--parallelConcurrent card search

Environment

EBAY_CLIENT_ID= # required - developer.ebay.com
EBAY_CLIENT_SECRET= # required
ANTHROPIC_API_KEY= # AI grading + magi translation
PSA_AUTH_TOKEN= # PSA pop reports
CASECOMP_API_KEY= # API auth (CC_LIVE_ prefix)
CASECOMP_SANDBOX_KEY= # public sandbox key (CC_LIVE_SANDBOX_ prefix, 5/min)

In production, secrets are stored in GCP Secret Manager and referenced by Cloud Run.

Caching

All caches use Firestore (shared across Cloud Run instances, persists across deploys). Owner key gets stale-while-revalidate; third-party keys get isolated per-key caches.

CollectionTTLContent
cache-grades30 daysAI grade results by image hash
cache-psa-pop24 hoursPSA population data
cache-psa-specpermanentPSA spec ID lookups
cache-translationspermanentEN-to-JP card name translations
cache-ebay-active6 hourseBay active listing results
cache-ebay-sold24 hourseBay sold comp results
price-historypermanentSold comp prices over time
api-keyspermanentDeveloper API keys (hashed)
error-logs30 days (TTL)API errors with request IDs
card-database-cachepermanent (on-demand sync)TCGdex card index (~29K cards)
user-milestonespermanentUser funnel milestones (signup, first search, etc.)

Infrastructure

GCP (Terraform managed): Cloud Run casecomp-api (API) + casecomp-site (frontend SSR with Cloud CDN), Firestore, HTTPS LB, Secret Manager, Cloud Monitoring, Cloud Scheduler. Cloudflare handles SSL + edge caching for casecomp.xyz (~85ms TTFB). GCP managed SSL for api.casecomp.xyz. Same LB IP routes by host. Cloud Scheduler runs track-prices and check-alerts every 6 hours. See terraform/.

Chrome Extension

Queue auto-join for Pokemon Center, Walmart, Costco, Target drops. News monitoring from Discord, X, Reddit.

Load unpacked from extension/ in chrome://extensions.

Tests

488 tests across three layers. CI required checks: unit + codeql. Smoke is non-blocking.

SuiteCountCommandCovers
Unit313yarn test:unitFilters, grading, query builder, card identity, condition detection, image preprocessing, email alerts, portfolio ROI, CSV export, autocomplete, JWT auth, price trends, RASP detection
API104yarn test:apiSearch, sold, PSA, grade, auth, admin keys, arbitrage, price history, alerts, share pages, portfolio CRUD, card view, upload-url, analytics, collection tracking, lang filter, card-database sync
Smoke71yarn test:smokeAPI root page, detail panel, tabs, PSA stats, arbitrage, mobile viewport, portfolio, autocomplete, search filters

Contributing

Contributions welcome. Fork the repo, create a branch, and open a PR against dev. Run yarn test before submitting - all tests must pass.

For bug reports or feature requests, open an issue.

Terms of Use

Personal, non-commercial use only. Not for scalping, cook groups, or bulk purchasing. Full terms in LICENSE.

Disclaimer

AI grades are estimates from photos, not official PSA/CGC grades. Use as screening hints only.

About

Pokemon TCG card research - multi-source search, AI pre-grading (8 subgrades, shareable reports), price trends, portfolio tracking, set browser. SLSA 3, Sigstore signed, 0 CVEs.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages