{"id":48946629,"url":"https://github.com/hariharanragothaman/resumerpg","last_synced_at":"2026-04-17T17:05:33.943Z","repository":{"id":346657337,"uuid":"1187759973","full_name":"hariharanragothaman/ResumeRPG","owner":"hariharanragothaman","description":"Transform your GitHub profile into a legendary RPG character card. Deterministic scoring, percentile rankings across 10K+ developers, anti-gaming hardened.","archived":false,"fork":false,"pushed_at":"2026-03-24T21:01:55.000Z","size":450,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-26T01:55:54.389Z","etag":null,"topics":["developer-tools","gamification","github","open-source","react","rpg","supabase","typescript"],"latest_commit_sha":null,"homepage":"https://gitrpgcard.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hariharanragothaman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-21T05:50:32.000Z","updated_at":"2026-03-24T21:01:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hariharanragothaman/ResumeRPG","commit_stats":null,"previous_names":["hariharanragothaman/resumerpg"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/hariharanragothaman/ResumeRPG","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hariharanragothaman%2FResumeRPG","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hariharanragothaman%2FResumeRPG/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hariharanragothaman%2FResumeRPG/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hariharanragothaman%2FResumeRPG/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hariharanragothaman","download_url":"https://codeload.github.com/hariharanragothaman/ResumeRPG/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hariharanragothaman%2FResumeRPG/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31937744,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-17T12:37:54.787Z","status":"ssl_error","status_checked_at":"2026-04-17T12:37:25.095Z","response_time":62,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["developer-tools","gamification","github","open-source","react","rpg","supabase","typescript"],"created_at":"2026-04-17T17:05:32.901Z","updated_at":"2026-04-17T17:05:33.932Z","avatar_url":"https://github.com/hariharanragothaman.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ⚔️ ResumeRPG\n\n**A developer indexing and ranking platform, disguised as an RPG character card generator.**\n\nResumeRPG transforms GitHub profiles and resumes into interactive RPG character cards with deterministic stats, percentile rankings across thousands of indexed developers, embeddable README badges, social-preview card images, and head-to-head duel mode. Every GitHub user has a card page at `/:username` — no login, no API key, no friction.\n\n**Live:** [resumerpg-production.up.railway.app](https://resumerpg-production.up.railway.app)\n\n## How It Works\n\n1. **GitHub path (viral):** Visit `/:username` → server fetches profile + repos from GitHub API → deterministic stat calculation → Supabase cache → percentile ranking among all indexed developers. No AI needed.\n2. **Resume path (AI):** Upload PDF or paste text → Claude/GPT parses experience into an RPG character sheet → holographic card with export and share.\n3. **Seed script:** Bulk-indexes top GitHub developers by follower count for realistic percentile baselines. 10K developers gives \"Top 5% of 10,000\" — a credible, shareable stat.\n\n## Architecture\n\n### System Overview\n\n```mermaid\ngraph TB\n    subgraph Client[\"Browser — React + Vite\"]\n        Landing[\"Landing Page\u003cbr/\u003e(example cards hero)\"]\n        CardPage[\"/:username\u003cbr/\u003eGitHubCardPage\"]\n        DuelPage[\"/:username/vs/:other\u003cbr/\u003eGitHubComparePage\"]\n        ResumeParse[\"Resume Upload\u003cbr/\u003e(PDF / paste)\"]\n        Export[\"Canvas → PNG Export\"]\n    end\n\n    subgraph Server[\"Express API — server/index.js\"]\n        GHAPI[\"/api/gh/:username\"]\n        ResumeAPI[\"/api/parse-resume-text\"]\n        ShareAPI[\"/api/share\"]\n        Badge[\"/:username/badge.svg\"]\n        CardPNG[\"/:username/card.png\"]\n        OGMeta[\"OG Meta Injection\u003cbr/\u003e(server-side)\"]\n        RateLimiter[\"Rate Limiter\u003cbr/\u003e10 gen/hr per IP\"]\n    end\n\n    subgraph External[\"External Services\"]\n        GitHub[\"GitHub API\u003cbr/\u003e(profile + repos)\"]\n        Claude[\"Anthropic Claude\"]\n        Supabase[\"Supabase Postgres\u003cbr/\u003e(github_cards, cards)\"]\n    end\n\n    subgraph Seed[\"scripts/seed.js\"]\n        Discovery[\"GitHub Search API\u003cbr/\u003e(discover top users)\"]\n        BatchUpsert[\"Batch upsert\u003cbr/\u003e(25 per batch)\"]\n        Recalc[\"recalc_percentiles()\"]\n    end\n\n    Landing --\u003e CardPage\n    CardPage --\u003e GHAPI\n    DuelPage --\u003e GHAPI\n    ResumeParse --\u003e ResumeAPI\n    ResumeAPI --\u003e RateLimiter --\u003e Claude\n    GHAPI --\u003e GitHub\n    GHAPI --\u003e Supabase\n    Badge --\u003e Supabase\n    CardPNG --\u003e Supabase\n    OGMeta --\u003e Supabase\n    CardPage --\u003e Export\n    Discovery --\u003e GitHub\n    BatchUpsert --\u003e Supabase\n    Recalc --\u003e Supabase\n```\n\n### Data Flow: GitHub Card (Viral Path)\n\n```mermaid\nsequenceDiagram\n    participant U as User / Social Crawler\n    participant S as Express Server\n    participant GH as GitHub API\n    participant DB as Supabase\n    participant R as React SPA\n\n    U-\u003e\u003eS: GET /torvalds\n    S-\u003e\u003eS: OG meta injection (og:image → /torvalds/card.png)\n    S--\u003e\u003eU: HTML with social preview meta tags\n    U-\u003e\u003eR: SPA renders GitHubCardPage\n    R-\u003e\u003eS: GET /api/gh/torvalds\n    S-\u003e\u003eDB: Check github_cards cache\n    alt Cache hit (\u003c 24h)\n        DB--\u003e\u003eS: Cached character + percentiles\n    else Cache miss or stale\n        S-\u003e\u003eGH: GET /users/torvalds + /repos\n        GH--\u003e\u003eS: Profile + repos JSON\n        S-\u003e\u003eS: calculateStats() → deterministic\n        S-\u003e\u003eDB: Upsert github_cards row\n        S-\u003e\u003eDB: recalc_percentiles() (async)\n    end\n    S--\u003e\u003eR: { character, percentiles, meta }\n    R-\u003e\u003eR: Render card + percentile badges + CTA\n```\n\n### Route Map\n\n| Route | Component / Handler | Description |\n|-------|-------------------|-------------|\n| `/` | `HomePage` | Landing hero with example cards, theme picker, generate/gallery/compare tabs |\n| `/:username` | `GitHubCardPage` | Public GitHub card with percentiles, export, share, duel link, \"What's YOUR card?\" CTA |\n| `/:username/vs` | `GitHubComparePage` | Duel mode input form |\n| `/:username/vs/:other` | `GitHubComparePage` | Head-to-head radar chart + side-by-side cards |\n| `/share/:id` | `SharePage` | View a shared resume-based card |\n| `/privacy` | `PrivacyPage` | Privacy policy |\n| `/api/gh/:username` | Express | GitHub card JSON API |\n| `/api/gh/:username/vs/:other` | Express | Duel comparison API |\n| `/api/gh-stats` | Express | Global cohort stats (total cards, avg power) |\n| `/api/parse-resume-text` | Express | Resume → AI → character JSON |\n| `/api/share` | Express | Save shared card |\n| `/:username/badge.svg` | Express | Embeddable SVG badge for README |\n| `/:username/card.png` | Express | PNG card image for social previews |\n| `/api/health` | Express | Health check endpoint |\n\nLegacy `/gh/:username/badge.svg` and `/gh/:username/card.png` return 301 redirects to the new paths.\n\n## Features\n\n| Feature | Description |\n|---------|-------------|\n| **GitHub Cards** | `/:username` — deterministic RPG card from public GitHub data. Cached 24h in Supabase. No AI, no API key needed. |\n| **Percentile Rankings** | Stats ranked across all indexed developers. Seed 10K for \"Top 5% of 10,000 developers.\" |\n| **Social Previews** | Server-side OG meta injection — sharing a card link on Twitter/Slack/Discord shows the card image automatically |\n| **Dynamic Titles** | Browser tab shows `@username — Lv.X ClassName | ResumeRPG` |\n| **README Badges** | `/:username/badge.svg` — embeddable badge with level, class, and rarity |\n| **Card Images** | `/:username/card.png` — server-rendered PNG via sharp for social preview and export |\n| **Duel Mode** | `/:username/vs/:other` — radar chart comparison with shareable results |\n| **Viral CTA** | \"What's YOUR card?\" input on every card page converts viewers into users |\n| **Landing Hero** | Homepage shows 3 example cards (Torvalds, Abramov, Sorhus) + cohort count |\n| **AI Resume Parsing** | Claude or GPT converts resume text into structured RPG character |\n| **5 Visual Themes** | Dark Fantasy, Cyberpunk, Pixel Art, Anime, Corporate — fonts, colors, particles |\n| **3D Holographic Card** | Mouse-tracking tilt, holographic shimmer, click to flip front/back |\n| **Trading Card Export** | 750×1050 PNG with stats, skills, QR code — sized for physical printing |\n| **Gallery** | Saved characters in localStorage with load/delete |\n| **Compare Mode** | Side-by-side radar chart comparison of resume-based characters |\n| **BYOK** | Client-side API key (sessionStorage) when server has no key configured |\n| **Rate Limiting** | 10 gen/hr, 30 share/hr per IP (configurable) |\n| **Seed Script** | Bulk-index top GitHub developers for realistic percentile baselines |\n\n## Power Profile Stats\n\n| Stat | Resume (AI) | GitHub (Deterministic) |\n|------|-------------|----------------------|\n| **IMPACT** | Leadership, team size, business outcomes | Stars, forks, repo count |\n| **CRAFT** | Technical depth, education, certifications | Language count, repo count, recent activity |\n| **RANGE** | Breadth of skills, cross-domain versatility | Language diversity, multi-language repos |\n| **TENURE** | Years of experience, career consistency | Years since oldest repo, repo count |\n| **VISION** | Strategic thinking, architecture decisions | Star concentration, top repo quality, bio |\n| **INFLUENCE** | Community presence, speaking, awards | Followers, follower/following ratio, company |\n\nEach stat is scored 1–20. Total power (max 120) determines rarity: Common (\u003c 40), Uncommon (40–54), Rare (55–74), Epic (75–94), Legendary (95+).\n\n## Project Structure\n\n```\nResumeRPG/\n├── server/\n│   ├── index.js              # Express — routes, CORS, rate limiting, OG meta injection, SPA serving\n│   └── lib/\n│       ├── github-cards.js   # GitHub fetch, deterministic stats, Supabase cache, percentiles\n│       ├── badge.js          # SVG badges for README embeds\n│       └── card-image.js     # PNG card image via sharp for social previews\n├── scripts/\n│   └── seed.js              # Bulk GitHub user indexer (discovery → fetch → generate → upsert)\n├── supabase/\n│   └── migrations/\n│       ├── 001_create_cards.sql   # Shared resume cards table\n│       ├── 002_github_cards.sql   # GitHub cards table + percentile RPC + stats view\n│       └── 003_increment_rpc.sql  # access_count increment helper\n├── src/\n│   ├── App.tsx               # React Router — /, /privacy, /share/:id, /:username, /:username/vs\n│   ├── components/\n│   │   ├── CardFront.tsx      # Front face — avatar, stats, skills, QR\n│   │   ├── CardBack.tsx       # Back face — lore, inventory, quests, boss battles\n│   │   ├── HolographicCard.tsx# 3D tilt + flip wrapper with ResizeObserver\n│   │   ├── CompareView.tsx    # Radar chart + side-by-side cards\n│   │   ├── GalleryView.tsx    # Saved characters list\n│   │   ├── StatBar.tsx        # Animated stat bar (theme-aware)\n│   │   ├── Particles.tsx      # Rising particle effects\n│   │   ├── Starfield.tsx      # Background star animation\n│   │   └── Layout.tsx         # Shell — fonts, animations, theme background, footer\n│   ├── lib/\n│   │   ├── api.ts             # AI provider calls, system prompt, normalizer\n│   │   ├── config.ts          # Themes, class/rarity config, stat names\n│   │   ├── export.ts          # Canvas trading card renderer\n│   │   ├── pdf.ts             # Client-side PDF extraction via pdf.js\n│   │   ├── share.ts           # QR generation, share encoding\n│   │   ├── siteUrl.ts         # Canonical URL helper (VITE_PUBLIC_SITE_URL)\n│   │   └── storage.ts         # localStorage persistence\n│   ├── pages/\n│   │   ├── HomePage.tsx       # Landing hero + tabs (generate, gallery, compare)\n│   │   ├── GitHubCardPage.tsx # GitHub card + percentiles + CTA + embed snippet\n│   │   ├── GitHubComparePage.tsx # Duel mode — radar + cards + CTA\n│   │   ├── SharePage.tsx      # Shared character viewer\n│   │   └── PrivacyPage.tsx    # Privacy policy\n│   └── types/\n│       └── character.ts       # TypeScript interfaces (CharacterSheet, StatBlock, etc.)\n├── index.html                # Default OG meta tags (replaced server-side per route)\n├── railway.json              # Railway deployment config\n├── DEPLOYMENT.md             # Production deployment checklist\n└── package.json\n```\n\n## Quick Start\n\n```bash\nnpm install\ncp .env.example .env          # add keys (see below)\nnpm run dev\n```\n\n- **Web:** http://localhost:5173\n- **API:** http://127.0.0.1:8787 (proxied as `/api/*` from Vite)\n\nUse **`npm run dev`** (not `dev:web`) so API routes and `/:username` pages work.\n\n**Supabase is optional locally:** GitHub cards are cached in server RAM without it (no percentile rankings until you add Supabase + migrations 001–003).\n\n**No server AI key?** Resume generation falls back to BYOK in the UI. GitHub cards need **no** AI key (stats are deterministic).\n\n## Seeding the Database\n\nThe seed script bulk-indexes top GitHub developers for realistic percentile rankings.\n\n```bash\n# Requires GITHUB_TOKEN, SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY in .env\n\nnpm run seed:small     # 1,000 users (~25 min)\nnpm run seed           # 10,000 users (~4 hours)\nnpm run seed:resume    # Resume from where you left off\n```\n\n**How it works:**\n1. **Discovery** — GitHub Search API finds top users by follower count across 28 ranges\n2. **Fetch + Generate** — Profile + repos → deterministic character (same logic as server)\n3. **Batch upsert** — Every 25 users, upserts into `github_cards` (safe to re-run)\n4. **Percentile recalc** — Calls `recalc_percentiles()` at the end\n\n**Safety:** Resumable via `scripts/.seed-progress.json`, auto-sleeps on rate limit, progress reports every 50 users. Use `--dry-run` to test without writing to Supabase.\n\n## Production Deployment (Railway)\n\nSee **[DEPLOYMENT.md](./DEPLOYMENT.md)** for the full checklist.\n\n### Short version\n\n1. **Supabase** — Run migrations `001` → `002` → `003` in the SQL Editor\n2. **Railway** — Deploy from GitHub; Nixpacks runs `npm ci` then `npm run build`; start runs `node server/index.js`\n3. **Env vars** — `NODE_ENV=production`, `SUPABASE_URL`, `SUPABASE_SERVICE_ROLE_KEY`, `ALLOWED_ORIGINS`, `ANTHROPIC_API_KEY`, `GITHUB_TOKEN`, `VITE_PUBLIC_SITE_URL`\n4. **Seed** — Run `npm run seed:small` locally to populate the cohort\n\n## Scripts\n\n| Script | Description |\n|--------|-------------|\n| `npm run dev` | Vite + Express API together (dev) |\n| `npm run build` | TypeScript check + Vite production build |\n| `npm start` | Production server (serves built client + API) |\n| `npm run lint` | ESLint |\n| `npm run seed` | Seed 10,000 GitHub developers into Supabase |\n| `npm run seed:small` | Seed 1,000 developers (~25 min) |\n| `npm run seed:resume` | Resume interrupted seed run |\n\n## Environment Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `ANTHROPIC_API_KEY` | For AI resume parsing | — | Claude API key |\n| `SUPABASE_URL` | For production | — | Supabase project URL |\n| `SUPABASE_SERVICE_ROLE_KEY` | For production | — | Supabase service role key (server only) |\n| `ALLOWED_ORIGINS` | In production | — | Comma-separated allowed CORS origins |\n| `NODE_ENV` | In production | — | Set to `production` |\n| `PORT` | No | `8787` | Server port (Railway sets this) |\n| `VITE_PUBLIC_SITE_URL` | Recommended | — | Canonical `https://` URL for badges, QR codes, OG tags (set before build) |\n| `PUBLIC_SITE_URL` | Optional | `https://resumerpg.app` | Server PNG card footer |\n| `GITHUB_TOKEN` | Recommended | — | GitHub PAT — 5K req/hr vs 60/hr anonymous |\n| `ANTHROPIC_MODEL` | No | `claude-sonnet-4-6` | Model for resume parsing |\n| `RATE_LIMIT_GENERATE` | No | `10` | Max generations per IP per hour |\n| `RATE_LIMIT_SHARE` | No | `30` | Max shares per IP per hour |\n\n## Tech Stack\n\n**Frontend:** React 19, TypeScript, Vite 6, Recharts, React Router 7, pdf.js (CDN)\n**Backend:** Express 4, Supabase JS v2, Anthropic SDK, sharp, multer, pdf-parse\n**AI:** Claude Sonnet 4.6 (Anthropic) / GPT-4.1 (OpenAI) — resume path only\n**Database:** Supabase Postgres (github_cards with percentile RPCs, shared resume cards)\n**Deployment:** Railway (Nixpacks), Supabase hosted Postgres\n**Storage:** localStorage (gallery), sessionStorage (BYOK API keys)\n\n## License\n\nPrivate / TBD.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhariharanragothaman%2Fresumerpg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhariharanragothaman%2Fresumerpg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhariharanragothaman%2Fresumerpg/lists"}