Generate flashcards from any text using Claude Haiku 4.5.
A clean rewrite of the original hackathon project (Strawcabbage/SmartCards + Strawcabbage/SmartCards_Server). Same features, single Next.js app on Vercel, no leaked API keys, no committed node_modules.
The original React + Spring Boot code lives in archive/ for reference. The original Auth0 setup is preserved at archive/auth0/.
Status: deployed at https://madhacks24-smartcard.vercel.app. Auth is now a minimal email + password system (Neon Postgres + bcrypt + JWT cookie) so the demo stays online without a hosted Auth0 tenant.
| Concern | Choice |
|---|---|
| Framework | Next.js 16 (App Router, TypeScript) |
| LLM | Vercel AI SDK + @ai-sdk/anthropic (Claude Haiku 4.5) |
| Auth | Email + password — bcryptjs + jose JWT cookie |
| Database | Neon Postgres (free tier via Vercel Marketplace) |
| File parsing | pdf-parse (PDF), mammoth (DOCX) |
| Hosting | Vercel |
- Sign up / log in / log out / delete account (cascade-deletes the user's sets)
- Paste text or upload
.txt/.pdf/.docx - Extract key terms via the selected LLM
- Auto-generate term/definition flashcards
- View (flip), edit, delete flashcards
- Persist sets and flashcards in Postgres (scoped per user)
npm install
cp .env.example .env.local
# fill in the values (see below)
npm run devOpen http://localhost:3000.
| Var | What it is |
|---|---|
ANTHROPIC_API_KEY |
Anthropic API key from https://console.anthropic.com/settings/keys. |
DATABASE_URL |
Neon Postgres connection string. On Vercel: provision Neon from the Marketplace and it's set automatically. |
JWT_SECRET |
Symmetric key for signing session cookies. Generate with openssl rand -hex 32. |
To change models, edit MODEL in lib/llm.ts.
vercel link # link to a new project
vercel env pull # pulls env vars locally after configuring them in dashboard
vercel --prod # deploysThen in the Vercel dashboard:
- Storage → Marketplace → Neon: provision a free Postgres instance.
DATABASE_URLis auto-injected. - Settings → Environment Variables: add
ANTHROPIC_API_KEYandJWT_SECRET(openssl rand -hex 32).
The schema (users, sets, flashcards) is created automatically on first request via ensureSchema() in lib/db.ts.
app/
page.tsx # server component, gates on session, redirects to /login
login/ # /login page + form
signup/ # /signup page + form
SmartCardsApp.tsx # main client UI (incl. Log Out + Delete Account)
globals.css # ported from original App.css
api/
auth/signup/route.ts # POST: create account + set cookie
auth/login/route.ts # POST: verify password + set cookie
auth/logout/route.ts # POST: clear cookie
auth/me/route.ts # GET: current user
auth/delete/route.ts # DELETE: delete account + cascade
extract/route.ts # POST: text → key terms
flashcards/route.ts # POST: terms → flashcards
flashcards/[id]/route.ts # DELETE (scoped to owner)
upload/route.ts # POST: .txt/.pdf/.docx → text
sets/route.ts # GET / POST sets (scoped to owner)
sets/[id]/flashcards/ # POST: insert flashcards into a set (ownership checked)
lib/
llm.ts # Anthropic Claude Haiku 4.5 via @ai-sdk/anthropic
db.ts # Neon client + schema (users, sets, flashcards)
auth.ts # bcrypt + JWT + cookie helpers + getCurrentUser()
archive/ # original hackathon code (read-only reference)
archive/auth0/ # the original Auth0 setup, replaced by lib/auth.ts
- @zlichtman (Zach)
- @Strawcabbage (Jackson)
- @ash13y16 (Ashley)
- @shunny2005 (Shantanu)