Adapters — o que fica em functions/
Como o resource isola o acoplamento ao banco/framework do servidor para que você possa adaptar sem mexer no core.
Por que adapters existem
Servidores FiveM têm bancos muito diferentes — uns usam vRP clássico, outros vRPex, alguns rodam ESX ou framework próprio. O resource Lua isola tudo o que depende do schema em um único diretório:
services/fivem-lua-api/
├── config.lua ← edita SEMPRE
├── server/ ← core, normalmente NÃO mexe
│ ├── main.lua ← router HTTP
│ ├── snapshots.lua ← /health, /system
│ ├── metrics.lua ← /metrics
│ ├── events_buffer.lua ← /events + hooks
│ └── *_handler.lua ← rotas inventory, garage, properties, punishments
└── functions/ ← ADAPTERS — edita conforme seu banco
├── tunnel.lua
├── player_search.lua
├── inventory.lua
├── garage.lua
├── properties.lua
└── punishments.luaserver/ deve continuar funcionando sem edição. Tudo dentro de functions/ é seu — você adapta ao schema do seu servidor.Contrato esperado
Cada adapter expõe um conjunto de funções globais que os handlers em server/*.lua chamam via pcall. Se uma função falhar, o request retorna partialErrors em vez de quebrar o painel inteiro.
Globals expostos por cada adapter
EliteSaaSPlayerSearch— pesquisa e perfil agregado.getUserInventory,getAvailableItems,tryGetInventoryItem,addInventoryItem— inventário.getUserVehicles,getAvailableVehicles,tryRemoveVehicle,addVehicle,getTrunkChest,tryRemoveTrunkItem— garagem.getUserProperties,getAvailableProperties,tryRemoveProperty,addProperty,getPropertyChest,tryRemovePropertyChestItem,getPropertyResidents,tryRemovePropertyResident— propriedades.getPunishmentHistory,getActivePunishments,jailPlayer,tempBanPlayer,permBanPlayer,kickPlayer,removeWhitelist,addWhitelist,unjailPlayer,unbanPlayer— punições.
Open-schema
Veículos e propriedades aceitam chaves extras arbitrárias além do mínimo (plate+model e propertyId+label). O painel renderiza essas chaves automaticamente como linhas chave/valor — você não precisa atualizar a UI para mostrar campos novos.
-- Você pode retornar qualquer chave extra:
{
plate = "ABC1D23",
model = "adder",
ipva = "em-dia", -- vira "Ipva: em-dia" no painel
apreendido = false, -- vira "Apreendido: Não"
kms_rodados = 18420 -- vira "Kms rodados: 18.420"
}Defensividade obrigatória
Como o resource roda dentro do FXServer, exceções em adapters podem bloquear ticks. Boas práticas:
- Use
pcallao chamar exports de outros recursos. - Cheque
type(x) == "table"antes de iterar resultados deexports.oxmysql:query_async. - Devolva listas vazias em vez de
nilquando não há dados. - Logue erros com
EliteSaaSDebug.log()em vez deprint.
Próximas páginas
Cada adapter tem uma página própria com o contrato SQL e exemplos prontos para adaptar: