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.