ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
An AI-powered career workspace: build a resume, generate tailored cover letters, practice interviews with AI-generated quizzes, and get personalized industry insights — all from one profile.
Try it live: (add your Vercel URL here after deploying)
Demo login: [email protected] / Demo@1234 — or just click "Try demo account" on the login page. No signup needed, no email verification, pre-populated with a sample resume and cover letter so there's something to look at immediately.檢視完整 README ↗An AI-powered career workspace: build a resume, generate tailored cover letters, practice interviews with AI-generated quizzes, and get personalized industry insights — all from one profile.
Try it live: (add your Vercel URL here after deploying)
Demo login: [email protected] / Demo@1234 — or just click "Try demo account" on the login page. No signup needed, no email verification, pre-populated with a sample resume and cover letter so there's something to look at immediately.
| Layer | Choice |
|---|---|
| Framework | Next.js 15 (App Router + a few legacy Pages Router API routes) |
| UI | React 19, Tailwind CSS v4, shadcn/ui (Radix primitives) |
| Database | PostgreSQL via Prisma ORM (Neon in production) |
| AI | Google Gemini → Groq → OpenAI fallback chain (see diagram below) |
| Auth | JWT in an httpOnly cookie, bcrypt password hashing |
| Nodemailer via Brevo SMTP (or console-logged in local dev) | |
| PDF export | @react-pdf/renderer |
| E2E testing | Playwright |
graph TB
Browser["Browser"]
subgraph Vercel["Vercel — Next.js App Router"]
MW["Middleware<br/>(route protection)"]
Pages["Pages / Server Components"]
Actions["Server Actions<br/>(actions/*.js)"]
API["Legacy API Routes<br/>(pages/api/*)"]
end
subgraph Data["Data"]
Neon[("Neon PostgreSQL")]
end
subgraph AI["AI provider chain"]
Gemini["Google Gemini<br/>(primary)"]
Groq["Groq<br/>(free fallback)"]
OpenAI["OpenAI<br/>(optional fallback)"]
end
subgraph Services["Other services"]
Brevo["Brevo SMTP<br/>(OTP emails)"]
end
Browser --> MW --> Pages
Pages --> Actions
Pages --> API
Actions --> Neon
API --> Neon
API --> Brevo
Actions --> Gemini
Gemini -. on failure .-> Groq
Groq -. on failure .-> OpenAI
flowchart TD
A["Land on '/'"] --> B["Register or click\n'Try demo account'"]
B --> C{"Verified?"}
C -->|New user| D["Email OTP"]
D --> E["Login"]
C -->|Demo account| E
E --> F{"Onboarding\ncomplete?"}
F -->|No| G["Onboarding:\nindustry, experience, skills"]
G --> H["Dashboard"]
F -->|Yes| H
H --> I["Resume Builder"]
H --> J["Cover Letter Generator"]
H --> K["Mock Interview"]
H --> L["Industry Insights"]
I --> M["Download one-page PDF"]
Every AI call (quiz generation, improvement tips, industry insights) goes through lib/ai-generate.js, which tries providers in order and only moves to the next one on a real failure — never as a race.
sequenceDiagram
participant U as Server Action
participant G as Gemini
participant Q as Groq (free)
participant O as OpenAI (optional)
U->>G: generateContent(prompt)
alt succeeds
G-->>U: text
else 503 / 429 / network error
loop up to 3 retries, exponential backoff
U->>G: retry
end
alt still failing
U->>Q: chat.completions.create(prompt)
alt Groq succeeds
Q-->>U: text
else Groq unavailable / not configured
U->>O: chat.completions.create(prompt)
O-->>U: text
end
end
end
erDiagram
User ||--o| Resume : has
User ||--o{ CoverLetter : has
User ||--o{ Assessment : has
User }o--o| IndustryInsight : "belongs to"
User {
string id PK
string email UK
string password
boolean isAccountVerified
string industry
int experience
string_array skills
string bio
}
Resume {
string id PK
string userId FK
string content "JSON resume data"
float atsScore
}
CoverLetter {
string id PK
string userId FK
string companyName
string jobTitle
string content
string status
}
Assessment {
string id PK
string userId FK
float quizScore
json_array questions
string improvementTip
}
IndustryInsight {
string id PK
string industry UK
json_array salaryRanges
float growthRate
string demandLevel
string_array topSkills
string marketOutlook
}
git clone https://github.com/prerna701/ai-career-coach.git
cd ai-career-coach
npm install
docker compose up -d postgres
cp .env.example .env
Then fill in .env — see Environment variables below. For local dev you can leave EMAIL_BACKEND="console" so OTPs print to the terminal instead of requiring real SMTP.
npx prisma migrate deploy
npm run seed:demo # optional: creates the [email protected] account
npm run dev
Visit whatever URL Next.js prints (usually http://localhost:3000, but it'll pick another free port if that one's taken).
| Variable | Required | Notes |
|---|---|---|
DATABASE_URL | Yes | Postgres connection string |
JWT_SECRET | Yes | Any long random string (openssl rand -hex 32) |
GEMINI_API_KEY | Yes | Free tier at aistudio.google.com/apikey |
GROQ_API_KEY | No | Free fallback if Gemini is overloaded — console.groq.com/keys |
OPENAI_API_KEY | No | Second fallback, only if you have a paid OpenAI key |
EMAIL_BACKEND | No | Set to "console" for local dev to log OTPs instead of sending them. Never set this in production. |
EMAIL_HOST / EMAIL_PORT / EMAIL_USER / EMAIL_PASS / EMAIL_FROM | Yes (unless EMAIL_BACKEND=console) | SMTP credentials — Brevo has a free tier (300 emails/day) |
| Command | What it does |
|---|---|
npm run dev | Start the dev server |
npm run build | Production build |
npm start | Run a production build |
npm run seed:demo | Seed the public demo account (safe to run against production) |
npm run seed:e2e | Seed a test account used by the E2E suite |
npm run test:e2e | Run the Playwright E2E suite (e2e/generation-flows.spec.js) |
npx prisma migrate deploy against it onceEMAIL_BACKEND unset in Vercel — it exists only to disable email sending in local devnpm run seed:demo once against your production DATABASE_URL if you want the demo account live there toopublic/uploads), which doesn't persist on Vercel's serverless functions. Works fine in local dev / on a traditional server; needs Vercel Blob or S3 to work in production.ai-career-coach/
├── app/
│ ├── (auth)/ # login, register, OTP verification, password reset
│ ├── (main)/ # onboarding, dashboard, resume, cover letter, interview
│ ├── layout.js # root layout, forced dark theme
│ └── page.jsx # landing page
├── actions/ # server actions (data + AI generation)
├── components/
│ ├── landing/ # landing page sections
│ ├── ui/ # shadcn/ui primitives
│ └── auth/ # shared auth form fields
├── lib/
│ ├── ai-generate.js # Gemini → Groq → OpenAI fallback chain
│ ├── ai-retry.js # retry-with-backoff for transient AI failures
│ ├── auth.js / jwt.js # session handling
│ └── mailer.js # SMTP / console email backend
├── pages/api/ # legacy auth + user API routes
├── prisma/ # schema + migrations
├── scripts/ # seed-demo-user.cjs, seed-e2e-user.cjs
├── e2e/ # Playwright tests
└── docker-compose.yml # local Postgres (+ migrate/seed service)
npm run test:e2e
Runs a real browser against the app (auth bypassed via a signed JWT, matching how the app itself issues sessions) and verifies the three core generation flows end to end: resume save, cover letter generation, and interview quiz generation — checking actual database state, not just UI text.