ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證App para preparar entrevistas técnicas de desarrollo web con IA y flashcards personalizadas.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
Practica entrevistas técnicas reales con IA — preguntas de código, feedback inmediato y cards para repasar. Mientras estudiaba programación y me preparaba para mi primer empleo, me di cuenta de que practicar entrevistas técnicas solo con teoría no funciona. Necesitaba preguntas reales de código, alguien que me dijera exactamente qué había fallado, y una forma de repasar lo aprendido. No encontré ninguna herramienta que hiciera las tres cosas a la vez sin costar dinero, así que la construí.檢視完整 README ↗
Practice real technical interviews with AI: code questions, instant feedback, and study cards to review later.
🌐 interviewkit.dev · Repository
While learning to code and preparing for my first job, I realised that practising technical interviews with theory alone doesn't work. I needed real code questions, someone telling me exactly what went wrong, and a way to review what I had learned.
I couldn't find a free tool that did all three, so I built one.
InterviewKit generates 5 questions (2 theory + 3 code) tailored to your stack and level, evaluates your answers with AI, and saves every concept as a Q&A card you can review whenever you want.
| Layer | Technology |
|---|---|
| Frontend | Next.js 15 + React 19 + TypeScript |
| Styling | Tailwind CSS v4 + shadcn/ui |
| Animations | Framer Motion |
| Code editor | CodeMirror |
| Backend | Flask 3 (Python 3.12) |
| Database | PostgreSQL 16 + SQLAlchemy |
| Migrations | Alembic (Flask-Migrate) |
| Auth | JWT in httpOnly cookies + OAuth 2.0 (Authlib) |
| Rate limiting | Flask-Limiter |
| AI | Groq API (openai/gpt-oss-120b) |
| Testing | pytest (backend), Vitest + Testing Library (frontend) |
| CI | GitHub Actions |
| Deployment | Vercel (frontend) + Fly.io (backend) |
┌──────────────────┐ HTTPS + cookies ┌──────────────────┐ ┌────────────┐
│ Next.js 15 │ ───────────────────▶ │ Flask REST API │ ──▶ │ PostgreSQL │
│ (Vercel) │ ◀─────────────────── │ (Fly.io) │ └────────────┘
└──────────────────┘ └────────┬─────────┘
│
┌────────▼─────────┐
│ Groq API │
│ question + eval │
└──────────────────┘
frontend/.nvmrc; with nvm or fnm, run nvm use inside frontend/)git clone https://github.com/albertsp/interviewkit.git
cd interviewkit
# Database
docker compose up -d
# Backend
cd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env # Fill in your keys (see below)
flask db upgrade
# Frontend
cd ../frontend
npm install
cp .env.example .env # NEXT_PUBLIC_API_URL=http://localhost:5000
# Terminal 1: backend
cd backend && flask run # http://localhost:5000
# Terminal 2: frontend
cd frontend && npm run dev # http://localhost:3000
The database container started in the setup step keeps running in the background.
backend/.env
| Variable | Required | Description |
|---|---|---|
JWT_SECRET_KEY | Yes | Secret used to sign JWTs. The app refuses to start without it. |
DATABASE_URL | Yes | e.g. postgresql://admin:admin@localhost:5432/interview_prep (matches docker-compose.yml). |
GROQ_API_KEY | Yes, for AI features | Groq API key used to generate and evaluate questions. |
FLASK_ENV | No | development locally, production when deployed. The /debug routes are only registered when it is not production. |
JWT_ACCESS_TOKEN_EXPIRES_HOURS | No | Lifetime of the access token. |
CORS_ORIGINS | Yes | Allowed frontend origins, e.g. http://localhost:3000. |
FRONTEND_URL | Yes | Where OAuth callbacks redirect the user. |
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET | For Google login | OAuth credentials. |
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET | For GitHub login | OAuth credentials. |
frontend/.env
| Variable | Description |
|---|---|
NEXT_PUBLIC_API_URL | Base URL of the backend, e.g. http://localhost:5000. |
Never commit real secrets. Use
.env.exampleas the template and keep.envfiles out of git.
All endpoints except /auth/*, /stacks and the OAuth flow require a valid JWT, sent as a cookie or as an Authorization: Bearer header.
| Method | Endpoint | Description |
|---|---|---|
POST | /auth/register | Create an account with email and password |
POST | /auth/login | Log in and set the session cookie |
POST | /auth/logout | Clear the session cookie |
GET | /auth/google, /auth/github | Start the OAuth flow (callbacks at /auth/<provider>/callback) |
GET | /stacks/ | Available roles, technologies and levels |
POST | /sessions/ | Start a session and generate 5 questions: 2 theory + 3 code (AI) |
PATCH | /sessions/<id>/questions/<qid> | Submit an answer and get AI feedback |
POST | /sessions/<id>/complete | Complete a session and award XP |
GET | /cards/ | List your study cards |
POST | /cards/ | Create a card from a question |
PATCH / DELETE | /cards/<id> | Edit or delete a card |
GET | /me/stats | Aggregated statistics, XP and level |
GET / PATCH | /me/profile | Read or update your profile |
GET | /debug/db | Database diagnostics (non-production only) |
POST | /auth/oauth/exchange | Exchange the one-time OAuth code for an access token |
GET | /health | Liveness and database check (no auth) |
Rate limits (AI endpoints): 5 session creations per hour and 15 answer evaluations per hour per user, plus a global shared limit of 20 per minute and 40 per day to protect the Groq free-tier budget.
XP rules: 100 XP for a correct answer, 50 for a partially correct one, 10 for an incorrect one, plus a 50 XP completion bonus. Every 500 XP is a level.
# Backend (SQLite in memory, no database or API keys needed)
cd backend
source venv/bin/activate # Windows: venv\Scripts\activate
pytest
# Backend with coverage
pytest --cov=app --cov-report=term-missing
# Frontend
cd frontend
npm test # single run
npm run test:watch # watch mode
The backend has tests for authentication, OAuth, models, sessions, cards, user stats and the AI service (with the Groq client mocked). The frontend has tests for the authentication context.
Continuous integration: .github/workflows/ci.yml runs on every push and pull request, with the backend and frontend jobs in parallel (Python 3.12 and Node 22, with dependency caching). Backend: ruff lint + pytest with coverage (minimum 85%, reported to Codecov). Frontend: tsc type-check + next lint + vitest. No secrets are required.
interviewkit/
├── .github/workflows/ci.yml # CI: pytest + npm test
├── backend/
│ ├── app/
│ │ ├── models/ # User, Session, Question, Card, OAuthAccount
│ │ ├── routes/ # auth, oauth, sessions, cards, user, stacks, debug
│ │ ├── services/ # Business logic and Groq integration
│ │ ├── constants/ # Gamification rules and stacks
│ │ ├── __init__.py # App factory, rate limiter, OAuth init
│ │ └── config.py # Configuration from environment variables
│ ├── migrations/ # Alembic migrations
│ ├── tests/
│ ├── Dockerfile
│ ├── fly.toml
│ └── requirements.txt
├── frontend/
│ ├── app/(app)/
│ │ ├── page.tsx # Landing page
│ │ ├── login/ · register/
│ │ ├── auth/callback/ # OAuth callback handler
│ │ └── (protected)/ # dashboard, session, stats, profile
│ ├── src/
│ │ ├── components/
│ │ ├── context/ # AuthContext
│ │ ├── services/ # API calls
│ │ └── __tests__/
│ └── public/
├── docker-compose.yml # Local PostgreSQL
└── README.md
Backend: Fly.io
cd backend && fly deploy
Migrations run automatically on every deploy (release_command in fly.toml). Set environment variables with fly secrets set, and make sure FLASK_ENV=production.
Frontend: Vercel
A push to main deploys automatically. Set NEXT_PUBLIC_API_URL in the Vercel dashboard.
Because the frontend and backend live on different domains, the auth cookie is set with SameSite=None; Secure, and CORS_ORIGINS must list the exact frontend origin.
Why Flask and not Django or FastAPI? Flask gave me full control over the structure without imposing patterns. For a REST API of this size Django would have been overkill, and FastAPI would have meant learning async from scratch at the same time.
Why Groq and not OpenAI? Groq has a generous free tier and very low latency. When the user is waiting for questions in real time, speed matters, and the hosted open-weight model is capable enough to generate quality technical questions.
Which model, and why?
The app uses openai/gpt-oss-120b on Groq. It replaced llama-3.3-70b-versatile, which Groq retired on 2026-08-16 and listed gpt-oss-120b as its recommended replacement. It is a production-tier model (the other candidates are previews), fast enough for real-time use, and strong enough for technical questions and feedback. The model name is set in backend/app/services/ai_service.py. Keep in mind it is a reasoning model, so its reasoning tokens count against the free-tier token limits (8K tokens per minute, 200K per day).
Two-layer rate limiting The Groq free tier has one budget shared by the whole app. I implemented two limits: per user (so one account can't drain it) and global (to protect the real budget). With only a per-user limit, a coordinated attack could still exhaust the quota.
OAuth login with a one-time exchange code The OAuth flow redirects from the backend to the frontend. Instead of putting the token in the URL (visible in history and logs), the backend sends a signed, one-time code (valid for 60 seconds) in the URL fragment, which browsers never send to a server. The frontend reads it, clears the address bar and exchanges it at POST /auth/oauth/exchange for the token. The token is stored in localStorage and also set as an httpOnly cookie. This is a compromise: some browsers (Safari, Brave) block the cross-site cookie, so the header is needed, at the cost of some XSS protection. Serving the API from a subdomain of the same site would let me drop localStorage.
Prompt injection mitigation
User answers go straight to the AI model for evaluation. I wrapped user input in ###ANSWER_START### / ###ANSWER_END### delimiters and added explicit instructions to the system prompt to treat that block as data, not as instructions.
The N+1 problem in statistics
The first version of /me/stats ran one query per session to fetch its questions. It's unnoticeable with little data but scales badly. I found it by inspecting the queries SQLAlchemy generated and fixed it with a single JOIN. I also added missing foreign-key indexes.
OAuth is more complex than it looks
Social login with Google and GitHub seemed simple until the details: cross-origin cookies require SameSite=None; Secure, the JWT can't travel in the URL, and you have to decide what happens when someone signs in with Google using an email that already has a password account. Every decision has security implications.
Global auth state in Next.js Coordinating session state between the server (httpOnly cookie) and the client (React Context) with the Next.js 15 App Router was the hardest frontend challenge. The protected layout has to handle the loading state correctly so it never shows protected content before the session is verified.
Designing the AI prompts The quality of the generated questions depends entirely on the prompt. Early versions produced overly theoretical questions ("What is a closure?"). Iterating on the system prompt to force concrete code questions in the code block was trial and error that took much longer than I expected. LLM output also needs defensive parsing (stripping markdown fences, fixing double-escaped newlines in code).
| Problem | Likely cause and fix |
|---|---|
RuntimeError about JWT_SECRET_KEY on startup | The variable is missing in backend/.env. |
connection refused on port 5432 | The database container isn't running: docker compose up -d. |
| Login works but you're immediately logged out | CORS_ORIGINS doesn't match the frontend origin, or cookies are blocked cross-origin. Check SameSite/Secure settings in production. |
429 Too Many Requests when starting a session | You hit a rate limit (see API overview). Wait and retry. |
| AI requests fail with 401 | GROQ_API_KEY is missing or invalid. |
pip install fails locally | Use Python 3.12 (the version used in the Dockerfile and CI). |
Contributions are welcome. Please read CONTRIBUTING.md for the setup, the checks that must pass and the commit conventions.
Released under the MIT License.