Skip to content

feat(cosmetics): add EXCLUSIVE tier and per-user cosmetic assignment - #57

Merged
diangogav merged 1 commit into
mainfrom
feat/exclusive-cosmetic-tier
Jun 22, 2026
Merged

feat(cosmetics): add EXCLUSIVE tier and per-user cosmetic assignment#57
diangogav merged 1 commit into
mainfrom
feat/exclusive-cosmetic-tier

Conversation

@diangogav

Copy link
Copy Markdown
Owner

Qué

Agrega un tier de cosmetic EXCLUSIVE y el mecanismo para asignar un cosmetic exclusivo a un usuario puntual.

Por qué

El control de acceso es tierGrants(userTier, cosmetic.tier) || cosmeticIds.has(cosmetic.id), y el gatekeeper sólo asigna STANDARD/REGISTERED/DONOR. Como el tier más bajo (STANDARD) es universal, ningún tier existente puede expresar un cosmetic verdaderamente exclusivo — cualquiera de los tres se lo regala a una clase entera de usuarios. EXCLUSIVE rankea por encima de DONOR, así que ningún tier de usuario lo otorga: el único acceso es un entitlement COSMETIC per-usuario.

Cambios

  • CosmeticTier.EXCLUSIVE + entrada en RANK (rank 3) en accessTier
  • Migración que agrega el valor EXCLUSIVE a cosmetic_tier_enum (el seed se difiere: el valor nuevo no se puede usar en la misma transacción)
  • Seed del companion Terminator con tier EXCLUSIVE
  • Script assign-cosmetic para otorgar un cosmetic a un usuario vía entitlement COSMETIC (idempotente, resuelve el cosmetic por assetRef, todos los argumentos obligatorios)

Flujo

bun run migration:cosmetics:run
bun run seed:cosmetics
bun run assign:cosmetic <userId> <assetRef> <source>

⚠️ Pendiente antes de seedear

La animación del Terminator en standardCosmetics.ts tiene placeholders TODO_* (clips y rigFile). El seed es insert-only: si se seedea con esos valores, arreglarlos después requiere una migración de datos. Reemplazar con los nombres reales de los clips y el rig del .glb antes de correr seed:cosmetics.

Add an EXCLUSIVE cosmetic tier that ranks above every user tier the
gatekeeper can assign (STANDARD/REGISTERED/DONOR), so no tier ever
grants it. Access to an EXCLUSIVE cosmetic comes solely from a per-user
COSMETIC entitlement.

- CosmeticTier.EXCLUSIVE + RANK entry (rank 3) in accessTier
- migration adding the EXCLUSIVE value to cosmetic_tier_enum (seeding
  deferred, value cannot be used in the same transaction)
- seed the Terminator EXCLUSIVE companion (animation clips/rig still TODO)
- assign-cosmetic script to grant a cosmetic to a single user via a
  COSMETIC entitlement (idempotent, resolves cosmetic by assetRef)
@diangogav diangogav self-assigned this Jun 22, 2026
@diangogav
diangogav merged commit d5bc6cf into main Jun 22, 2026
1 check passed
@diangogav
diangogav deleted the feat/exclusive-cosmetic-tier branch June 22, 2026 22:05
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