ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Portal de disciplinas do curso de Analise e Desenvolvimento de Sistemas - IFCE Campus Horizonte. Guia do aluno e, de proposito, exemplo real de programacao web.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Portal de Disciplinas — IFCE Campus Horizonte Guia do aluno das disciplinas do curso de Tecnologia em Análise e Desenvolvimento de Sistemas. Começa servindo Sistemas Operacionais (ADS23); a arquitetura é multi-disciplina desde o primeiro commit. O projeto tem dupla função: é o portal que os alunos usam e um exemplo real de programação web moderna — o código é público de propósito, para ser lido em Programação Web I/II.查看完整 README ↗
No ar: https://portal-ads-henna.vercel.app
Guia do aluno das disciplinas do curso de Tecnologia em Análise e Desenvolvimento de Sistemas. Começa servindo Sistemas Operacionais (ADS23); a arquitetura é multi-disciplina desde o primeiro commit.
O projeto tem dupla função: é o portal que os alunos usam e um exemplo real de programação web moderna — o código é público de propósito, para ser lido em Programação Web I/II.
| Camada | Tecnologia |
|---|---|
| Framework | Next.js 15 (App Router) · React 19 · TypeScript |
| Estilo | Tailwind CSS v4, com a paleta institucional em src/app/globals.css |
| Conteúdo | Módulos TypeScript tipados em src/content/; roteiros em MDX (@next/mdx + remark-gfm) |
| Deploy | Vercel (plano Hobby) |
| Banco | Supabase — PostgreSQL + Auth, acessado só pelo servidor (@supabase/supabase-js, @supabase/ssr), com validação em Zod |
npm install
npm run dev # http://localhost:3000
Outros comandos:
npm run build # build de produção
npm run typecheck # tsc --noEmit
npm run lint # ESLint
npm test # testes das regras de nota (Vitest)
npm run banco:copiar # cópia de segurança do banco e dos PDFs em curso/backups/
npm run material:preparar # prepara o material publicado (as duas tarefas abaixo)
npm run material:voltar # injeta o botão "voltar ao portal" nos HTMLs de material
npm run material:indexar # regenera o índice dos arquivos de material
Não rode
npm run buildcom onpm run devaberto. Os dois escrevem no mesmo diretório.next, e o build sobrescreve os chunks que o servidor de desenvolvimento já tinha carregado. O sintoma é um erro do tipoCannot find module './331.js'vindo dowebpack-runtime. A correção é parar o servidor, apagar.nexte subir de novo:rm -rf .next # PowerShell: Remove-Item .next -Recurse -Force npm run dev
src/
app/
layout.tsx fontes, paleta e metadados de compartilhamento
page.tsx capa do portal (lista de disciplinas)
icon.svg favicon do portal
opengraph-image.tsx prévia do link (gerada no build, 1200×630)
robots.ts · sitemap.ts derivados da camada de conteúdo
[disciplina]/
layout.tsx cabeçalho, navegação e rodapé da disciplina
page.tsx visão geral: próximo encontro, ementa, avaliação
encontros/page.tsx índice dos encontros por etapa
encontros/[numero]/page.tsx página de um encontro: material, Docker, leituras
cronograma/page.tsx tabela de datas e marcos
leituras/page.tsx mapa de leituras completo
avaliacao/page.tsx projeto integrador, marcos e rubricas
components/ UI compartilhada (selos, cartões, listas)
content/
tipos.ts os tipos de todo o conteúdo
disciplinas.ts registro multi-disciplina
index.ts slug → conteúdo (único ponto que conhece as disciplinas)
materiais.gerado.ts ARQUIVO GERADO — índice dos HTMLs em public/
so/ conteúdo de Sistemas Operacionais
lib/
datas.ts formatação de datas em pt-BR
site.ts endereço público do site (metadata, sitemap)
public/material/<disciplina>/<pasta>/ slides em HTML avulso
supabase/migrations/ SQL do banco (aplicado no painel do Supabase)
Os nomes dos arquivos de material são longos e escritos à mão
(Encontro-07_Concorrencia-Condicao-de-Corrida.html). Em vez de repetir esses nomes no código —
onde um erro de digitação vira link quebrado em produção —, o script scripts/indexar-materiais.mjs
lê o que existe em public/material/ e gera src/content/materiais.gerado.ts.
Publicar material novo:
# 1. copie os HTMLs para public/material/so/aulaN/
npm run material:preparar
git add -A && git commit -m "Publica material do Encontro N"
Se o arquivo não existe em disco, ele simplesmente não aparece no site.
Os roteiros vivem em src/content/so/roteiros/<numero>.mdx e usam os componentes de
src/components/aula.tsx (<Passo>, <Comando>, <Terminal>, <Dica>, <Checklist>…). A rota
/so/encontros/<n>/roteiro só existe se o .mdx existir; enquanto não existir, a página do
encontro continua oferecendo o HTML avulso. Os dois nunca aparecem juntos.
Os 18 (Semana 0 + 17 encontros) já foram migrados. Diferente do HTML original, o que o aluno
escreve nos rascunhos de observação e marca no checklist sobrevive ao recarregamento — fica no
navegador dele (localStorage), não no servidor.
scripts/converter-roteiro.mjs fez a conversão inicial a partir do HTML. Ele relata todo bloco
que não reconhece em vez de descartá-lo em silêncio — omissão em material didático é pior que erro
visível, porque ninguém nota que um passo sumiu.
Cada encontro com leitura tem um quiz em /so/encontros/<n>/quiz: perguntas de múltipla escolha
sobre a leitura e as observações do laboratório, num envio só. O conteúdo fica em
src/content/so/quizzes.ts, versionado; o banco guarda só os envios.
src/lib/acoes-quiz.ts), que valida com Zod, corrige no servidor e grava com a chave secreta.
A página não recebe o gabarito nem as justificativas; eles só voltam na resposta ao envio.submissoes_quiz: a chave pública não lê nem
grava nada nela.localStorage dos rascunhos do roteiro: o que o aluno
escreveu durante a prática chega preenchido. Quem é o aluno não fica guardado, porque os
computadores do laboratório são compartilhados.Com a turma importada, o aluno escolhe o nome numa lista em vez de digitar nome e matrícula — tanto no quiz quanto na entrega do relatório. Some assim a fonte de erro mais cara do semestre: matrícula digitada errada, que faz o envio não cair no portfólio de ninguém.
A importação é feita no painel, aba Turma (/professor/turma): anexe o CSV exportado do
diário e o portal mostra o que vai mudar (quem entra, quem muda de nome, quem sai) antes de gravar.
Linha fora do formato faz a importação inteira ser recusada. A leitura do CSV e a comparação com
a lista atual são funções puras, com testes, em src/lib/importar-turma.ts; o arquivo salvo de
novo pelo Excel (Windows-1252) também é lido com os acentos certos.
turma_alunos), nunca em src/content/: este repositório é
público e nome de aluno é dado pessoal. O CSV fica em curso/, que está no .gitignore.src/lib/acoes-turma.ts) e traz só nome e um identificador opaco; é o servidor que
resolve a matrícula oficial ao gravar o envio. Como o carregamento não é feito no build, a lista
também não entra no HTML estático nem em buscador./professor é o painel: login pelo Supabase Auth, aceito só para o e-mail de PROFESSOR_EMAIL.
Tem seis abas: envios por quiz (com as marcas do professor e o botão de desconsiderar um
envio), portfólio consolidado por etapa, entregas (PDF e .zip), roteiros do professor, a lista
da turma e o calendário do semestre, com exportação .csv onde faz sentido.Os quizzes começaram como HTML avulso que gravava com window.storage, uma API que só existe
dentro dos artefatos do Claude. Publicados no portal, eles não salvavam nada. Por isso saíram de
public/material/, e os endereços antigos redirecionam para o quiz nativo (next.config.ts).
Sem as variáveis do Supabase o portal funciona normalmente: os quizzes aparecem, mas o envio avisa que ainda não está ativo.
As regras de nota de SO vivem em src/content/so/avaliacao.ts: pesos de cada etapa, valor de cada
quiz, descarte do pior, prazos e rubricas. A página de avaliação, a página do quiz, o enunciado do
projeto e o painel leem dali. Mudar um peso é mudar esse arquivo; os prazos também podem ser
ajustados pelo painel, como explicado logo abaixo.
As datas são editáveis pelo painel. O planejamento do semestre continua no código
(encontros.ts, avaliacao.ts, curso.ts); a aba Calendário de /professor grava só os
ajustes, na tabela calendario_ajustes: data de encontro, prazo de quiz, prazo de entrega e dias
sem aula. src/lib/ajustes-calendario.ts aplica a precedência (função pura, com testes) e
conteudoVigente(slug), em src/lib/calendario.ts, é a porta de entrada de toda página e ação
que lida com data. Salvar regenera o site em instantes, sem deploy; com o banco fora do ar, vale o
planejamento. Desenho completo em docs/superpowers/specs/2026-10-06-calendario-editavel-design.md.
src/lib/portfolio.ts, com funções puras. A leitura do banco para o painel fica
em src/lib/painel-quiz.ts.src/content/so/projetos/<etapa>.mdx, publicado em
/so/projeto/<etapa>, com o formulário de envio do PDF.src/lib/acoes-entrega.ts): o servidor gera uma URL
assinada de uso único para um caminho no bucket privado relatorios, e o navegador envia direto
ao Supabase. Isso contorna o limite de 4,5 MB do corpo das funções da Vercel. Depois o servidor
confere que o arquivo chegou e registra a entrega. O professor baixa por URL assinada de 60 s.avaliacao.ts declara formato: "pdf" (relatórios
da 1ª etapa) ou "zip" (toolkit da 2ª). A regra do arquivo — tipo, extensão e 15 MB — fica em
src/lib/arquivo-entrega.ts, usada igualmente pelo formulário e pelo servidor; o bucket repete a
regra por conta própria.supabase/migrations/..env.example para .env.local e preencha. Na Vercel, cadastre as mesmas variáveis e
faça um novo deploy.O plano gratuito do Supabase pausa o projeto depois de cerca de uma semana sem uso, e pausado o
envio de quiz e de relatório falha. Um agendamento da Vercel (vercel.json) chama
/api/manter-ativo uma vez por dia; a rota só conta os alunos da turma, o que basta para o banco
contar como usado. Exige a variável CRON_SECRET na Vercel.
O plano gratuito também não oferece backup para baixar. Para ter uma cópia no computador:
npm run banco:copiar
O comando só lê o banco e cria curso/backups/<data-hora>/ (fora do git) com cada tabela em
.json (cópia fiel, para restaurar) e .csv (para abrir no Excel), os PDFs dos relatórios e um
resumo.txt com as contagens. Vale rodar depois de cada prazo de entrega. Para restaurar uma
tabela, importe o .json pelo painel do Supabase ou peça ajuda — não há restauração automática.
Os HTMLs de material foram escritos antes do portal: são documentos avulsos, com CSS próprio e
nenhuma navegação. Aberto a partir de um encontro, o aluno entrava no material e ficava sem
caminho de volta. scripts/injetar-volta-ao-portal.mjs insere em cada um deles um botão fixo
"← Voltar ao Encontro N", entre marcadores <!-- portal:voltar:… --> — rodar de novo substitui o
bloco em vez de duplicar. É uma medida de transição: na fase 2 o material passa a ser MDX
renderizado dentro do portal, e o botão deixa de ser necessário.
A paleta é a mesma dos materiais dos encontros, derivada das cores oficiais do Manual de Aplicação
da Marca IF: teal #1b878f como primária, verde IF #399b3f como secundária, vermelho IF
#cd191e reservado para alerta, sobre fundo creme #fbfaf5. Blocos de terminal permanecem
escuros (#10161f) por contraste técnico. Tipografia: Space Grotesk (títulos), IBM Plex Sans
(texto) e IBM Plex Mono (código).
Os tokens ficam em @theme, no globals.css — trocar a paleta de uma disciplina futura é mexer
num arquivo só.
O site é estático (SSG, com revalidação de 1 h nas páginas que destacam o próximo encontro) e vai
ao ar pela Vercel: cada git push na main publica em produção; cada branch ganha uma URL de
preview.
Publicado em 06/08/2026. Repositório: https://github.com/steliobastos/portal-ads · produção: https://portal-ads-henna.vercel.app.
Publicar uma mudança é dar git push na main — a Vercel constrói e coloca no ar em cerca de um
minuto. Branches ganham URL de preview automaticamente.
| Variável | Onde | Para quê |
|---|---|---|
NEXT_PUBLIC_SITE_URL | opcional | Endereço absoluto do site. Só é necessária quando houver domínio próprio — na Vercel, src/lib/site.ts já usa VERCEL_PROJECT_PRODUCTION_URL automaticamente. Em desenvolvimento, o padrão é http://localhost:3000. |
SUPABASE_URL | quiz | Endereço do projeto Supabase |
SUPABASE_PUBLISHABLE_KEY | quiz | Chave pública, usada só no login do professor |
SUPABASE_SECRET_KEY | quiz | Chave secreta, que ignora a RLS. Só no servidor |
PROFESSOR_EMAIL | quiz | Único e-mail com acesso a /professor |
CRON_SECRET | Vercel | Segredo do agendamento diário (vercel.json) que chama /api/manter-ativo para o Supabase gratuito não pausar o banco por falta de uso. A Vercel o envia sozinha nas chamadas agendadas |
O endereço absoluto alimenta o metadataBase (prévia do link em WhatsApp e Classroom), o
sitemap.xml e o robots.txt.
sitemap.xml/robots.txt e deploy na VercelRoteiros de condução, checklists e rubricas ficam em curso/, fora do git: o repositório é
público. Por isso não entram no build. npm run professor:publicar, rodado só na máquina do
professor (usa o .env.local), espelha curso/**/*.md num bucket privado do Supabase. A aba
Roteiros de /professor lê de lá, com sessão conferida. Editou um roteiro? Rode o script de novo;
não precisa de deploy.