@cactus-agents/validations
Engine de regras para validação de dados do usuário. Avalia quais módulos estão pendentes com base na configuração da marca (BrandValidationModules) e no estado atual do usuário (ValidationSnapshot).
Instalação
pnpm add @cactus-agents/validations
Uso recomendado
import { fetchAllValidations } from "@cactus-agents/validations";
const result = fetchAllValidations({
config: brand.features.authValidation,
snapshot: validationSnapshot,
});
if (result.hasPending) {
console.log(result.pendingType); // "force" | "regulatory" | "global"
console.log(result.pendingModule); // "address" | "email" | "kyc" | ...
}
Conceitos
Três paths de avaliação
| Path | Quando ativa | O que bloqueia | Prioridade |
|---|---|---|---|
| force | forceRequestKyc = true no perfil | Navegação inteira (overlay bloqueante) | 1 (mais alta) |
| regulatory | showPendingDataFlow = true no perfil | Navegação inteira (overlay bloqueante) | 2 |
| global | config.global.active = true | Navegação inteira (overlay bloqueante) | 3 |
Além desses, cada contexto (casino, sports, deposit, withdraw, etc.) é avaliado separadamente e bloqueia apenas a ação correspondente.
Módulos suportados
| Módulo | Validador | O que verifica |
|---|---|---|
email | email E validateEmailAt preenchidos (ambos obrigatorios) | E-mail verificado |
phone / sms | phone E ddi preenchidos; se validateSmsAt e undefined retorna true, se definido verifica preenchido | Telefone verificado por SMS |
address | zipcode + countryCode + fullAddress + city + state (5 campos) | Endereço completo |
docs / document | documentNumber + birthDate; para BRA, tambem verifica nationalities.length > 0 | Documentos básicos |
kyc | isKycApprovedStatus(latestKycStatus) (validacao apos login e verificada em evaluateForceValidation, nao no predicate padrao) | Selfie/documentos verificados |
password | strongPassword é truthy | Senha forte definida |
user_limits | se regulatoryValidationEnabled e false, retorna true (skip); se true, verifica userLimitTimeChange e userLimitLossChange | Limites prudenciais |
terms | termsAccepted = true | Termos aceitos |
gps | gpsGranted = true | Geolocalização permitida |
bank_account | se completeRegulatoryRegistrationEnabled e false, retorna true (skip); se true, verifica hasBankAccount | Conta bancária cadastrada |
frequent flag
Quando entry.frequent = true, os módulos daquela entry são sempre avaliados como inválidos — forçando revalidação a cada ação (ex: senha para saque).
API
fetchAllValidations(input)
Função principal. Avaliacao completa que combina force + regulatory + global + contexts. Retorna FetchAllValidationsResult com hasPending, pendingType, pendingModule.
function fetchAllValidations(input: FetchAllValidationsInput): FetchAllValidationsResult;
Input:
interface FetchAllValidationsInput {
config: BrandValidationModules; // da brand config
snapshot: ValidationSnapshot; // estado do usuário
contextAmounts?: Partial<Record<ValidationContextName, number>>; // valores em centavos
}
EvaluateValidationInput
interface EvaluateValidationInput {
config: BrandValidationModules;
snapshot: ValidationSnapshot;
includeGlobal?: boolean;
enforceModules?: ValidationModuleName[];
respectFrequent?: boolean;
}
Output:
interface FetchAllValidationsResult {
force: ForceValidationDecision;
regulatory: ContextValidationDecision;
global: ContextValidationDecision;
contexts: Partial<Record<ValidationContextName, ContextValidationDecision>>;
hasPending: boolean;
pendingType: "force" | "regulatory" | "global" | null;
pendingModule: ValidationModuleName | null;
}
buildValidationSnapshot
Converte dados raw da API (formato inconsistente, campos snake_case) em ValidationSnapshot limpo:
import { buildValidationSnapshot, normalizeNationalities } from "@cactus-agents/validations";
const snapshot = buildValidationSnapshot({
isAuthenticated: true,
email: user.email,
phone: user.phone,
ddi: user.ddi,
birth_date: user.birth_date,
document: user.document,
country_data: user.country_data,
latestKyc: user.latestKyc,
address: userInfo.address,
nationalities: userInfo.nationalities,
validate_email_at: userInfo.validate_email_at,
validate_sms_at: userInfo.validate_sms_at,
// ... demais campos
});
O builder normaliza: enderecos (nested object ou string), bank account detection, regulatory flags (4 variantes de campo), termos aceitos, GPS, nacionalidades (JSON array, CSV, objects).
normalizeNationalities(raw): parseia strings de nacionalidades em diversos formatos (JSON array, CSV, objetos com value/name/code) em string[].
RawUserSnapshot: interface com todos os campos raw aceitos pelo builder.
evaluateValidationContext(input)
Avalia um contexto específico (casino, deposit, withdraw, etc.).
function evaluateValidationContext(input: EvaluateValidationInput): ValidationDecision;
evaluateForceValidation(snapshot)
Avalia se o KYC forçado está pendente. Verifica forceRequestKyc + isKycApprovedStatus + wasKycValidatedAfterLogin. Retorna ForceValidationDecision.
function evaluateForceValidation(snapshot: ValidationSnapshot): ForceValidationDecision;
resolveModulesForContext(input)
Retorna a lista de módulos que precisam ser verificados para um contexto.
function resolveModulesForContext(input: ResolveModulesInput): ValidationModuleName[];
validateModule(module, snapshot, predicates)
Valida um módulo individual contra o snapshot.
function validateModule(
module: ValidationModuleName,
snapshot: ValidationSnapshot,
predicates: Partial<Record<ValidationModuleName, ValidationPredicate>> = defaultModulePredicates,
): boolean;
Tipos principais
ValidationSnapshot
interface ValidationSnapshot {
isAuthenticated: boolean;
countryCode?: string | null;
email?: string | null;
phone?: string | null;
ddi?: string | null;
birthDate?: string | null;
nationalities?: string[];
documentNumber?: string | null;
latestKycStatus?: number | string | null;
latestKycUpdatedAt?: string | null;
kycValidatedAt?: string | null;
loginAt?: string | null;
forceRequestKyc?: boolean;
forceRequestKycReasons?: string[];
validateEmailAt?: string | null;
validateSmsAt?: string | null;
strongPassword?: boolean | number | null;
termsAccepted?: boolean;
gpsGranted?: boolean;
regulatoryValidationEnabled?: boolean;
userLimitTimeChange?: string | null;
userLimitLossChange?: string | null;
hasBankAccount?: boolean;
completeRegulatoryRegistrationEnabled?: boolean;
address?: {
zipcode?: string | null;
countryCode?: string | null;
fullAddress?: string | null;
city?: string | null;
state?: string | null;
};
}
BrandValidationModules
Config que vem da brand API (features.authValidation). Cada contexto define quais módulos estão ativos:
interface BrandValidationModules {
casino: ValidationModuleEntry;
global: ValidationModuleEntry;
sports: ValidationModuleEntry;
deposit: ValidationModuleEntry;
register: ValidationModuleEntry;
withdraw: ValidationModuleEntry;
updateData: ValidationModuleEntry;
firstDeposit: ValidationModuleEntry;
updateLimits: ValidationModuleEntry;
firstWithdraw: ValidationModuleEntry;
}
interface ValidationModuleEntry {
active: boolean;
modules: string[];
frequent: boolean;
minValue: number | null;
device: string | null;
}
ValidationContextName
type ValidationContextName =
| "casino" | "global" | "sports" | "deposit" | "register"
| "withdraw" | "updateData" | "firstDeposit" | "updateLimits" | "firstWithdraw";
ValidationModuleName
type ValidationModuleName =
| "docs" | "terms" | "email" | "phone" | "address"
| "kyc" | "gps" | "password" | "user_limits" | "bank_account"
| string;
Arquivos relevantes
| Arquivo | Conteúdo |
|---|---|
src/evaluate.ts | Funções de avaliação (fetchAllValidations, evaluateValidationContext, evaluateForceValidation, etc.) |
src/modules.ts | Predicados por módulo (defaultModulePredicates) |
src/snapshot.ts | buildValidationSnapshot, normalizeNationalities, RawUserSnapshot |
src/types.ts | Todas as interfaces e tipos |
src/index.ts | Re-exports públicos |