Conversation
- Add syncedAt DateTime column to HeroKill, ObjectiveKill, WardEvent, Transaction, StructureDestruction - Backfill syncedAt from Match.startTime for existing data - Convert tables to TimescaleDB hypertables (composite PK id+syncedAt) - Enable auto-compression policy for chunks older than 1 month - cleanupOldData() uses drop_chunks() instead of DELETE (ms vs minutes) - HeroBan kept as regular table (small, not worth converting) Closes #160 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New 'No sincronizable' row (HIDDEN + console) separate from stale count - playerPct now based on syncable players only (excludes unsyncable) - POST /admin/verify-nonsyncable: tests sample against pred.gg, recovers players that now have data and moves them to syncable - 'Verificar no sincronizables' button in Data Controls Closes #180 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…sole) Fixes inflated 'No sincronizable' count. Now shows only the ones that are dragging down the re-sync counter (stale AND can't be synced), not all console/HIDDEN players regardless of sync status. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Console/HIDDEN players have lastSynced updated by match sync but have no real pred.gg profile. They must always be in 'No sincronizable' regardless of lastSynced timestamp. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Store the 3 pre-game augments (HERO_SPECIFIC_1, COMMON_1, COMMON_2) per MatchPlayer and display them in the Scoreboard tab alongside items. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents the ALTER TABLE workflow required before approving deploys when schema changes involve TimescaleDB hypertables. Includes pending migrations table tracking columns not yet applied to production. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat: augments (hero-specific perks) in Match Detail scoreboard
…mplete Extends the auto-sync trigger to cover three cases: - rosterSynced=false or fewer than 10 players stored - all players have perks=null (matches synced before augments feature) - eventStreamSynced=false (existing behavior) Closes #181 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat: auto-sync match on open when roster, perks or event stream incomplete
Adds a fine-grained permission system (52 permissions across 5 roles) configurable by PLATFORM_ADMIN. Introduces SUPER_ADMIN role with immutable full access. - PermissionsConfig table (single global row, JSONB) - GET/PUT/POST /admin/permissions API endpoints - PermissionsProvider context + usePermissions hook - Platform Admin → Roles & Permissions page with basic/advanced toggle table - Default permissions seeded for all roles Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove external image fallback in HeroAvatar — local assets only, initials shown when image is missing (no hotlinking to omeda.city) - Add attribution footer in sidebar: pred.gg and omeda.city credited as data sources with links - Fix duplicate /management/roles route (ComingSoon was shadowing PermissionsPage) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
chore: data attribution footer + remove omeda.city hotlink
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a279352468
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const synced = await syncPlayerByName(db, player.predggId, userToken); | ||
| if (synced && synced.displayName !== 'HIDDEN') { | ||
| recovered++; |
There was a problem hiding this comment.
Clear console flag when recovering non-syncable players
This recovery path increments recovered based only on displayName !== 'HIDDEN', but unsyncable players are also defined by isConsole = true; for those players, syncPlayerByName does not reset isConsole, so they can be reported as recovered while still remaining unsyncable and excluded from normal stale re-sync flow. This is reproducible for any previously-console player that now resolves on pred.gg.
Useful? React with 👍 / 👎.
| db.$executeRaw`SELECT drop_chunks('"HeroKill"', ${cutoff}::timestamptz)`, | ||
| db.$executeRaw`SELECT drop_chunks('"ObjectiveKill"', ${cutoff}::timestamptz)`, | ||
| db.$executeRaw`SELECT drop_chunks('"WardEvent"', ${cutoff}::timestamptz)`, | ||
| db.$executeRaw`SELECT drop_chunks('"Transaction"', ${cutoff}::timestamptz)`, | ||
| db.$executeRaw`SELECT drop_chunks('"StructureDestruction"', ${cutoff}::timestamptz)`, |
There was a problem hiding this comment.
Align chunk deletion with match-retention cutoff
These drop_chunks calls delete by hypertable time (syncedAt), but the retention target is computed from Match.startTime; if an old match was synced recently, its event rows will not be dropped here, and the later deleteMany on old matches can fail on remaining required matchId foreign-key references from event tables. This can break the cleanup job instead of pruning old data.
Useful? React with 👍 / 👎.
feat: platform permissions system — fine-grained role access control
Sprint PR — Sprint 2B
Cambios incluidos
TimescaleDB (#160)
drop_chunks(): minutos → milisegundossyncedAtañadido a tablas de event streamData Quality (#180)
Auto-sync match (#181)
Augments / perks
Platform permissions system (#184)
Fixes y mejoras
Migraciones aplicadas en producción (antes del deploy)
✅
MatchPlayer.perks— aplicado manualmente en Hetzner✅ TimescaleDB hypertables + compresión — aplicado manualmente en Hetzner
✅
syncedAten tablas de event stream — backfill completadoTesting
Issue de testing: #189
Probar en staging (
http://localhost:8080) antes de aprobar el deploy.🤖 Generated with Claude Code