ESP32-S3 Bench Guide
ESP32‑S3 N16R8 벤치 가이드: 실시간 핀아웃, 강의, 시뮬레이터 및 벤치 로그
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기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.