ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Simulados com quizzes gerados por IA a partir dos seus arquivos, com cronômetro e estatísticas. Python puro, PostgreSQL e JavaScript sem frameworks.
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗Site: acely.com.br · Repositório: Eduardo2049/QuizesStudies (o nome do repositório é anterior à marca).
Plataforma de simulados de alto rendimento e treino de raciocínio lógico. Transforme qualquer material em PDF, DOCX ou TXT (ou gere tópicos do zero) em simulados interativos com gabarito pedagógico e Caderno de Erros inteligente com mutações por IA.
Proposta de Valor Central: “Da sua apostila ao simulado ativo, com gabarito comentado.”
Menos tempo formatando flashcards, zero distração com fóruns poluídos e foco total na retenção de raciocínio.
Estudantes para concursos, certificações e vestibulares enfrentam três grandes problemas no mercado atual:
O Acely resolve isso unindo a extração instantânea de conteúdo à Mutação de Questões por IA: a IA identifica onde você errou e pode gerar variações inéditas mantendo o mesmo conceito teórico e nível de dificuldade, forçando a aplicação real do raciocínio.
| Critério / Ferramenta | Acely | Quizlet | QConcursos / Gran Cursos | Anki |
|---|---|---|---|---|
| Geração Instantânea por Material Próprio | Sim (PDF, DOCX, TXT) | Não (Manual ou listas públicas) | Não (Apenas banco próprio de bancas) | Não (Manual card a card) |
| Geração de Simulado por Tema via IA | Sim (OpenRouter, modelos gratuitos) | Limitado (em planos pagos) | Não | Não nativo |
| Caderno de Erros com Mutação IA | Sim (Gera variações inéditas) | Não (Apenas repete o card) | Não (Filtra questões estáticas) | Não (Repete o mesmo card) |
| Explicação Didática Passo a Passo | Sim (Imediata via IA) | Raras (Geralmente apenas definição) | Sim (Fórum / Comentários de profs) | Apenas se o usuário tiver escrito |
| Experiência Limpa e Sem Fricção | Sim (Modo foco + cronômetro) | Não (Gameficado/Anúncios) | Não (Poluído de propagandas e fórum) | Interface crua e curva alta |
| Acesso sem Cadastro | Sim (home aberta + 3 usos de IA como convidado) | Parcial (sets públicos) | Não | Sim (Local) |
# 1. Instalar dependências
pip install -r requirements.txt
# 2. Criar arquivo de variáveis de ambiente
cp .env.example .env
Edite o .env:
| Variável | Obrigatória | Descrição |
|---|---|---|
DATABASE_URL | ✅ | postgresql://user:password@host:5432/dbname |
POSTGRES_PASSWORD | ✅ Docker | Senha forte do PostgreSQL local |
ADMIN_USERNAME | Não | Usuário do administrador inicial (padrão: admin) |
ADMIN_PASSWORD | ✅ | Senha forte do administrador inicial |
ALLOWED_ORIGINS | Não | Lista separada por vírgulas de origens CORS permitidas |
COOKIE_SECURE | Não | Padrão true; use false apenas no desenvolvimento HTTP |
CLOUDFLARE_TUNNEL_TOKEN | Para Tunnel | Token do Cloudflare Zero Trust para expor via túnel HTTPS |
OPENROUTER_API_KEY | Para IA | Chave do OpenRouter. Só modelos gratuitos (:free) são usados; libere-os em Settings → Privacy e deixe ZDR Endpoints Only desligado (ele bloqueia todos os gratuitos) |
OPENROUTER_FREE_MODELS | Não | Modelos gratuitos preferidos, em ordem, separados por vírgula |
OPENROUTER_DISCOVER_FREE_MODELS | Não | Padrão true: descobre os modelos gratuitos disponíveis e usa como reserva |
OPENROUTER_MAX_ATTEMPTS | Não | Modelos tentados por pedido antes de desistir (padrão: 4) |
AI_DAILY_CALL_LIMIT | Não | Teto diário de chamadas de IA; deixe abaixo do limite gratuito do OpenRouter (50/dia sem créditos) |
AI_TOKEN_QUOTA_PER_HOUR | Não | Cota de tokens estimados por hora por IP (padrão: 50000) |
AI_DAILY_CALL_LIMIT | Não | Teto global de chamadas à IA a cada 24 h, somando todos os usuários (padrão: 1000; 0 desliga). Trava de emergência contra a conta do provedor estourar |
Sobe o PostgreSQL e a aplicação com um único comando:
docker compose up -d
Para subir também o Cloudflare Tunnel (expondo com HTTPS e proteção DDoS na Cloudflare):
docker compose --profile tunnel up -d
python quiz_api.py
O servidor inicia em http://localhost:8000 (ou próxima porta livre) e executa as migrations automaticamente na primeira vez.
localStorage (quiz_lang); na primeira visita segue o idioma do navegador.web/modules/i18n.js troca textos e atributos pelo dicionário web/modules/i18n/en.js e observa o que o app.js gera depois; web/modules/i18n-boot.js evita mostrar o português por um instante antes da tradução. Elementos com translate="no" não são tocados./api/quiz/generate, /api/upload e /api/quiz/remix-mistakes aceitam o campo language (pt-BR ou en; padrão pt-BR).web/modules/i18n/<código>.js, registre em LANGUAGES e DICTIONARIES (i18n.js), repita a regra em i18n-boot.js e acrescente o código em AI_LANGUAGES (api/services/ai_service.py).qs_guest) e com teto por IP. Os simulados ficam só no navegador e o upload vai até 5 MB. Ao esgotar a cota, a tela oferece a conta grátis./register e autenticação via /login (ou Google, se configurado). Ao entrar, os simulados criados como convidado na mesma aba são salvos na conta./termos e política em /privacidade. Em "Minha conta" a pessoa baixa uma cópia dos dados (GET /api/account/export) e exclui a conta (POST /api/account/delete, com senha). O token de sessão não vai no JSON do login (só no cookie HttpOnly); clientes de API pedem com "return_token": true. POSTs vindos de outro site são recusados.adminADMIN_PASSWORD no seu .env (obrigatório antes de iniciar).python scripts/reset_admin.py "NovaSenha123*"
python scripts/reset_sessions.py
A base de código é submetida a auditorias estáticas contínuas (SAST) com Semgrep utilizando o conjunto oficial de regras para OWASP Top 10, Python, Dockerfile e Web:
# Executar varredura estática de segurança
semgrep scan --config auto .
Dockerfile cria e executa o processo sob um usuário sem privilégios (appuser, UID 1000), prevenindo ataques de escape de container e execução indevida como root (dockerfile.security.missing-user.missing-user).api/services/ai_service.py utiliza a biblioteca requests com timeout explícito e validação estrita de protocolo HTTP/HTTPS, eliminando riscos de leitura local de arquivos via esquemas como file:// (python.lang.security.audit.dynamic-urllib-use-detected).RateLimiter genérico em api/handlers/quiz_handler.py protegendo rotas críticas (/api/auth/*, /api/upload, /api/quiz/generate).CF-Connecting-IP → primeiro IP confiável de X-Forwarded-For → endereço de socket (client_address).AI_TOKEN_QUOTA_PER_HOUR):
.env), impedindo o esgotamento malicioso da cota do OpenRouter.Strict-Transport-Security (HSTS com max-age=63072000; includeSubDomains; preload), X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy e Referrer-Policy.MAX_JSON_BYTES = 1 MB), upload com teto de 20 MB e whitelist de formatos (.txt, .pdf, .docx).Para disponibilizar sua aplicação com domínio próprio, HTTPS automático e proteção contra DDoS sem abrir portas no roteador:
http://app:8000.CLOUDFLARE_TUNNEL_TOKEN do seu arquivo .env.docker compose --profile tunnel up -d
Clique no botão "+ Adicionar Quiz" na interface. Você pode escolher entre duas formas:
Se você não tiver um documento pronto, digite o tema ou assunto desejado (ex: Raciocínio Lógico Proposicional, Python Básico, História do Brasil, Direito Constitucional), escolha o número de questões (3, 5 ou 10) e o nível de dificuldade. A IA elaborará todo o simulado com alternativas e explicações detalhadas!
Envie um arquivo nos formatos suportados:
.txt — texto estruturado ou em formato livre. O sistema conta com parser heurístico inteligente e adaptação via IA capaz de reconhecer perguntas e alternativas mesmo sem números de separação (1., 2.), marcadores padronizados ou com quebras de linha irregulares (respeitando o limite de peso de 20 MB)..pdf — documento PDF (extração automática de texto via pdfplumber).docx — documento Word (via python-docx)Se o arquivo não contiver gabarito, as respostas e justificativas são geradas automaticamente via IA (OPENROUTER_API_KEY, modelos gratuitos). Cada questão pode ter de 2 a N alternativas.
**1.** Enunciado da questão?
a) Opção A b) Opção B c) Opção C d) Opção D
**2.** Outra questão com alternativas em linhas separadas?
a) Opção A
b) Opção B
c) Opção C
# Gabarito
1. b) Opção B → Explicação da resposta.
2. a) Opção A → Explicação da resposta.
| Método | Rota | Autenticação | Descrição |
|---|---|---|---|
GET | / ou /index.html | Pública | Interface principal de simulados |
GET | /login ou /login.html | Pública | Página de autenticação |
GET | /register ou /register.html | Pública | Página de cadastro de estudante |
GET | /termos e /privacidade | Pública | Termos de uso e política de privacidade (LGPD) |
GET | /api/quizzes | Pública | Lista quizzes disponíveis (com cache HTTP e ETag / 304) |
GET | /api/quiz?source=<name> | Pública | Questões de um quiz (sem gabarito; com ETag / 304) |
POST | /api/quiz/submit | Pública | Submete respostas, salva tentativa e retorna score/gabarito |
GET | /api/user/attempts | Autenticado / Convidado | Histórico de tentativas e caderno de erros |
POST | /api/quiz/remix-mistakes | Convidado / Autenticado | Cria variações inéditas com IA para questões erradas (aceita language) |
POST | /api/quiz/generate | Convidado / Autenticado | Gera questões por tema via IA, com cache por hash (aceita language) |
POST | /api/auth/login | Pública | Login (sessão em cookie HttpOnly; o token só vem no JSON com "return_token": true) |
POST | /api/auth/register | Pública | Cadastro de estudante |
GET | /api/auth/me | Cookie / Bearer Token | Dados do usuário autenticado |
O projeto conta com suítes completas tanto para auditoria em ambiente isolado (sem custo de tokens) quanto para testes reais de carga contra o servidor ativo.
Nota sobre o CI: Os testes unitários (
python -m unittest discover tests) executam com PostgreSQL 16 real no pipeline de CI. Em ambiente local sem PostgreSQL disponível, o sistema faz fallback automático para SQLite em memória — funcional para desenvolvimento, mas não garante compatibilidade total com tipos PostgreSQL (ex:JSONB,SERIAL).
Valida a integridade do RateLimiter, cotas de tokens por IP e concorrência massiva:
python -m unittest tests/test_load_and_token_usage.py
429 Too Many Requests.X-Forwarded-For.Para testar a infraestrutura com geração real de questões via IA (POST /api/quiz/generate):
# Nível 1: Teste rápido de validação (5 chamadas, 1 worker, ~7k tokens)
python tests/load_test_real_api.py --calls 5 --workers 1 --guest --questions 3
# Nível 2: Carga moderada (10 chamadas, 3 workers, ~15k tokens)
python tests/load_test_real_api.py --calls 10 --workers 3 --guest --questions 5
# Nível 3: Teste de estresse com teto de 200k tokens
python tests/load_test_real_api.py --calls 50 --workers 5 --guest --questions 10 --token-limit 200000
# Nível 4: Rajada imediata para testar bloqueio 429 pelo Rate Limiter
python tests/load_test_real_api.py --calls 30 --workers 10 --burst --guest
8001, 8002, etc., evitando conflitos com serviços nativos do Windows (como IIS/HTTP.sys na porta 8000).OK, 429 BLOCKED, ERR), latência e barra de progresso do consumo acumulado de tokens.QuizesStudies/
├── api/
│ ├── database/
│ │ ├── connection.py # Context managers para PostgreSQL
│ │ └── migrations.py # Schema (executa na inicialização)
│ ├── controllers/
│ │ ├── auth_controller.py # Endpoints de login, registro e sessão
│ │ └── quiz_controller.py # Endpoints de quizzes e upload
│ ├── exceptions/
│ │ └── quiz_exceptions.py # Exceções de domínio
│ ├── handlers/
│ │ └── quiz_handler.py # Handler HTTP (GET/POST/OPTIONS)
│ ├── middleware/
│ │ └── http_middleware.py # CORS, cache, ResponseFormatter
│ ├── models/
│ │ └── dtos.py # Data Transfer Objects
│ ├── repositories/
│ │ ├── quiz_repository.py # Persistência de quizzes e questões
│ │ ├── rate_limit_repository.py # Contadores de rate limit e cotas
│ │ └── user_repository.py # Usuários, sessões, exportação e exclusão (LGPD)
│ ├── services/
│ │ ├── ai_service.py # IA via OpenRouter (só modelos gratuitos, troca automática de modelo)
│ │ ├── auth_service.py # Regras de hash e autenticação
│ │ ├── email_service.py # E-mail de redefinição de senha
│ │ ├── google_auth_service.py # Login com Google (OAuth)
│ │ ├── guest_service.py # Modo convidado e cota gratuita de IA
│ │ ├── import_service.py # Importa simulados do convidado para a conta
│ │ ├── quiz_service.py # Lógica de negócio de simulados
│ │ └── upload_service.py # Orquestração de upload TXT/PDF/DOCX
│ ├── utils/
│ │ ├── config.py # Variáveis de ambiente
│ │ ├── file_parser.py # Extração de texto (TXT/PDF/DOCX) e parse de questões
│ │ ├── quiz_logic.py # Correção e pontuação de respostas
│ │ └── validators.py # Validação de payloads HTTP
│ ├── index.py # Entrypoint Vercel (serverless)
│ └── main.py # Inicialização do servidor
├── web/
│ ├── app.js # Lógica client-side (SPA)
│ ├── index.html # Interface principal
│ ├── login.html # Tela de login moderna
│ ├── register.html # Tela de cadastro moderna
│ ├── reset-password.html # Troca de senha
│ ├── termos.html # Termos de uso
│ ├── privacidade.html # Política de privacidade (LGPD)
│ ├── modules/ # ES Modules (tema, idiomas, atalhos, estatísticas, ícones...)
│ │ ├── i18n.js # Tradução da interface (PT/EN)
│ │ ├── i18n-boot.js # Evita piscar o português antes da tradução
│ │ └── i18n/en.js # Dicionário em inglês
│ └── styles.css # Design system completo
├── 404.html # Página 404 própria
├── .env.example # Template de variáveis de ambiente
├── docker-compose.yml # PostgreSQL + app + tunnel
├── Dockerfile # Multi-stage (builder + runtime) com usuário non-root
├── Procfile
├── quiz_api.py # Entry point local
└── requirements.txt # Dependências (psycopg2, pdfplumber, requests, etc.)
-- Quizzes cadastrados
CREATE TABLE quizzes (
id SERIAL PRIMARY KEY,
name VARCHAR(255) UNIQUE NOT NULL, -- slug identificador
label VARCHAR(255) NOT NULL, -- nome de exibição
original_filename VARCHAR(255),
file_type VARCHAR(10) DEFAULT 'txt', -- 'txt' | 'pdf' | 'docx' | 'md'
has_answer_key BOOLEAN DEFAULT TRUE,
ai_generated BOOLEAN DEFAULT FALSE,
created_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
is_public BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP DEFAULT NOW()
);
-- Questões (options em JSONB suporta 2 a N alternativas)
CREATE TABLE questions (
id SERIAL PRIMARY KEY,
quiz_id INTEGER NOT NULL REFERENCES quizzes(id) ON DELETE CASCADE,
question_number INTEGER NOT NULL,
section VARCHAR(255) DEFAULT 'Geral',
context TEXT DEFAULT '',
question TEXT NOT NULL,
options JSONB NOT NULL, -- ["Opção A", "Opção B", ...]
answer INTEGER, -- índice base-0 (0=A, 1=B, ...)
explanation TEXT DEFAULT '',
UNIQUE (quiz_id, question_number)
);
CREATE INDEX idx_questions_quiz_id ON questions(quiz_id);
-- Usuários e Autenticação
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
salt VARCHAR(64) NOT NULL,
role VARCHAR(20) DEFAULT 'student',
created_at TIMESTAMP DEFAULT NOW()
);
-- Sessões (token armazenado como hash SHA-256)
CREATE TABLE sessions (
token VARCHAR(128) PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
expires_at TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_sessions_token ON sessions(token);
CREATE INDEX idx_sessions_user_id ON sessions(user_id);
-- Tentativas e Histórico de Desempenho (Caderno de Erros)
CREATE TABLE quiz_attempts (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
quiz_id INTEGER REFERENCES quizzes(id) ON DELETE SET NULL,
quiz_name VARCHAR(255) NOT NULL,
score INTEGER NOT NULL,
total INTEGER NOT NULL,
percentage INTEGER NOT NULL,
wrong_question_ids JSONB DEFAULT '[]'::jsonb,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_quiz_attempts_user_id ON quiz_attempts(user_id);
CREATE INDEX idx_quiz_attempts_quiz_id ON quiz_attempts(quiz_id);
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET | Não | Liga o botão "Entrar com Google". Redirect URI: <APP_URL>/api/auth/google/callback (defina APP_URL em produção) |
GUEST_AI_LIMIT | Não | Usos de IA do convidado por janela (padrão: 3; 0 desliga a IA para convidados) |
GUEST_AI_WINDOW_HOURS | Não | Janela da cota do convidado em horas (padrão e máximo: 24) |
GUEST_AI_IP_LIMIT | Não | Teto de usos de IA de convidados por IP na janela (padrão: 10), contra quem apaga cookies para renovar a cota |
TRUST_PROXY | Não | Confiar em headers de proxy (padrão: false, auto true na Vercel) |
PORT | Não | Porta do servidor (padrão: 8000) |
DEBUG | Não | Logs detalhados (padrão: false) |
semgrep scan --config auto . para verificar o status atual.POST | /api/auth/logout | Cookie / Bearer Token | Encerramento de sessão |
POST | /api/auth/forgot-password e /api/auth/reset-password | Pública | Pedido e troca de senha por e-mail |
GET | /api/auth/providers | Pública | Informa se o login com Google está ligado |
GET | /api/auth/google/start e /api/auth/google/callback | Pública | Login com Google (OAuth, state em cookie) |
POST | /api/guest/start, /api/guest/end · GET /api/guest/status | Pública | Sessão de convidado e cota gratuita de IA |
POST | /api/quizzes/import | Autenticado | Salva na conta os simulados criados como convidado |
GET | /api/account/export | Autenticado | Cópia dos dados da conta em JSON (LGPD) |
POST | /api/account/delete | Autenticado (com senha) | Exclui a conta e os dados |
POST | /api/upload | Autenticado (20 MB) / Convidado (?guest=1, 5 MB) | Upload multipart/form-data (TXT, PDF, DOCX); aceita language |