Files
democratic-money/REDME-FIXSES-TRIAGE.txt
root 7eac42e820 Legal pages, Threads OAuth, live wallet pill, PvP money flow + resume
- Legal: /privacy-policy and /datadeletion (shared LegalPageLayout, footer
  links, sitemap + integration tests, NEXT_PUBLIC_LEGAL_CONTACT_EMAIL).
- Threads OAuth: server-side /api/threads-exchange and /threads-callback
  page (Suspense + client component, noindex, no leaked secrets).
- Username + live wallet pill in top nav. New NavWalletBalance component
  polls /api/wallet, refreshes on tab focus, and listens to the
  `wallet:refresh` event bus so cash-outs and refunds update the nav in
  real time. Flash animation on balance changes.
- useLiveWalletBalance hook now broadcasts `wallet:refresh` after every
  fetch so games, exchange panel, wallet actions, and nav all stay in
  sync without extra polling.
- PvP fund-locking (`POST /api/games/rooms`): creator funds debited
  atomically with room creation; ledger entry tagged with `gameRoomId`.
  Joiner debit happens at join. Old double-debit of the creator is gone.
- DELETE /api/games/rooms?id=... lets a creator cancel a WAITING room
  and get an idempotent refund. Coin Flip + Pong waiting screens show a
  Cancel & Refund button.
- Pong/Coin Flip recovery: expiry sweep + boot-time `recoverOrphaned
  RoomsOnBoot()` (runs before listen()) refund both parties for any
  ACTIVE/expired rooms so a server restart never strands locked credits.
- Schema migration `20260520000000_game_ledger_links` adds optional
  `gameSessionId` + `gameRoomId` FKs to LedgerEntry (with indexes) and
  extra indexes on GameSession/GameRoom for resume + sweep queries.
- GET /api/games/active returns a user's active solo session + open
  rooms (sanitized — no mine/bomb positions). Mines and Tower clients
  rehydrate on mount so a refresh mid-round resumes instead of dropping.
- ActiveGamesBanner surfaces unfinished rounds on /wallet and /casino
  with Resume / Rejoin / Cancel & refund actions.
- ExchangePanel unified with useLiveWalletBalance; per-game header gets
  an "Open wallet →" chip; Dice clears stale result on roll; Blackjack
  reveals full dealer hand on natural blackjack/push; Mines refund
  label fixed; Tower final multiplier fixed; GameHistory error path;
  Prediction "Resolved" tab.
- Site audit + redmeFIXES triage notes (REDME-FIXSES-TRIAGE.txt,
  SITE-AUDIT.txt).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 06:43:26 +00:00

323 lines
9.8 KiB
Plaintext

================================================================================
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.
================================================================================