feat(city): implement marketplace, missions, customization and admin dashboard
- Add database migrations for market_listings, missions and character cosmetics - Create controllers for marketplace, missions, presence and character customization - Implement admin world dashboard with live platform metrics - Add feature tests for world functionality - Include phase 2 design documents and gap analysis
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
<div style="text-align:center;margin-bottom:1.5rem">
|
||||
<h2>📐 Design — Cidade 3D Fase 2</h2>
|
||||
<p class="subtitle">Arquitetura, componentes, fluxo de dados e testes — revise seção por seção</p>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<span class="label">1. Arquitetura</span>
|
||||
<p>A cena Three.js passa de <strong>órbita isométrica</strong> para <strong>exploração a pé</strong>. O backend continua o mesmo (Sanctum + <code>/city/data</code>), mas o payload ganha: ruas, prédios gerados, e um streaming de mensagens de chat via <strong>SSE</strong> (Server-Sent Events) por agente — sem dependência nova.</p>
|
||||
<pre style="background:#0b1220;border:1px solid var(--border);border-radius:.5rem;padding:.75rem;overflow:auto;font-size:.8rem">Frontend (Three.js)
|
||||
├── CameraController — WASD + mouse, colisão AABB
|
||||
├── CityGenerator — ruas, quadras, prédios de preenchimento
|
||||
├── CharacterFactory — carrega modelos GLTF por tipo de agente
|
||||
├── HudOverlay — painel POSIÇÃO + minimapa
|
||||
└── ChatPanel — fluxo SSE /city/chat/{agent}
|
||||
|
||||
Backend (Laravel)
|
||||
├── CityViewerController::data() — stores + agents + city layout
|
||||
├── ChatController — SSE endpoint por agente
|
||||
└── AgentThinkJob (queue) — chama OpenRouter, persiste last_decision</pre>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<span class="label">2. Componentes</span>
|
||||
<table style="width:100%;border-collapse:collapse;font-size:.9rem">
|
||||
<tr style="border-bottom:1px solid var(--border)"><td style="padding:.5rem"><strong>CameraController</strong></td><td>Pointer-lock, WASD, gravidade simples, raycast contra colisores AABB de prédios</td></tr>
|
||||
<tr style="border-bottom:1px solid var(--border)"><td style="padding:.5rem"><strong>CityGenerator</strong></td><td>Rua central + quadras laterais a partir das posições das lojas; prédios de preenchimento procedural (seed determinística)</td></tr>
|
||||
<tr style="border-bottom:1px solid var(--border)"><td style="padding:.5rem"><strong>StreetMesh</strong></td><td>Asfalto (canvas texture com faixas), calçada de ladrilho, postes a cada N metros</td></tr>
|
||||
<tr style="border-bottom:1px solid var(--border)"><td style="padding:.5rem"><strong>CharacterFactory</strong></td><td>GLTF por <code>agent.type</code>; fallback: cápsula texturizada. Animação Idle/Walk/Run</td></tr>
|
||||
<tr style="border-bottom:1px solid var(--border)"><td style="padding:.5rem"><strong>HudOverlay</strong></td><td>Painel POSIÇÃO (x,y,z, triângulos) + minimapa 2D no canto</td></tr>
|
||||
<tr><td style="padding:.5rem"><strong>ChatPanel</strong></td><td>Abre ao clicar no NPC; mostra nome, status (pensando/respondendo), mensagens; envia via POST e recebe via SSE</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<span class="label">3. Fluxo de dados</span>
|
||||
<ol>
|
||||
<li>Viewport carrega → <code>GET /city/data</code> → lojas + agentes + layout de ruas</li>
|
||||
<li><code>CityGenerator</code> monta ruas e prédios; prédios de loja ganham fachada custom</li>
|
||||
<li>Usuário anda (WASD) → colisão por AABB → câmera segue</li>
|
||||
<li>Clica em NPC → <code>ChatPanel</code> abre → <code>GET /city/chat/{agent}/stream</code> (SSE)</li>
|
||||
<li>Envia mensagem → <code>POST /city/chat/{agent}</code> → job enfileirado → OpenRouter → persiste <code>last_decision</code> → SSE emite resposta</li>
|
||||
<li>HUD recalcula posição a cada frame</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<span class="label">4. Tratamento de erros</span>
|
||||
<ul>
|
||||
<li>SSE cai → reconexão automática com backoff, indicador "reconectando"</li>
|
||||
<li>OpenRouter falha → <code>error_count++</code>, backoff exponencial, status vira <code>error</code> no painel</li>
|
||||
<li>GLTF ausente → fallback silencioso para cápsula (nunca quebra a cena)</li>
|
||||
<li>Colisão detecta NaN → reposiciona no spawn</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<span class="label">5. Testes</span>
|
||||
<ul>
|
||||
<li><strong>PHPUnit</strong>: <code>CityViewerController::data()</code> retorna layout; <code>ChatController</code> valida input e rate-limit; job persiste <code>last_decision</code></li>
|
||||
<li><strong>JS</strong>: <code>CameraController</code> (colisão, WASD), <code>CityGenerator</code> (determinístico com seed), reconexão SSE</li>
|
||||
<li><strong>Manual</strong>: navegar, colidir, conversar com NPC, verificar HUD</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<hr style="border-color:var(--border);margin:1.5rem 0">
|
||||
|
||||
<p style="text-align:center"><strong>Esse design está correto? Aprovo para escrever a especificação formal.</strong></p>
|
||||
<div class="options">
|
||||
<div class="option" data-choice="approve" onclick="toggleSelect(this)">
|
||||
<div class="letter">✅</div>
|
||||
<div class="content"><h3>Aprovar design</h3><p>Escrever spec → revisão → plano de implementação</p></div>
|
||||
</div>
|
||||
<div class="option" data-choice="revise" onclick="toggleSelect(this)">
|
||||
<div class="letter">✏️</div>
|
||||
<div class="content"><h3>Revisar</h3><p>Quero mudar algo antes de seguir</p></div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user