Skip to content

feat: implement phase1 table-result, wins/losses and rating layer in race-facade#22

Open
spozitivom wants to merge 2 commits intomasterfrom
feature/facade-phase1-result-rating-layer
Open

feat: implement phase1 table-result, wins/losses and rating layer in race-facade#22
spozitivom wants to merge 2 commits intomasterfrom
feature/facade-phase1-result-rating-layer

Conversation

@spozitivom
Copy link
Copy Markdown
Collaborator

@spozitivom spozitivom commented Apr 8, 2026

Summary

This PR adds the Phase 1 result layer on top of the existing centralized product write foundation in race/facade.

It introduces a canonical table_result_recorded path for:

  • wins / losses
  • simple Phase 1 rating updates
  • centralized rank_bucket recalculation
  • idempotent result processing

The architecture remains consistent with the previous foundation work:

  • normalized product events
  • centralized processing in product_event_service
  • shared rules in product_rules
  • storage compatibility across Postgres and sqlite fallback

What changed

  • added GuestTableResultRecorded to the normalized product event model
  • added centralized result classification rules:
    • strong_positive
    • moderate_positive
    • neutral
    • moderate_negative
    • strong_negative
  • added stats writes through the event processor:
    • positive result -> wins +1
    • negative result -> losses +1
    • neutral result -> no wins/losses change
  • added Phase 1 rating rules:
    • minimum hands guard
    • minimum session duration guard
    • minimum opponents guard
    • fixed deltas per result category
    • minimum rating floor
    • centralized rank_bucket recalculation
  • extended the store abstraction so both sqlite fallback and Postgres-backed product storage support:
    • wins/losses writes
    • user_rating updates
  • added an explicit internal/test ingestion RPC for result events:
    • internal_guest_table_result_recorded

What is not included

This PR does not add:

  • leaderboard logic
  • seasonal ladders or resets
  • advanced MMR / Elo / Glicko
  • matchmaking changes
  • rewards / missions / VIP / NFT modifiers
  • wallet-link-specific rating rules
  • forced runtime hookup from an unstable facade event source

table_result_recorded is production-architected, but current runtime wiring remains intentionally deferred until there is a stable and unambiguous source of truth.

Test plan

Verified locally:

cargo build -p race-facade
cargo test -p race-facade -- --nocapture

Coverage includes:

  • positive result classification
  • negative result classification
  • neutral result classification
  • positive result -> wins +1
  • negative result -> losses +1
  • neutral result -> no wins/losses
  • eligible result -> rating delta applied
  • non-eligible result -> stats update without rating change
  • rating floor guard
  • duplicate result event protection
  • explicit internal ingestion path for result events
  • existing join/hand/session foundation path still green

Risks / follow-ups

  • result ingestion is currently explicit internal/test wiring, not full production runtime wiring
  • future runtime hookup for table_result_recorded must only be added when there is a stable source of truth
  • advanced ranking, leaderboards, and seasonal systems should build on this same processor path rather than bypassing it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant