ÆGIS ÆGIS
← voltar à plataforma
home / documentação
// índice de conteúdo
// ÆGIS SECURITY TRAINING PLATFORM — DOCUMENTAÇÃO TÉCNICA v1.0.0

ÆGIS

Plataforma de treinamento em segurança serverless com mecânica de jogo. O usuário aprende defendendo o sistema contra ataques em tempo real simulados pelo Loki's Shadows.
Premissa: O jogador é um Guardião responsável por manter o ÆGIS operacional. Erros custam integridade (HP). Bloqueios corretos concedem XP. Se o HP chegar a 0%, o sistema é destruído e precisa ser reanimado.

Stack: HTML + CSS + JavaScript vanilla · Node.js + Express · Supabase (PostgreSQL + Auth) · Mistral AI (via proxy server) · Deploy no Railway.


02Arquitetura
/
index.html — estrutura principal da SPA
main.js — game state, HUD, Loki, morte/cura
server.js — Express: proxy Mistral, ranking API, auth middleware
style.css — estilos globais e variáveis CSS
package.json — dependências Node.js
/js
missions-data.js — MISSIONS_DATA, MISSION_STATE, FLASHCARDS
missions-ui.js — render das missões e steps
missions-attacks.js — pool de ataques ATTACKS
ai-router.js — ÆGIS-BOT + taunts Loki via Mistral
estudos.js / estudos_content.js — módulos de estudo
nick-screen.js — autenticação Supabase
aegis-mobile-nav.js — navegação mobile completa
ranking.js — ranking global (Supabase + STATE Proxy)
activity-feed.js — feed de atividades recentes
progresso-dynamic.js — árvore de skills e runas
simulados.js — lógica dos simulados
A ordem dos scripts no index.html é crítica. Supabase SDK deve ser o primeiro. ranking.js deve ser o último — ele envolve o STATE num Proxy.

03Game State

Estado global em window.STATE (alias STATE). Única fonte de verdade da sessão. Nunca modificar métricas de jogo diretamente — use _grantXP().

scorenumber
XP acumulado. Nunca vai abaixo de 0.
aegisHp0–100
Integridade do ÆGIS em %. Chegar a 0 dispara a morte.
blocksnumber
Ataques do Loki bloqueados com sucesso.
failsnumber
Erros e timeouts nos ataques do Loki.
lokiLevelnumber
Nível do Loki. Aumenta a cada bloqueio. Reduz delay entre ataques.
completedMissionsnumber[]
IDs das missões concluídas. Evita reprocessar recompensas.
activeMissionIdnumber|null
ID da missão em andamento. Null desativa os ataques do Loki.
modalActiveboolean
True enquanto o modal de ataque está aberto. Evita ataques sobrepostos.
timerSecsnumber
Tempo do timer do modal. Base 15s, reduz com lokiLevel (mín. 8s).
currentSectionstring
Seção atualmente ativa na navegação.

Persistido via persistStateLocally() e restaurado via restoreStateFromLocal(). O ranking.js envolve o STATE num Proxy que sincroniza automaticamente com o Supabase a cada mudança relevante.


04Sistema de XP

Toda alteração de score, HP, bloqueios e falhas deve passar por window._grantXP().

JS
window._grantXP({
  xp:     60,              // adiciona ao score
  hp:     -3,              // altera integridade (+cura / -dano)
  blocks: 1,               // incrementa bloqueios
  fails:  1,               // incrementa falhas
  label:  'missoes:loki',  // log no console (opcional)
});
Tabela de Eventos
EventoXPHPBlqFal
Bloqueio correto do Loki+60+lokiLevel×20+5%+1
Erro na resposta do Loki−3%+1
Timeout no modal do Loki−5%+1
Questão certa (cronometrado)+10+(timeLeft/60)×20+1
Questão certa (livre)+10+1
Questão errada (simulado)−5%+1
Missão concluída+200+15%+1
Simulado concluído (base)+100
Simulado acima de 80%+50
Flashcard revelado+3%

05HUD & Integridade

updateHUD() atualiza todos os elementos visuais do estado. Chamada automaticamente por _grantXP().

Cores da barra de HP
crítico
20%
≤ 30% — vermelho + pulsante
alerta
50%
31–60% — amarelo
saudável
85%
> 60% — verde
Recarga de Emergência
LocalIDEfeitoCooldown
Sidebar desktopaegisRechargeBtn+10% HP2 horas
Footer drawer mobileaegisRechargeBtnMob+10% HP2 horas (compartilhado)

06Sistema Loki

O Loki só ataca quando lokiCanAttack() retorna true — i.e., quando existe MISSION_STATE.activeMissionId definido.

Escalada por Missão
MissãoTemaIntervaloTimer
01Command Injection30–45s15s
02IDOR22–35s13s
03Broken Auth16–28s11s
04SSRF12–22s9s
05Supply Chain9–16s8s
06Final APT7–13s7s
Fluxo de Ataque
scheduleAttack() — agenda próximo ataque via setTimeout
delay = max(9s, 22s − (lokiLevel−1)×3.5s) + random(4s)
launchAttack() — dispara quando timeout vence
disruptAegis(atk) — anima bot, exibe mensagem no chat
openModal(atk) — choices embaralhadas + timer
Usuário responde via answerLoki(i, shuffled)
Correto: +XP, +5% HP, +bloqueio, lokiLevel++, reagenda
Errado: −3% HP, +falha, reagenda
Timer esgota → onTimeout(): −5% HP, +falha, reagenda

Pool de ataques: ATTACKS em missions-attacks.js. 70% ataques temáticos da missão ativa, 30% pool global. Taunts dinâmicos via generateLokiTaunt() no ai-router.js usando Mistral AI.


07Morte & Reanimação
Quando aegisHp chega a 0, todos os ataques do Loki são pausados até o jogador clicar em Reanimar.
triggerAegisDeath()
1.Para todos os ataques — stopLokiAttacks() + limpa lokiTimeout
2.Fecha o modal do Loki se estiver aberto
3.Cria (ou reutiliza) o overlay #aegisDeathOverlay
4.Exibe stats: bloqueios, falhas, XP acumulado
5.Sorteia frase de vitória em LOKI_VICTORY_LINES[]
6.Atualiza o bot para estado DESTRUÍDO
reviveAegis()
1.Restaura aegisHp = 50
2.Remove .active do overlay
3.Restaura bot para estado amarelo "reanimado"
4.Retoma ataques via startLokiAttacks()

08Sistema de Cura
FonteHPCondição
Bloqueio correto do Loki+5%sempre
Missão concluída+15%se HP < 100
Flashcard revelado+3%se 0 < HP < 100
Recarga de emergência+10%cooldown 2h
Regeneração passiva+2% / 30sHP ≤ 10 e missão ativa
Reanimação após morte50% fixoapós reviveAegis()

09Missões

Cada missão tem steps com conteúdo educativo e um quiz final. MISSION_STATE (em missions-data.js) controla o passo atual.

MissãoTema
01Command Injection
02IDOR
03Broken Authentication
04SSRF
05Supply Chain
06Final APT
Ciclo de Vida
navigate('missoes')refreshMissionsList()
Usuário clica → goToStep(1, mission)
onMissionStarted() → ativa ataques do Loki
Navegação pelos steps via goTo(n)
onMissionCompleted(id, xp) → recompensas + cura
onMissionEnded() → para ataques do Loki
onMissionCompleted verifica completedMissions.includes(missionId) antes de conceder recompensas — evita duplicatas.

10Estudos

Controlado por estudos.js + estudos_content.js. Inicializado via call(initEstudos). Destruído ao sair via destroyEstudos(). Módulos concluídos desbloqueiam questões extras no banco de simulados via buildSimuladoPool().


11Flashcards
FunçãoDescrição
initFlashcards()Reseta índice e renderiza primeiro card
flipCard()Vira o card; concede +3% HP ao revelar resposta
nextCard() / prevCard()Navegação circular entre os cards
renderFlashcard()Atualiza o DOM com o card atual
updateFcCounter()Atualiza "card N / total // deck: X"

12Simulados
ModoTimerXP por questão certa
cronometrado60s por questão10 + (timeLeft/60) × 20
livresem timer10

buildSimuladoPool(): 12 questões base + questões de módulos concluídos, embaralhadas, 10 por sessão. Estado em window.SIMULADO_STATE, separado do STATE principal.


13Progresso

Inicializado por initProgresso(). Exibe XP, bloqueios e missões concluídas. A skill de Command Injection reflete o progresso real da Missão 01. A árvore de habilidades e as runas são preenchidas dinamicamente por progresso-dynamic.js.


14Ranking

Controlado por ranking.js. Tabs: global, semanal, missoes. Dados lidos do Supabase em tempo real via refreshRankingView(). O score é sempre calculado e validado server-side pelo server.js — o frontend não controla XP diretamente.



16Mobile

Breakpoint: <= 768px. Todos os componentes são injetados dinamicamente por aegis-mobile-nav.js.

ComponenteIDDescrição
Topbar#mob-topbarBarra superior com botão ≡ e logo
Drawer#mob-nav-drawerMenu lateral com nav + stats + recarga
Backdrop#mob-nav-backdropOverlay escuro ao abrir o drawer
Puxador#mob-bot-pullerTab lateral para abrir o ÆGIS-BOT
API Pública
window.AegisMobile.openSidebar()   window.AegisMobile.closeSidebar()
window.AegisMobile.openBot()       window.AegisMobile.closeBot()
window.AegisMobile.openDrawer()    window.AegisMobile.closeDrawer()
window.AegisMobile.isMob()         // true se <= 768px
Anti-duplicate listeners: todos os botões usam clone + replace antes de adicionar event listeners. Evita disparos múltiplos quando bind() é chamado mais de uma vez.

17Backend — Node.js + Express

O server.js roda em Node.js com Express e é deployado no Railway. Serve o frontend via express.static e expõe endpoints de API.

Endpoints
EndpointAuthDescrição
POST /api/chat✓ requireAuthProxy para Mistral AI (ÆGIS-BOT e taunts do Loki)
POST /api/ranking/save✓ requireAuthSalva estado do jogador com score server-side
GET /api/rankingpúblicoRetorna ranking global/semanal/missões
GET /api/ranking/me✓ requireAuthRetorna dados do jogador autenticado
POST /api/mission/start✓ requireAuthGera mission_token para iniciar missão
POST /api/mission/complete✓ requireAuthValida token e registra missão concluída
Segurança do Score
Score calculado server-side via recalculateScore() — o frontend não controla XP diretamente.
fails e blocks só sobem. aegis_hp só cai. Nunca sobrescreve com valores mais favoráveis ao jogador.
Supabase

Auth via OAuth Google gerenciada por nick-screen.js. Evento aegis:nick-set disparado após autenticação bem-sucedida para sincronizar o STATE. JWT validado pelo requireAuth middleware em cada request.

ColunaTipoDescrição
user_idtextID do usuário Supabase
nicktextNick do guardião (máx. 30 chars)
scoreintXP total — calculado server-side
blocksintAtaques bloqueados
failsintErros acumulados
aegis_hpintIntegridade atual
missionsintNúmero de missões concluídas
completed_missionsint[]IDs das missões concluídas

18ÆGIS-BOT

Controlado por ai-router.js. Usa Mistral AI via proxy em /api/chat no server.js. Respostas locais frequentes são atendidas sem chamada à API — latência zero. Chamadas externas só ocorrem para perguntas livres e taunts dinâmicos do Loki.

Modelos
UsoModelomax_tokens
ÆGIS-BOT (respostas livres)mistral-small-latest300
Loki taunts dinâmicosmistral-small-latest80
Reação ao resultado do ataquemistral-small-latest60
Funções
FunçãoDescrição
botSay(msg)Exibe mensagem do bot no chat
appendMsg(html, type, cls)Adiciona mensagem ao #chatArea
sendUserMsg()#chatInput, tenta resposta local, depois chama Mistral
showQR() / hideQR()Exibe/oculta quick replies contextuais
aegisReactToResult(win, type)Bot reage ao resultado do ataque do Loki
generateLokiTaunt(type, lastChoice?)Gera fala contextual do Loki via Mistral
getAuthToken()Lê token do Supabase no localStorage para autenticar o proxy

19Variáveis CSS
style.css
--green:        #00ff41      /* cor principal */
--red:          #ff1a3c      /* dano / Loki */
--yellow:       #ffe066      /* aviso / HP médio */
--loki-purple:  #a050ff      /* identidade do Loki */
--bg:           #020b04      /* fundo principal */
--border:       rgba(0,255,65,0.25)
--border-bright:rgba(0,255,65,0.6)
--text-dim:     rgba(0,255,65,0.45)
--text-mid:     rgba(0,255,65,0.72)
--text-bright:  #e8ffe8
--green-faint:  rgba(0,255,65,0.06)
--red-glow:     rgba(255,0,40,0.4)
--green-glow:   rgba(0,255,65,0.3)

20IDs HTML Críticos
IDUsado em
aegisHpBar / hpTextupdateHUD(), injectRechargeBtn()
scoreDisplay / blocksDisplay / failsDisplayupdateHUD()
lokiModal / lmBackdropopenModal(), closeLokiModal()
timerFill / timerCountstartTimer()
lmChoices / lmResult / lmTauntopenModal(), showResult()
botAvatar / botPill / botName / botSubdisruptAegis(), recoverAegis()
chatArea / chatInputappendMsg(), sendUserMsg()
aegisDeathOverlaytriggerAegisDeath(), reviveAegis()
aegisRechargeBtn / aegisRechargeBtnMobinjectRechargeBtn(), updateRechargeBtn()
mob-nav-drawer / mob-nav-footeraegis-mobile-nav.js, injectRechargeBtn()

21Comandos de Console
>
window.STATE.aegisHp = 0; triggerAegisDeath();
Testar tela de morte do ÆGIS
>
launchAttack();
Forçar ataque imediato do Loki
>
window._grantXP({ xp: 500, hp: 50, label: 'debug' });
Conceder XP e HP manualmente
>
onMissionCompleted(1, 200);
Forçar conclusão da Missão 01
>
navigate('ranking');
Navegar para qualquer seção
>
window.STATE.lokiLevel = 1;
Resetar nível do Loki
>
window._rechargeCooldownEnd = 0; activateEmergencyRecharge();
Forçar recarga de emergência
>
console.log(window.STATE);
Inspecionar estado completo

22Fluxo Completo de Sessão
1.Página carrega
Supabase SDK inicializado
nick-screen.js verifica sessão
sem sessão → tela de login Google
com sessão → dispara aegis:nick-set
2.aegis:nick-set disparado
ranking.js restaura STATE do servidor
aegis-mobile-nav.js fecha painéis, rebinda eventos
initBinBg()updateHUD()navigate('home')initBot() (600ms)
3.Usuário inicia missão
POST /api/mission/start → recebe mission_token
goToStep(1, mission)onMissionStarted()scheduleAttack()
4.Loki ataca
disruptAegis() → animação + chat
openModal() → choices + timer
correto → XP + HP + lokiLevel++ → reagenda
errado → HP-- → checkAegisDeath() → reagenda
5.Missão concluída
POST /api/mission/complete → valida token → registra no Supabase
onMissionCompleted() → XP + cura → onMissionEnded()
6.HP chega a 0 → morte
triggerAegisDeath() → overlay
Reanimar → reviveAegis() → HP=50 → retoma ataques

23Glossário
Guardião
O usuário/jogador da plataforma.
ÆGIS
O sistema de defesa que o jogador protege.
Loki's Shadows
APT simulado, o vilão. Ataca em tempo real durante missões.
HP / Integridade
Saúde do ÆGIS em % (0–100). Chegar a 0 causa morte.
XP
Pontos de experiência acumulados via bloqueios e missões.
Bloqueio
Resposta correta a um ataque do Loki.
lokiLevel
Nível do Loki. Aumenta a cada bloqueio. Reduz delay entre ataques.
Modal
Janela de ataque do Loki com choices e timer.
Payload
Código malicioso exibido no modal de ataque.
Taunt
Fala provocativa do Loki (estática ou gerada via Mistral AI).
Runa
Recompensa desbloqueada ao concluir missões.
Deck
Conjunto de flashcards associado a uma missão.
STATE
Objeto global de estado (window.STATE). Única fonte de verdade.
_grantXP
Função central de modificação de estado para XP/HP.
mission_token
Token gerado pelo server ao iniciar missão. Necessário para registrar conclusão.
requireAuth
Middleware Express que valida o JWT do Supabase antes de cada endpoint protegido.
Drawer
Menu de navegação deslizante no mobile.
Puxador
Tab lateral para abrir o ÆGIS-BOT no mobile.