James Chang / Projects / The Judge Tool / Roadmap & health
Judge Tool · Roadmap & health · Last Updated
Product health scorecard, risk register, roadmap.
8.0/10 overall health across six dimensions. Six tracked risks with mitigations. Short-term / medium-term / long-term roadmap with priority triage.
Health scorecard
Six dimensions, scored on intake and reviewed each session.
Architecture 9/10: Feature modules, barrel exports, clean separation.
Code quality 8/10: TypeScript strict, pure utils, tests for business logic.
Security 8/10: Auth guards in place, password hashing, rate limiting. Gaps: per-user PINs, CSP.
Testing 7/10: 113 unit tests, E2E simulation, zero browser tests.
Documentation 9/10: 15 docs in Diataxis framework, CLAUDE.md, build journal.
Tooling 7/10: Vitest, ESLint present. Missing: Playwright, Storybook, bundle analyzer.
Production readiness
Live phases auto-synced daily from docs/PRODUCTION_ROADMAP.md in the source repo.
Paid plans and billing
- Let organizers sign up with just their email
- Offer a few different paid plans through Stripe
- Let organizers pay for a single event, or subscribe for the season
- Keep billing status accurate automatically
- Let organizers view invoices and manage their subscription
- Track how much organizers are using the app
- A guided setup: create an account, pick a plan, pay, and run your first competition
Website and customer support
- A public website explaining what the app does, pricing, and stories from real customers
- Let people try the app before signing up
- A help center that walks organizers through setting up a competition and adding judges
- A way to reach support directly from the app
- Terms of service and a privacy policy
- A status page so organizers can check the app is working during events
- Automatic emails for welcome messages, password resets, and competition reminders
- Real stories from competitions that used the app
- Make the app easier to find in search results
Ideas for later
- An app judges can install on their phones that works without a signal
- Export final results and score sheets as a PDF
- Let organizers use their own logo and branding
- Connect with other competition management tools organizers already use
- Support for other languages as the app grows beyond the US
- Track a judge's history and reputation across competitions
- A step-by-step wizard that walks organizers through setting up a competition
Medium & long term
Medium term · 1–2 months
• Real-time score updates (L) — replace 15s polling with WebSocket/SSE [P2]
• Table Organizer role (L) — new role for logistics, boxes, distribution [P3]
• Competition templates (M) — save and reuse competition configurations [P3]
• PDF score reports (M) — downloadable standings + judge scorecards [P2]
• Offline judge mode (XL) — service worker + IndexedDB for offline scoring [P3]
Long term · 3–6 months
• Multi-competition management (XL) — dashboard for concurrent events [P3]
• Sanctioning body API integration (XL) — direct integration with competition management systems [P3]
• Mobile native app (XL) — React Native with push, offline, scanning [P3]
• Analytics dashboard (L) — historical trends, judge consistency, outlier detection [P3]
Risk register
Six tracked risks with mitigations. Impact x Likelihood scoring, updated per session.
R-1 · In-memory rate limiter ineffective on Vercel serverless
Impact: Medium · Likelihood: High
Mitigation: Redis migration planned (ST-2).
R-2 · Shared judge PIN allows impersonation
Impact: High · Likelihood: Medium
Mitigation: PIN now bcrypt-hashed. Per-user PINs planned (ST-1). Seat selection is weak identity today.
R-3 · JWT role not re-validated against DB
Impact: Medium · Likelihood: Low
Mitigation: 24h token expiry limits the window. Critical actions should re-check DB (ST-4).
R-4 · No CSP headers configured
Impact: Medium · Likelihood: Low
Mitigation: OWASP headers present. CSP planned (ST-3). No user-generated content reduces XSS surface.
R-5 · Prisma v5 pinned — no patches from v7
Impact: Medium · Likelihood: Low
Mitigation: Next.js 14 incompatible with Prisma v7 node: imports. Will migrate when moving to Next.js 15.
R-6 · Single Supabase instance — no read replicas
Impact: Low · Likelihood: Low
Mitigation: Connection pooling enabled. Single competition doesn't need replicas yet.
Findings history
Ten critical issues caught and fixed during the 20-day build. All closed.
- F-1 (P1): Auth guards missing from server actions — all 62 actions had no guards. Fixed Mar 9 — created
auth-guards.tswithrequireAuth/Organizer/Judge/Captain. - F-2 (P1): Client-supplied user IDs in actions (IDOR). Fixed Mar 9 — derived user IDs from session context.
- F-3 (P1): DB writes not in transactions. Fixed Mar 9 — wrapped all mutations in
prisma.$transaction. - F-4 (P1): DQ edge cases in tabulation. Fixed Mar 11 — E2E simulation found 3 bugs unit tests missed.
- F-5 (P1): No rate limiting on login (4-digit PIN brute-force). Fixed Mar 10 — added 5/15min sliding window.
- F-6 (P2): Missing ARIA labels. Fixed Mar 10 — WCAG pass: ARIA, keyboard nav, focus management.
- F-7 (P1): Captain couldn't verify table ownership. Fixed Mar 9 — added
table.captainId === userIdcheck. - F-8 (P2): Monolithic 1,200-line action file. Fixed Mar 11 — split into 6 focused files.
- F-9 (P2): shadcn v4 generates Tailwind v4 code. Fixed Mar 6 — use
npx shadcn@1. - F-10 (P2): Prisma v7 incompatible with Next.js 14. Fixed Mar 6 — pin to Prisma v5 (documented in
CLAUDE.md).