Skip to content

Sprint 2B — TimescaleDB, Data Quality, auto-sync match, augments#188

Merged
saggacce merged 14 commits into
mainfrom
develop
May 19, 2026
Merged

Sprint 2B — TimescaleDB, Data Quality, auto-sync match, augments#188
saggacce merged 14 commits into
mainfrom
develop

Conversation

@saggacce
Copy link
Copy Markdown
Owner

@saggacce saggacce commented May 19, 2026

Sprint PR — Sprint 2B

Cambios incluidos

TimescaleDB (#160)

  • Hypertables + compresión columnar en HeroKill, ObjectiveKill, WardEvent, Transaction, StructureDestruction
  • DB producción: 2.5 GB → 930 MB (63% reducción)
  • Cleanup mensual con drop_chunks(): minutos → milisegundos
  • Campo syncedAt añadido a tablas de event stream

Data Quality (#180)

  • Nueva fila "No sincronizable" — jugadores HIDDEN/consola separados del contador de re-sync
  • "Needs re-sync" ahora muestra solo jugadores realmente syncables (~10.858 vs 12.234 antes)
  • Botón "Verificar no sincronizables" en Data Controls — prueba muestra contra pred.gg y recupera los que ahora tienen datos

Auto-sync match (#181)

  • Al abrir un match con roster < 10 jugadores o sin event stream → sync automático
  • Evita scoreboards vacíos que parecen bugs

Augments / perks

  • Aumentos de héroe visibles en el scoreboard del Match Detail

Platform permissions system (#184)

  • Control de acceso configurable por rol desde Platform Admin
  • Permisos granulares por sección (teams, análisis, review queue, etc.)
  • Roles configurables: MANAGER, COACH, ANALISTA, JUGADOR

Fixes y mejoras

  • PermissionsPage — ruta activa con página real de permisos
  • Data attribution footer
  • Documentación de protocolo de migraciones de BD en Hetzner

Migraciones aplicadas en producción (antes del deploy)

MatchPlayer.perks — aplicado manualmente en Hetzner
✅ TimescaleDB hypertables + compresión — aplicado manualmente en Hetzner
syncedAt en tablas de event stream — backfill completado

Testing

Issue de testing: #189
Probar en staging (http://localhost:8080) antes de aprobar el deploy.

🤖 Generated with Claude Code

saggacce and others added 13 commits May 14, 2026 18:44
- 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>
@github-actions
Copy link
Copy Markdown

🧪 Testing requerido

Se ha creado el issue de testing: #189

Completa el checklist y cierra el issue antes de aprobar el deploy en producción.

#189

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +812 to +814
const synced = await syncPlayerByName(db, player.predggId, userToken);
if (synced && synced.displayName !== 'HIDDEN') {
recovered++;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment on lines +1519 to +1523
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)`,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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
@saggacce saggacce merged commit e2a0d30 into main May 19, 2026
5 checks passed
@saggacce saggacce deleted the develop branch May 19, 2026 21:28
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