Planos por dentro (tiers)
O sistema de planos vive no painel (db.mjs) e é espelhado no site (para o site também
saber esconder recursos). Aqui está como ele funciona por dentro.
Os três tiers
Section titled “Os três tiers”TIER_RANK = { essencial: 1, profissional: 2, premium: 3 }Cada rádio tem um tier no banco (radios.tier). Vazio = essencial (o piso). A
comparação é por rank: a rádio tem o recurso se o rank do tier dela ≥ o rank exigido
pelo recurso.
O mapa recurso → tier mínimo
Section titled “O mapa recurso → tier mínimo”Cada recurso declara o tier mínimo que o libera (FEATURE_MIN_TIER):
| Recurso | Tier mínimo |
|---|---|
programete |
essencial |
studio (estúdio ao vivo) |
profissional |
horaCertaCustom (hora certa com nome) |
profissional |
sitePremium |
profissional |
appPremium |
profissional |
vinheta |
profissional |
campanha |
profissional |
programa |
profissional |
youtubeAuto (vídeos do canal) |
premium |
A promoção “liberado pra todos”
Section titled “A promoção “liberado pra todos””Existe uma janela promocional (PROMO_END) em que alguns recursos ficam soltos pra
qualquer rádio, independente do tier:
PROMO_FEATURES = new Set(['studio', 'horaCertaCustom'])Durante a promoção, só esses dois ficam livres pra todos. Os conteúdos de biblioteca (vinheta, campanha, programa) não entram na promoção — travam por tier o tempo todo. Quando a promoção vence, a trava dura volta a valer para todos.
A decisão fica em hasFeatureNow(tier, feature):
function hasFeatureNow(tier, feature, now) { if (promoActive(now) && PROMO_FEATURES.has(feature)) return true; return tierHasFeature(tier, feature);}Exceções por rádio (overrides)
Section titled “Exceções por rádio (overrides)”Dá pra forçar liberar ou bloquear um recurso numa rádio específica, ignorando o plano,
via a tabela station_feature_overrides:
mode = 'allow'→ libera mesmo sem o plano;mode = 'block'→ tira mesmo tendo o plano.
O override vence o tier e a promoção. Útil pra cortesias pontuais ou pra desligar algo numa rádio específica.
Onde isso é setado
Section titled “Onde isso é setado”- Tier:
POST /api/admin/tier{ station_id, tier }→ grava emradios.tier. - Override:
POST /api/admin/feature-override{ station_id, feature, mode }.
Ambos são endpoints de administração (PSYCO). Não há, hoje, uma tela pra o operador fazer isso sozinho — é o que a página operacional de planos chama de “falar com a PSYCO”.
Como o painel e o site usam
Section titled “Como o painel e o site usam”O painel calcula um mapa { recurso: true/false } por rádio (effectiveFeatures) e o front
só mostra ou esconde. Recurso bloqueado vira uma vitrine de upgrade. O site público
recebe o tier no config e aplica a mesma lógica (via um espelho do FEATURE_MIN_TIER),
pra não renderizar um recurso que a rádio não tem.