Events — Live Feed
Stream de eventos do servidor (connect/disconnect/punishments/economia) consumido em tempo real pelo painel.
Modelo
O resource mantém um ring buffer em memória de até 500 eventos. Sem persistência — basta para a janela curta de live feed. Cada evento tem um id monotônico que permite ao cliente pedir só o delta:
buffer (capacity = 500)
┌─────────────────────────────────────────────────┐
│ id=1 id=2 id=3 ... id=N (mais recente) │
└─────────────────────────────────────────────────┘
▲
cliente envia after=<lastId>
servidor devolve só id > lastId/elite-saas/events?after=<lastId>&limit=<n>🔒 authRetorna eventos novos desde o último id conhecido. Sem after, devolve os últimos `limit` eventos.
Query parameters
afterid que o cliente já viu. 0 ou omitido = trás os últimos limit eventos.limit200 OK
{
"tenantId": "elite-city",
"count": 3,
"lastId": 1238,
"events": [
{
"id": 1236,
"at": 1716587410123,
"type": "connect",
"title": "João entrou na cidade",
"detail": "uid #4823",
"severity": "info",
"actor": null,
"target": "João",
"userId": 4823,
"serverId": 7,
"source": "fivem"
},
{
"id": 1237,
"at": 1716587422001,
"type": "ban",
"title": "perm_ban aplicado a Carlos",
"detail": "Motivo: cheating",
"severity": "danger",
"actor": "@lucas",
"target": "Carlos",
"userId": 9012,
"source": "fivem"
},
{
"id": 1238,
"at": 1716587430500,
"type": "disconnect",
"title": "Maria saiu",
"detail": "Disconnected.",
"severity": "info",
"userId": 5511,
"serverId": 9,
"source": "fivem"
}
]
}Tipos comuns
connect / disconnectplayerJoining / playerDropped. Inclui userId resolvido via vRP (pode ser null se ainda não houver mapeamento).ban / jail / kick / warnfunctions/punishments.lua). Use EliteSaaSEvents.punishment(kind, target, uid, reason, actor).economyEliteSaaSEvents.economy(actor, amount, kind).inventory / garage / propertycustomEmpurrando eventos custom
Em qualquer arquivo Lua do seu servidor (não precisa ser dentro do elite_saas_api):
-- Direto (controle total dos campos)
EliteSaaSEvents.push({
type = "gang",
title = "Conflito iniciado",
detail = "Vagos vs Ballas · Grove St.",
severity = "warn",
actor = "evento automático",
meta = { zone = "grove" }
})
-- Helpers prontos
EliteSaaSEvents.punishment("temp_ban", "Carlos", 9012, "RDM", "@lucas")
EliteSaaSEvents.economy("Maria", 12450, "salário")
EliteSaaSEvents.inventoryChange("@staff", "ak47", 1)type mapeia para um ícone e cor. severity: "danger" destaca em vermelho; "warn" em âmbar. Tipos desconhecidos ainda aparecem (cinza + info).Merge no painel
O backend Nest combina os eventos do Lua com o AuditLog do próprio painel (mudanças de branding, bans via API, mudanças de cargo) e devolve um stream único:
/v1/events/feed?after=<ms>&limit=<n>🔒 authEndpoint do painel (não do Lua). Mescla source=lua + source=panel ordenado desc por `at`.
O parâmetro aqui é after em milissegundos epoch (não o id do Lua — porque o painel mistura duas fontes com IDs disjuntos).
Reinício e janela de retenção
- Buffer só vive em RAM. Restart do resource zera. Para retenção longa, persista os eventos relevantes via
AuditLogno painel (ações administrativas) ou tabelas custom. - Capacidade 500 — em servidores muito ativos, suba o
CAPACITYemevents_buffer.luaou reduza o escopo dos hooks.