Skip to content

feat(academy): add AI flashcard studio with Anki export#4229

Open
federiconardelli7 wants to merge 20 commits into
masterfrom
feat/academy-flashcards
Open

feat(academy): add AI flashcard studio with Anki export#4229
federiconardelli7 wants to merge 20 commits into
masterfrom
feat/academy-flashcards

Conversation

@federiconardelli7

@federiconardelli7 federiconardelli7 commented May 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds AI-powered flashcards to the Builders Hub Academy across five connected surfaces — on-demand Anki export, an AI generation studio, an in-app study player, per-course standard decks,
and a personal deck library — plus a one-line Turbopack build unblock.

What ships

1. Anki download for existing in-app flashcards. The existing <Flashcard flashcardSetId="..." /> component gets an Anki icon in its header. Clicking it downloads a .apkg built on
demand from flashcardData.json. Anonymous, no rate limit, idempotent. Route: GET /api/flashcards/download/[setId].

2. Flashcard Studio. /academy/flashcards lets logged-in users multi-select chapters from any Academy course (search + collapsible tree), pick a target card count (10–50), and POST /api/flashcards/generate. The route reads selected MDX, strips JSX (preserving fenced code blocks), builds a prompt for Claude (claude-sonnet-4-6 via @ai-sdk/anthropic), validates
with Zod, dedupes by text-embedding-3-small cosine similarity (threshold 0.88), and returns the deck. Source input is hard-capped at 100k tokens. Preview at
/academy/flashcards/[sessionId] renders Q&A, cloze, and code cards with per-card keep / reject / regenerate (single-card regen via POST /api/flashcards/regenerate-card). Final
deck downloads as .apkg (POST /api/flashcards/studio-download). Rate-limited per authenticated user: 10 deck generations / 24h, 30 card regenerations / hr.

3. In-app study player. /academy/flashcards/play/[setId] (standard decks) and /academy/flashcards/play/user/[deckId] (saved decks) provide a full study mode — flip,
spaced-repetition rating buckets, progress tracking, and keyboard shortcuts (Space to flip, 1/2/3 to rate, arrows to navigate), with responsive mobile layout.

4. Standard per-course decks. Each Academy course ships a baked ~50-card standard deck (resolved via lib/flashcards/catalog.ts + deck-resolver.ts), surfaced through a deck picker
and the flashcards dropdown in the sidebar actions.

5. Deck library + profile "My Decks". /academy/flashcards/library browses available decks; the profile gains a My Decks tab (MyDecksCard) listing user-saved decks. Saved decks
and per-card ratings persist client-side via IndexedDB (v4 schema, setId:cardIndex keys) — no Prisma migration.

6. Coverage scripts. yarn generate:flashcards (single source) and a batch generator walk MDX under content/academy/..., run the same pipeline, and write into flashcardData.json
so the existing <Flashcard /> picks them up. Maintainer-run, not CI-auto — not invoked in this PR.

Architecture

  • Shared library at lib/flashcards/ (13 modules): Zod types, MDX source-loader (JSX stripping, fenced-code-safe), prompt builders (full-deck + single-card), embedding dedupe,
    .apkg builder, rate-limit, zustand + sessionStorage studio store, legacy ↔ rich Flashcard adapter, catalog / deck-resolver / course-path for standard decks, and errors
    (sanitizes API keys, stacks, and internal paths out of all client-facing errors).
  • Persistence: study progress + saved decks live in IndexedDB (utils/quizzes/indexedDB.ts, v4). Studio drafts stay session-scoped in sessionStorage.
  • New runtime dep: anki-apkg-export@4.0.3 (MIT). genanki-js is AGPL-3.0 and would contaminate this BSD-3-Clause repo, so it was rejected. Minimal declare module shim at
    types/anki-apkg-export.d.ts.
  • 12 Vitest test files under tests/unit/flashcards/: types adapter, source-loader, dedupe, legacy adapter, .apkg round-trip, catalog, course-path, deck-resolver, study-state, error
    sanitization, and both generate + download API routes (mocked NextAuth + LLM — covers auth gate, schema validation, rate-limit 429, token-budget, and success paths).

Build / config changes

  • next.config.mjs: externalize anki-apkg-export for the production server build.
  • package.json postinstall: removes a stale nested @avalanche-sdk/client/node_modules/@noble/secp256k1@3.0.0 directory so Turbopack's strict nested resolution doesn't crash on
    ProjectivePoint. Master-wide issue, not introduced here; idempotent, yarn.lock-neutral.

Test plan

  • npx vitest run tests/unit/flashcards — all green
  • yarn tsc --noEmit clean
  • Visit an existing flashcard chapter → Anki icon in header → click → .apkg opens in Anki desktop
  • /academy/flashcards logged out → button reads "Sign in to generate"; logged in → enabled
  • Pick chapters across 2 courses → Generate → mixed Q&A / cloze / code cards within ~30s; reject one → greys out; regenerate one → replaced; "Download for Anki" → .apkg opens with
    surviving cards
  • POST /api/flashcards/generate without a session → 401; 11th generation in 24h → 429
  • Play a standard deck → flip with Space, rate with 1/2/3, navigate with arrows; reload → progress restored from IndexedDB
  • Save a deck → appears under profile My Decks and in the sidebar dropdown
  • Hard-refresh on /academy/flashcards/[sessionId] mid-edit → zustand rehydrates from sessionStorage

Notes for reviewers

  • Coverage scripts are shipped but not run here — backfilling technical courses consumes Anthropic + OpenAI quota and should be a deliberate maintainer action.
  • E2E Playwright tests deferred (no Playwright infra in the repo today).
  • yarn.lock is managed separately per repo convention; the new anki-apkg-export dep is added to package.json and the lockfile is regenerated + committed outside these commits.
  • The @noble/secp256k1 postinstall is the minimum-touch Turbopack unblock; the cleaner long-term fix is bumping @avalanche-sdk/client to 0.1.1 stable in a separate PR.

@vercel

vercel Bot commented May 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
builder-hub Ready Ready Preview, Comment Jun 2, 2026 1:12pm

Request Review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f0b2ee53ab

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/flashcards/generate.ts
Comment thread lib/flashcards/source-loader.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant