Frontend Challenge Content Integration
Context
The fact_challenge_content table contains pre-generated challenge content for ~144K facts across 6 styles (statement_blank, direct_question, fill_the_gap, multiple_choice, reverse_lookup, free_text). Each row includes setup_text, challenge_text, reveal_correct, reveal_wrong, correct_answer, and style-specific style_data (e.g., options for multiple choice).
Currently, the card detail UI components generate challenge content algorithmically at render time. This project switches them to consume pre-generated content from the database, with algorithmic fallback for uncovered facts. It also wires the queue integration so new facts entering the pipeline automatically get challenge content generated.
Key constraint: Algorithmic fallback must remain functional for facts without pre-generated content (CC-004).
Current State
| Item | Status |
|---|---|
fact_challenge_content table | 378K+ rows, regeneration in progress for 144K facts |
| API endpoint for challenge content | Does not exist |
quiz-interface.tsx | Algorithmic generation only |
recall-interface.tsx | Algorithmic generation only |
text-input-challenge.tsx | Algorithmic generation only |
Queue: GENERATE_CHALLENGE_CONTENT message type | Defined in schema, handler built in worker-facts |
Queue: Auto-enqueue after IMPORT_FACTS | Partially wired (seed pipeline only, not news pipeline) |
Key File References
| File | Purpose |
|---|---|
apps/web/app/card/[slug]/_components/quiz-interface.tsx | Multiple choice UI |
apps/web/app/card/[slug]/_components/recall-interface.tsx | Fill-the-gap, statement blank UI |
apps/web/app/card/[slug]/_components/text-input-challenge.tsx | Free text UI |
apps/web/app/card/[slug]/_components/challenge-reveal.tsx | Reveal correct/wrong feedback |
apps/web/app/api/cards/[slug]/route.ts | Card detail endpoint |
packages/db/src/drizzle/fact-engine-queries.ts | Query layer |
packages/ai/src/challenge-content.ts | AI generation function |
packages/ai/src/challenge-content-rules.ts | Validation, constants, style list |
apps/worker-facts/src/handlers/generate-challenge-content.ts | Queue handler |
Challenges
Wave 1: API & Data Loading
Challenge 3.1: Query Function for Challenge Content
Requirement: Add a query function that retrieves pre-generated challenge content for a given fact. Acceptance Criteria:
-
getChallengeContentForFact(factRecordId, options?)function exists infact-engine-queries.ts - Returns all challenge content rows for the fact, grouped by style
- Optional
stylefilter parameter - Optional
difficultyfilter parameter (default: 1) -
bun run typecheckpasses Evaluation: PENDING Owner: card-ux-designer
Challenge 3.2: API Endpoint for Challenge Content
Requirement: Create or extend an API endpoint that serves pre-generated challenge content. Acceptance Criteria:
- Endpoint at
/api/cards/[slug]/challengesOR challenge content included in existing/api/cards/[slug]response - Returns pre-generated content keyed by challenge style
- Includes
correct_answerfield for each style - Requires authentication (same gating as card detail)
- Returns empty object (not error) when no pre-generated content exists Evaluation: PENDING Owner: card-ux-designer
Challenge 3.3: Type Definitions for Frontend
Requirement: Add TypeScript types for pre-generated challenge content consumed by UI components. Acceptance Criteria:
- Type exported from
@eko/sharedor defined in card components - Covers all 6 pre-generated styles with their
style_datavariants - Includes
correct_answerfield -
bun run typecheckpasses Evaluation: PENDING Owner: card-ux-designer
Wave 2: UI Component Updates
Challenge 3.4: Quiz Interface — Pre-generated Content
Requirement: quiz-interface.tsx consumes pre-generated multiple_choice content when available.
Acceptance Criteria:
- Checks for pre-generated
multiple_choicecontent before algorithmic generation - Uses
setup_textfor context display - Uses
challenge_textfor the question - Uses
style_data.optionsfor answer choices - Uses
reveal_correct/reveal_wrongfor feedback - Uses
correct_answerfor narrative reveal - Falls back to algorithmic generation when no pre-generated content exists (CC-004) Evaluation: PENDING Owner: card-ux-designer
Challenge 3.5: Recall Interface — Pre-generated Content
Requirement: recall-interface.tsx consumes pre-generated statement_blank and fill_the_gap content when available.
Acceptance Criteria:
- Checks for pre-generated content before algorithmic generation
- Supports both
statement_blankandfill_the_gapstyles - Uses
style_data.blank_answerfor answer validation - Uses
correct_answerfor narrative reveal - Falls back to algorithmic generation when no pre-generated content exists (CC-004) Evaluation: PENDING Owner: card-ux-designer
Challenge 3.6: Text Input Challenge — Pre-generated Content
Requirement: text-input-challenge.tsx consumes pre-generated free_text and direct_question content when available.
Acceptance Criteria:
- Checks for pre-generated content before algorithmic generation
- Supports both
free_textanddirect_questionstyles - Uses
correct_answerfor narrative reveal - Falls back to algorithmic generation when no pre-generated content exists (CC-004) Evaluation: PENDING Owner: card-ux-designer
Challenge 3.7: Challenge Reveal — Correct Answer Streaming
Requirement: challenge-reveal.tsx displays the correct_answer narrative with animated streaming.
Acceptance Criteria:
- Renders
correct_answerwith a typewriter/streaming animation - Falls back to existing reveal text when
correct_answeris null - Animation respects
prefers-reduced-motion - Works for all challenge styles Evaluation: PENDING Owner: card-ux-designer
Wave 3: Queue Integration
Challenge 3.8: Auto-enqueue for News Pipeline Facts
Requirement: Facts entering via the news pipeline (EXTRACT_FACTS) automatically enqueue GENERATE_CHALLENGE_CONTENT. Acceptance Criteria:
-
extract-facts.tshandler enqueuesGENERATE_CHALLENGE_CONTENTafter successful fact insertion - Only enqueues for facts with status
pending_validationor better - Does not duplicate-enqueue if content already exists
- Verified by checking queue message flow in worker logs Evaluation: PENDING Owner: queue-sre
Challenge 3.9: Validation Gate
Requirement: Challenge content generation waits until fact validation completes. Acceptance Criteria:
-
GENERATE_CHALLENGE_CONTENTis enqueued afterVALIDATE_FACTsucceeds (not afterEXTRACT_FACTS) - Rejected facts do not get challenge content generated
- Validated facts that already have challenge content are skipped
-
bun run typecheckpasses Evaluation: PENDING Owner: queue-sre
Quality Tier
Verification Checklist
- Card detail page renders pre-generated content for covered facts
- Card detail page falls back to algorithmic generation for uncovered facts
-
correct_answerdisplays with streaming animation - No visual regression on card detail pages
- New facts from news pipeline get challenge content auto-generated
-
bun run typecheckpasses -
bun run lintpasses
Evaluation Summary
| Challenge | Result |
|---|---|
| 3.1 Query Function | PENDING |
| 3.2 API Endpoint | PENDING |
| 3.3 Type Definitions | PENDING |
| 3.4 Quiz Interface | PENDING |
| 3.5 Recall Interface | PENDING |
| 3.6 Text Input Challenge | PENDING |
| 3.7 Challenge Reveal Streaming | PENDING |
| 3.8 Auto-enqueue News Pipeline | PENDING |
| 3.9 Validation Gate | PENDING |
Score: 0/9 PASS
Implementation Notes
- Wave 1 must complete before Wave 2 — UI components need the API endpoint and types.
- Wave 2 is parallelizable — quiz, recall, and text-input components can be updated independently.
- Wave 3 is independent of Waves 1-2 — queue wiring doesn't depend on frontend changes.
- The
correct_answerstreaming animation (Challenge 3.7) is a new UX pattern — consider adding a Storybook story. - Challenge numbering uses the
3.xprefix to follow the taxonomy expansion (1.x) and backfill-fact-nulls (2.x) challenge docs.
Related Documents
- Challenge Content Seeding TODO — Parent tracking document
- Challenge Content Rules — CC-004 governs fallback behavior
- Taxonomy Expansion — Sibling GTD project
- Backfill Fact Nulls — Sibling GTD project