================================================================================ REDMEFIXSES CONSERVATIVE TRIAGE ================================================================================ Source reviewed: redmeFIXSES.md Date: 2026-05-19 Mode: evaluation only; no application code changed. Principle used: If the site works and a change is not clearly safer, smaller, and worth the risk, do not do it. Prefer no-op/defer over broad refactors. Decision key: DO = worth doing later as a small, contained change DEFER = valid concern, but product/legal/infra/risky scope DO NOT = stale, already fixed, intentional, or too risky for current goal ================================================================================ SUMMARY ================================================================================ Items evaluated: 35 DO: 1.3 Registration rate limiting 5.2 Clarify dev vs dev:next because Socket.IO games need server.ts 5.3 Wire ESLint separately from TypeScript checking 6.1 Active nav state styling DEFER: 1.4 Password reset flow 1.5 Admin bootstrap/audit log 2.4 Ledger FK links to GameSession/GameRoom 2.5 Pong multi-instance/recovery architecture 3.4 Homepage meter vs boost meter product wording 3.6 Static FAQ vs dynamic FAQ source of truth 4.2 Casino/compliance review 4.3 Prediction oracle/fairness model 4.4 Initiative moderation queue 4.5 Email verification enforcement 6.2 Skeleton/loading polish 7.1 Unit test suite 7.2 Structured logging/APM 7.3 Webhook alerting DO NOT: 1.1 Socket userId trust issue 1.2 Socket CORS wildcard 1.6 Anonymous FAQ pending leak 2.1 Public stats vs treasury succeeded filter 2.2 Prediction bet transaction 2.3 Boost milestone race 3.1 FAQ API has no UI 3.2 Billboard API has no UI 3.3 Spotlight API has no UI 3.5 Cards API has no UI 4.1 Committee/legal placeholders 5.1 NEXT_PUBLIC_SITE_URL missing from .env.example 5.4 HSTS preload 5.5 Sitemap incomplete 6.3 DonationCheckout .env wording ================================================================================ ITEM-BY-ITEM DETERMINATION ================================================================================ 1.1 Socket.IO trusts browser userId Decision: DO NOT Current truth: This appears fixed. server.ts resolves the user from the auth token via resolveSocketUserId(), and CoinFlipRoom/PongGame emit only roomId on join. Why: The old redme claim is stale. Touching working socket auth now risks breaking coin flip and pong. 1.2 Socket.IO CORS origin "*" Decision: DO NOT Current truth: server.ts uses allowedOrigin from NEXT_PUBLIC_SITE_URL/AUTH_URL fallback, not wildcard. Why: Already fixed. No change. 1.3 Registration endpoint unthrottled Decision: DO Current truth: Still valid. /api/register is a plain POST handler. Worth it: Yes, but only as a small contained rate limiter. It reduces account spam and credential stuffing risk without changing normal user flows. Safe shape: Add an in-memory IP/email bucket first, or Cloudflare rate rule. Do not add CAPTCHA/email verification in the same change. 1.4 No automated password reset Decision: DEFER Current truth: Static forgot-password page only. Why defer: A real reset flow touches email delivery, tokens, auth UX, and support process. It is worth doing eventually, but not a safe quick patch while the site is working. 1.5 Admin bootstrap/audit log missing Decision: DEFER Current truth: Admin role exists; audit logging for admin actions is not a complete system. Why defer: Cross-cutting ops/security feature. Needs design. Do not bolt it on. 1.6 Public FAQ API leaks pending submissions Decision: DO NOT Current truth: Anonymous users get pending: []; signed-in users can see pending submissions for the FAQ board workflow. Why: The original public leak claim is stale. Making pending admin-only may break the current voting/board behavior unless product direction changes. 2.1 public stats vs treasury status filter mismatch Decision: DO NOT Current truth: Both current stats and treasury queries filter status: \"succeeded\". Why: Already fixed. 2.2 Prediction bets not transactional Decision: DO NOT Current truth: Prediction bet debit, ledger entry, bet create, and market total update are inside prisma.$transaction(). Why: Already fixed. 2.3 Movement boost milestone race Decision: DO NOT Current truth: Current boost route uses Serializable isolation and handles P2034 conflicts. Why: Good enough for current scale. Idempotency rows would add schema complexity. 2.4 Ledger not linked to GameSession/GameRoom Decision: DEFER Current truth: Valid. Game ledger lines are memo-linked, not FK-linked. Why defer: Requires Prisma migration and touching every game settlement path. Good long-term reconciliation work, but not worth risking a working wallet today. 2.5 Pong in-memory server state Decision: DEFER Current truth: Valid. Pong state lives in server.ts memory and assumes one Node process. Why defer: Redis/recovery would be a significant architecture change. Current service is single-instance, so do not change now. 3.1 FAQ API has no UI Decision: DO NOT Current truth: Stale. /faq-board fetches /api/faq. 3.2 Billboard API has no UI Decision: DO NOT Current truth: Stale. /billboard fetches /api/billboard. 3.3 Spotlight API has no UI Decision: DO NOT Current truth: Stale. /spotlight fetches /api/spotlight. 3.4 Movement boost meter vs homepage meter Decision: DEFER Current truth: /boost is wired. Homepage ProgressSection is a USD fundraising meter, not the BWT boost meter. Why defer: Not broken. This is copy/product clarity, not a code defect. 3.5 Cards API has no UI Decision: DO NOT Current truth: Stale. /cards fetches /api/cards. 3.6 Static FAQ and dynamic FAQ both exist Decision: DEFER Current truth: Valid. Homepage marketing FAQ and /faq-board dynamic FAQ coexist. Why defer: Product/source-of-truth decision. Both can coexist without breaking the site. 4.1 Committee/legal placeholders Decision: DO NOT Current truth: Valid placeholders remain. Why: This is deployment/legal configuration, not code. Do not invent legal copy. 4.2 Casino / prediction / games compliance Decision: DEFER Current truth: Valid concern. Why defer: Legal/jurisdiction scope. No autonomous code change is safe. 4.3 Prediction creator resolves outcome Decision: DEFER Current truth: Valid. Creator resolves market after close. Why defer: Oracle design is product/fairness architecture. Do not change while working. 4.4 User-generated initiatives moderation Decision: DEFER Current truth: Valid. Initiatives can be submitted without a moderator queue. Why defer: New moderation workflow and policy decisions needed. 4.5 Email verification unused Decision: DEFER Current truth: Valid. emailVerified exists in schema but credentials login does not enforce it. Why defer: Enforcing verification changes registration/login behavior. Risky without an email delivery plan. 5.1 NEXT_PUBLIC_SITE_URL missing in .env.example Decision: DO NOT Current truth: Fixed. .env.example includes NEXT_PUBLIC_SITE_URL. 5.2 dev vs dev:next confusion Decision: DO Current truth: Valid. npm run dev uses server.ts with sockets. npm run dev:next runs Next only and would break coin flip/pong sockets. Worth it: Yes. A README/package script description change is low-risk and prevents dev confusion. 5.3 lint only runs tsc Decision: DO Current truth: Valid. npm run lint is tsc --noEmit despite ESLint being installed. Worth it: Yes, if done as a separate script (for example typecheck + lint:eslint) so the existing working tsc path is not broken. 5.4 HSTS preload globally Decision: DO NOT Current truth: Valid, but intentional production security header. Why: Removing or env-gating it is unnecessary unless it causes a proven deployment issue. 5.5 Sitemap incomplete Decision: DO NOT Current truth: Mostly stale. Sitemap includes many major pages now. Casino auth pages are intentionally less SEO-oriented. Why: Not worth touching right now. 6.1 Active nav state Decision: DO Current truth: Valid. SiteNav/MobileNav do not appear to show current route state. Worth it: Yes, small isolated UX improvement if done carefully. 6.2 Loading shimmer coverage Decision: DEFER Current truth: Partial. Some loading states exist; skeleton polish is inconsistent. Why defer: Cosmetic and broad. Not worth risking layout churn. 6.3 DonationCheckout .env copy Decision: DO NOT Current truth: Stale/low-value. DonationCheckout is not the active checkout path and copy is already more production-friendly than the old note suggests. 7.1 No unit test suite Decision: DEFER Current truth: Valid. Why defer: Valuable, but not a quick no-risk change. Add tests around future bug fixes instead of inventing a full harness now. 7.2 No structured logging / APM Decision: DEFER Current truth: Valid. Why defer: Ops choice. Needs tool/vendor decision. 7.3 Webhook 500 / alerting Decision: DEFER Current truth: Valid. Stripe retries on 500; no alerting layer found. Why defer: Alerting belongs in ops/monitoring setup. Do not fake it in app code. ================================================================================ FINAL DETERMINATION ================================================================================ Do not perform a broad cleanup/refactor now. The app works and many redme items are stale. The only changes worth doing next are small and low-risk: 1. Add conservative registration rate limiting. 2. Clarify dev scripts so socket games are not started with dev:next. 3. Add ESLint as a separate script without replacing the current typecheck. 4. Add active nav styling. Everything else should be deferred or left alone unless it becomes a proven bug, legal requirement, or planned product change. ================================================================================