ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻訳待ち
No updates detected yet. GitHub releases will appear here.
Classes, students, tasks and grades in one place
翻訳待ち
Loading the full README. The saved excerpt is shown below.
Everything about the classes I teach in one place: classes, students, tasks, scores with notes, term grades, and exports. Replaces a Google Drive full of spreadsheets. Next.js 16 (App Router) · Tailwind CSS 4 · PostgreSQL on Supabase · Drizzle ORM · next-intl (Español (Argentina) / English) · Vitest · hosted on Vercel.Read the full README ↗
Annora (the repository is still teaching-workspace) keeps everything about
the classes I teach in one place: classes, students, tasks, scores with notes,
term grades, attendance and exports. Replaces a Google Drive full of
spreadsheets.
Next.js 16 (App Router) · Tailwind CSS 4 · PostgreSQL on Supabase · Drizzle ORM · next-intl (Español (Argentina) / English) · Vitest · hosted on Vercel at annora.com.ar.
main, and the one-time GitHub/Vercel setup.Node 24, the version in .nvmrc (nvm use 24). CI and Vercel use the same
one: a lockfile written by another Node's npm can fail npm ci in CI.
npm install
npm run dev
Then open http://localhost:3000. Without a .env.local the app runs with
sign-in switched off and a banner saying so — enough to work on screens
offline.
npm test
npm run lint
npm run build
No Docker: development runs against a cloud Supabase project. Use two — dev
for working, prod for Vercel — so experiments never touch real grades.
Create a project at supabase.com.
Copy .env.example to .env.local and fill in the three values.
Create the tables (the migrations are in drizzle/):
npm run db:migrate
Then the private file bucket for task attachments and its access rules
(supabase/storage.sql):
npm run storage:apply
Turn on Google sign-in: in Google Cloud Console create an OAuth client
(Web application) with the redirect URI Supabase shows under
Authentication → Providers → Google, then paste its id and secret there.
Under Authentication → URL Configuration, add the address sign-in returns
to: http://localhost:3000/auth/callback in the dev project, and
https://annora.com.ar/auth/callback in the prod project, whose Site URL is
https://annora.com.ar. Sign-in returns to whatever domain the page is on,
so a new domain needs only this setting, not a code change.
The free plan pauses a project that gets too little activity over a week
(school holidays). One read every 3 days wasn't enough, so
.github/workflows/keep-supabase-awake.yml now touches each project twice a
day: one request through Supabase's API and one read on the database. It needs
four repository secrets, set once from a terminal in the project folder:
grep '^DATABASE_URL=' .env.local | cut -d= -f2- | gh secret set SUPABASE_DEV_DB_URL
grep '^DATABASE_URL=' .env.prod | cut -d= -f2- | gh secret set SUPABASE_PROD_DB_URL
grep '^NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=' .env.local | cut -d= -f2- | gh secret set SUPABASE_DEV_PUBLISHABLE_KEY
The prod publishable key isn't in .env.prod: copy it from the prod project's
Project Settings → API Keys, run this and paste it at the prompt:
gh secret set SUPABASE_PROD_PUBLISHABLE_KEY
A missing secret fails the run, and GitHub emails about it. If a project does get paused, restoring it is one click in the dashboard; nothing is lost.
src/
app/
page.tsx the public home page (signed-in teachers skip it)
privacidad/ the privacy policy, public
(app)/ signed-in pages: dashboard, classes, students, settings
login/ Google sign-in
auth/callback/ finishes the Google sign-in
components/ presentation only
db/ schema.ts (the data model) and the connection
i18n/ language config; texts live in messages/
lib/
access.ts who can open which page, pure and tested
grading.ts grading rules, pure and tested
supabase/ auth clients
proxy.ts refreshes the session; sends signed-out users to /login
(except from the home page), signed-in ones from / and
/login to /dashboard
messages/ es-AR.json, en.json
drizzle/ generated SQL migrations
docs/