Skip to content

Ambiente Docker de produção, UI completa, login Supabase e 213 testes - #101

Merged
c4rlosfb merged 2 commits into
devfrom
fix/docker-production-ready
Jun 18, 2026
Merged

Ambiente Docker de produção, UI completa, login Supabase e 213 testes#101
c4rlosfb merged 2 commits into
devfrom
fix/docker-production-ready

Conversation

@c4rlosfb

Copy link
Copy Markdown
Owner

O que muda?

PR completo com todas as melhorias implementadas para produção:

🖥️ Frontend

  • UI completa: splitter resizable, NASM Monaco Editor, terminal xterm.js
  • Exemplos corrigidos para sintaxe real do simplesc (com ;, leia sem (), escreva() com ())
  • Dropdown exemplos: hello, fatorial, fibonacci, tabuada
  • Botões: ▶ Compilar, ■ Parar, Limpar
  • Editor fica read-only durante compilação/execução
  • Tailwind CSS funcionando (cores, layout, responsivo)
  • Dockerfile otimizado com build args para Supabase

⚙️ Backend

  • Dockerfile: Ubuntu 24.04 + python3 + simplesc binário real
  • dev_server.py: servidor gevent para WebSocket funcional
  • Health endpoint: todos componentes OK
  • Docker sandbox: stop_timeout=12 (defesa em profundidade)
  • WebSocket funcional sem erros

🧪 Testes

  • 213 testes passando (era 48), cobertura 79%
  • Playwright E2E: 4/4 passando
  • Frontend build: OK

📦 DevOps

  • docker-compose.yml: build args Supabase, runner_image_build corrigido
  • docker-compose.demo.yml: corrigido com volume tmpfs
  • .env configurado para produção com Supabase real

📝 Documentação

  • README atualizado com badges, funcionalidades, como testar
  • PROGRESS.md: 45/53 itens (85%)
  • PRESENTATION.md: slides completos (Marp)
  • docs/INCIDENTS.md: auditoria de segurança do sandbox (9 camadas)

Por quê?

Closes #48 (parcial — deploy OCI pendente de credenciais)

Implementa todos os requisitos do PRD §4.1 (escopo v1) exceto deploy Oracle Cloud.

Como testar?

# Subir tudo
docker compose up --build -d

# Verificar
curl http://localhost/api/health
# → {"status":"healthy","version":"1.0.0"}

curl -X POST http://localhost/api/compile   -H "Content-Type: application/json"   -d '{"code":"programa t\ninteiro x;\ninicio\n  leia x;\n  escreval(x);\nfim"}'
# → {"success":true,"asm":"global _start\n..."}

# Frontend
http://localhost → IDE completa
http://localhost/login → Login Supabase

# Testes
pytest tests/ -q  → 213 passed
cd frontend && npx playwright test → 4 passed

Checklist

  • Testes passando localmente
  • Atualizei o README
  • Não introduzi breaking changes
  • CI verde
  • Docker compose up funcional

…testes

## Principais mudanças

### Frontend
- App.tsx reescrito: UI completa com splitter resizable, NASM Monaco, terminal xterm.js
- Exemplos corrigidos para sintaxe real do simplesc (;, leia sem (), escreva com ())
- Exemplos dropdown: hello, fatorial, fibonacci, tabuada
- Botões: Compilar, Parar, Limpar
- Editor read-only durante compilação/execução
- Tailwind CSS (@tailwind directives no index.css)
- Vite proxy fix (localhost:5000)
- .env configurado para Supabase e modo demo
- Playwright E2E: 4 testes passando
- Dockerfile com ARG/ENV para VITE_SUPABASE_URL/ANON_KEY

### Backend
- Dockerfile: Ubuntu 24.04, python3, simplesc binário pré-compilado
- dev_server.py: servidor com gevent para suporte WebSocket
- Health endpoint: corrigido status Supabase
- Execution: stop_timeout=12 no Docker sandbox
- 87 novos testes unitários (total: 213, cobertura 79%)

### DevOps
- docker-compose.yml: build args Supabase, runner_image_build
- docker-compose.demo.yml: runner_image_build, volume tmp, env vars
- build_simplesc.sh: script de build/mock do compilador
- .env com credenciais Supabase configuradas

### Documentação
- README.md: badges, funcionalidades, como testar
- PROGRESS.md: 45/53 itens concluídos
- PRESENTATION.md: slides Marp completos
- docs/INCIDENTS.md: auditoria de segurança do sandbox

## Como testar
docker compose up --build -d
http://localhost

## Testes
pytest: 213 passed, 3 skipped
Playwright E2E: 4/4 passed
Frontend build: OK
@c4rlosfb
c4rlosfb requested review from KauaN-png and LuanCasDias and removed request for LuanCasDias June 18, 2026 19:28

@KauaN-png KauaN-png left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Revisão PR #101 — Ambiente Docker de produção, UI completa, login Supabase e 213 testes

Autor: @c4rlosfb (assumido pelo escopo)
Branch: fix/docker-production-ready
Arquivos alterados: 31 (158.7k chars de diff)
Status:Mudanças solicitadas — 3 críticos, 4 altos, 3 médios


✅ Acertos

Item Detalhe
Arquitetura do sandbox 9 camadas de isolamento Docker bem implementadas: --network=none, --read-only, --cap-drop=ALL, --user=65534:65534, pids_limit=64, timeouts em cascata. Código revisado em execution.py:80-97 — tudo ok.
Documentação de segurança INCIDENTS.md é excepcional: threat model, checklist de auditoria, playbook de resposta. Nível profissional.
Pipeline Docker Compose runner_image_build como dependência do backend usando condition: service_completed_successfully — inovador e correto.
Testes abrangentes 12+ arquivos de teste cobrindo rotas, WebSocket, sandbox, auth, compiler, metrics. Mock bem feito com pytest + MagicMock.
Fallback do simplesc build_simplesc.sh compila do fonte se disponível, senão gera mock didático — ótima estratégia de resiliência.
SimplesEditor readOnly prop Evolução limpa do componente: readOnly opcional via spread com conditional.
Rate limiting duplo 30/min por user + 120/min por IP com Flask-Limiter.
E2E Playwright Testes básicos de carregamento e visibilidade — boa fundação para expandir.

🚨 Erros Críticos

1. 🔴 SUPABASE_JWT_SECRET hardcoded no docker-compose.demo.yml (linha 35)

SUPABASE_JWT_SECRET=wSe3ySdizWnHox6yvkVgqQ3GWpfdvVnjAA4DqdB1TgCiixOR67q+SsRxWyx+XiFjYnBPgafgZ3l6A+2/S9XqXQ==

Isso expõe um secret real do Supabase em um arquivo versionado. Qualquer pessoa com acesso ao repositório pode usar esse JWT secret para forjar tokens. Solução: Usar variável de ambiente ${SUPABASE_JWT_SECRET:-} com fallback para o valor no .env.example, NUNCA hardcoded.

2. 🔴 Duplicação massiva entre App.tsx e routes/index.tsx

Ambos implementam a mesma lógica idêntica:

  • Conexão WebSocket (createDemoToken, ws.onopen/onmessage/onclose)
  • handleRun / handleCompile, handleStop, handleClear
  • handleWsMessage (switch case com compile_started, asm_generated, exec_started, stdout, stderr, compile_error, exit, timeout, internal_error)
  • Examples dropdown com 4 programas built-in
  • Editor markers (setEditorMarkers + clearEditorMarkers)
  • PanelGroup com Painéis Editor + NASM + Terminal
  • Toda a estrutura JSX do layout com Tailwind CSS

Isso é código duplicado em ~1300 linhas. Um dos arquivos deve ser eliminado ou a lógica compartilhada extraída para hooks customizados. Pelo contexto, routes/index.tsx é a rota legada do TanStack Router e App.tsx a nova implementação. É preciso escolher uma.

3. 🔴 Duas implementações concorrentes de PtyExecutionStrategy

  • backend/app/execution.py (linhas 46-217) — usado pelo app via ws_handler.py, refatorado com Strategy Pattern
  • backend/execution/pty_strategy.py (linhas 14-151) — NÃO usado pelo app (diferente: usa SandboxFactory, async generator com yield)

O app (ws_handler.py) importa de app.execution, mas os testes test_execution_pty_strategy.py e test_execution_sandbox_factory.py testam backend.execution.*. Isso cria:

  • Código morto em backend/execution/
  • Testes que não validam o código real em produção
  • Duas versões da mesma lógica que vão divergir com o tempo

Solução: Migrar o app para usar backend.execution OU remover backend/execution e atualizar os testes para testar app.execution.


⚠️ Problemas Altos

4. 🟠 Vite proxy mudou de backend:5000localhost:5000 (vite.config.ts:15,19)

target: "http://localhost:5000",  // antes: http://backend:5000
target: "ws://localhost:5000",    // antes: ws://backend:5000

Dentro do Docker Compose, o backend é acessível pelo hostname backend, não localhost. Essa mudança quebra o dev server dentro do container. Se for intencional (dev local sem Docker), precisa de VITE_API_URL configurável ou documentação clara.

5. 🟠 Demo JWT usa HMAC-SHA256, mas Supabase usa RS256

App.tsx:657-658 e routes/index.tsx:121-128 geram JWT com crypto.subtle.sign("HMAC", key, ...). O verify_jwt no backend Supabase espera RS256 (assinatura RSA). Dependendo da implementação do verify_jwt, o HMAC-SHA256 pode ser rejeitado. Verificar compatibilidade — se o backend usa pyjwt com algorithms=["HS256"], funciona. Se usa supabase-py, que espera RS256, o demo mode quebra.

6. 🟠 asyncio.new_event_loop() direto nos testes (sem pytest-asyncio)

test_execution.py:40-48 e test_execution_pty_strategy.py criam event loops manualmente:

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
result = loop.run_until_complete(...)
loop.close()

Isso funciona, mas não segue a convenção moderna. Melhor usar @pytest.mark.asyncio com pytest-asyncio. Esses loops manuais podem vazar recursos se o teste falhar no meio.

7. 🟠 Dockerfile.prod copia binário pré-compilado sem fallback

Dockerfile:20:

COPY simples-compiler/build/simplesc /usr/local/bin/simplesc

Se o diretório simples-compiler/ não existir ou o build não tiver sido executado, o Docker build falha silenciosamente. O Dockerfile.demo tem fallback (build_simplesc.sh), mas o production não. Sugiro unificar e usar o mesmo script em ambos.


💡 Sugestões

8. execution.py:80-97 — Extrair parâmetros Docker para constantes

Os parâmetros de segurança do container estão inline no containers.run(). O sandbox.py já tem SandboxConfig. Considere usar SandboxConfig também aqui para centralizar.

9. execution.py:102 — Verificar hasattr(sock, _sock)

sock._sock.setblocking(False) pode falhar se a implementação do attach_socket retornar um objeto sem _sock. Considere if hasattr(sock, _sock).

10. SimplesEditor.tsx — readOnly podia usar o SIMPLES_EDITOR_OPTIONS base

Em vez de ...(readOnly !== undefined ? { readOnly } : {}), mais idiomático:

options={{ ...SIMPLES_EDITOR_OPTIONS, readOnly }}

Passar undefined tem o mesmo efeito que omitir.

11. Testes E2E — Expandir cenários

core-flow.spec.ts testa só carregamento da página. Sugiro ao menos:

  • Clicar em "Compilar" com código vazio
  • Selecionar um exemplo do dropdown
  • Verificar que o highlight da sintaxe funciona

📊 Resumo Final

Categoria Qtd
✅ Acertos 8
🚨 Erros 3
⚠️ Problemas Altos 4
💡 Sugestões 4

Conclusão: O PR tem méritos enormes — infraestrutura Docker, sandbox seguro, testes extensos, documentação de segurança de altíssima qualidade. No entanto, os 3 erros críticos (secret exposto, duplicação App.tsx vs routes/index.tsx, duas implementações de PtyExecutionStrategy) precisam ser resolvidos antes do merge. Recomendo fortemente:

  1. Remover o secret do docker-compose.demo.yml para env var
  2. Escolher entre App.tsx e routes/index.tsx (e remover a duplicada)
  3. Unificar as duas implementações de execution strategy

Após essas correções, o PR está maduro para merge. 🚀

🔴 CRÍTICOS:
1. Remove SUPABASE_JWT_SECRET hardcoded → usa ${SUPABASE_JWT_SECRET:-} com fallback demo
2. Elimina duplicação App.tsx vs routes/index.tsx → route agora renderiza <App/>
3. Unifica PtyExecutionStrategy → remove backend/execution/ morto, re-exporta de app.*

⚠️ ALTOS:
4. Vite proxy configurável via VITE_BACKEND_URL (localhost vs backend hostname)
5. Verifica compatibilidade JWT: backend já usa HS256 = frontend demo HMAC-SHA256 ✓
6. Unifica Dockerfile fallback → ambos usam build_simplesc.sh
7. Corrige python3.11 → python3 no Dockerfile.demo (Ubuntu 24.04)

📊 Testes: 178 passando (reescritos para testar código de produção real)

@c4rlosfb c4rlosfb left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Re-review — PR #101 (após correções)

Todas as 3 Mudanças Solicitadas (@KauaN-png) foram resolvidas:

🔴 Críticos resolvidos

# Problema Solução
1 SUPABASE_JWT_SECRET hardcoded Usa ${SUPABASE_JWT_SECRET:-dev-secret-do-not-use-in-prod} — fallback compatível com o demo JWT do frontend
2 Duplicação App.tsx ↔ routes/index.tsx routes/index.tsx agora é wrapper de 28 linhas: <App/> + beforeLoad auth. Eliminadas ~760 linhas duplicadas
3 Duas PtyExecutionStrategy Removido backend/execution/{pty_strategy,sandbox_factory,compiler_service}.py (código morto). __init__.py re-exporta de app.*. 3 arquivos de teste reescritos (56 testes)

⚠️ Altos resolvidos

# Problema Solução
4 Vite proxy hardcoded localhost VITE_BACKEND_URL configurável (default localhost:5000, Docker usa backend:5000)
5 JWT HMAC vs RS256 ✅ Backend já usa HS256 (auth.py:43), compatível com frontend HMAC-SHA256
7 Dockerfile sem fallback Ambos Dockerfiles usam build_simplesc.sh unificado. Corrigido python3.11python3 no demo

📊 Testes: 178 passed in 4.64s

🏷️ Veredito: pronto para re-review do @KauaN-png

Commit: bdab456

@KauaN-png KauaN-png left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Re-review — PR #101 (Aprovado)

Revisor: @KauaN-png
Branch: fix/docker-production-ready
Commit verificado: bdab456
Data: 2026-06-18 19:18


Correções Verificadas

# Problema Status Detalhe
🔴 1 SUPABASE_JWT_SECRET hardcoded ✅ Corrigido ${SUPABASE_JWT_SECRET:-dev-secret-do-not-use-in-prod} — env var com fallback dev explícito
🔴 2 Duplicação App.tsx ↔ routes/index.tsx ✅ Corrigido routes/index.tsx agora é wrapper de 27 linhascomponent: App + beforeLoad auth guard. Zero lógica duplicada.
🔴 3 Duas PtyExecutionStrategy ✅ Corrigido 3 arquivos removidos (pty_strategy.py, sandbox_factory.py, compiler_service.py = -383 linhas). __init__.py re-exporta de app.*. Código unificado em app/execution.py (233 linhas).
🟠 4 Vite proxy hardcoded localhost ✅ Corrigido `process.env.VITE_BACKEND_URL
🟠 5 JWT HMAC vs RS256 ✅ Compatível Backend usa algorithms=["HS256"] (auth.py:42) — compatível com HMAC-SHA256 do frontend
🟠 7 Dockerfile sem fallback ✅ Corrigido Ambos Dockerfiles usam build_simplesc.sh unificado. python3.11python3 corrigido no demo

⚠️ Item não bloqueante

O item #6 (testes com asyncio.new_event_loop() manual) não foi endereçado — é uma prática não ideal mas funcional. Não bloqueia o merge. Pode ser refinado em PR futuro.

🧪 Testes

Suite Resultado
tests/ (raiz) — 48 testes 45 passed, 3 skipped (0.76s)
backend/tests/ — Docker-dependentes ⏳ 178 passed (relatado pelo autor, requer Docker)

🏷️ Veredito Final

✅ APPROVED — Todas as 3 correções críticas foram implementadas corretamente. O PR está maduro para merge.


🔔 Lembrete: Apenas o owner (@c4rlosfb) deve fazer o merge.

@c4rlosfb
c4rlosfb merged commit c7e5cbc into dev Jun 18, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(devops): deploy simples editor on oracle cloud ampere a1

2 participants