Skip to content

orionbits/germa

Repository files navigation

German Worksheet Builder

Interactive workbook generator built with Next.js 14 App Router.

The app takes:

  • one markdown file for chapter/content
  • one markdown file for answers

Then it parses, matches, and renders a chapter-based workbook where learners can:

  • open/collapse chapters
  • answer inline exercises
  • reveal expected answers
  • check responses
  • track chapter and overall completion

Core Goal

Turn plain markdown teaching material into an interactive practice workbook with automatic post-upload processing:

  • local matching
  • AI-assisted alignment (Gemini)
  • optional run persistence (Supabase)

Tech Stack

Frontend

  • Next.js 14 (App Router)
  • React 18
  • TypeScript
  • Tailwind CSS
  • React Markdown (react-markdown) for rendering chapter markdown

Backend/API (still present in project)

  • Next.js Route Handlers
  • Zod schema validation for JSON conversion-related routes
  • Gemini-powered answer alignment and markdown conversion routes
  • Supabase client integration for processing run storage

Tooling

  • ESLint
  • PostCSS
  • TypeScript compiler

High-Level Architecture

The app is organized into 3 functional layers:

  1. Input Layer (Upload Components)

    • src/components/markdown-upload.tsx
    • src/components/answer-markdown-upload.tsx
    • Validates .md files and max file size (10MB)
    • Reads file text in browser (file.text())
    • Sends loaded markdown up to parent state
  2. Processing Layer (Parsing + Matching + API Processing)

    • src/lib/workbook.ts
    • src/lib/match-exercises.ts
    • src/lib/supabase-client.ts
    • Parses chapters and exercise IDs from content markdown
    • Parses answer IDs and answer lines from answer markdown
    • Builds local ID-based matches (A1, B12, etc.)
    • Calls AI alignment for unmatched IDs
    • Converts chapter markdown into structured block JSON
    • Optionally stores run metadata in Supabase
  3. Presentation Layer (Interactive Workbook UI)

    • src/components/interactive-workbook.tsx
    • Renders chapter content and exercise interaction
    • Stores response/check/reveal state client-side
    • Computes progress per chapter and overall

Main orchestration happens in:

  • src/app/page.tsx

Folder-Level Overview

src/app

  • page.tsx: main screen composition and state orchestration
  • api/align-answers/route.ts: Gemini-based alignment for unmatched exercises
  • api/convert-json/route.ts: Gemini + Zod conversion from markdown to block JSON
  • api/health/route.ts: app health endpoint

src/components

  • markdown-upload.tsx: chapter markdown upload
  • answer-markdown-upload.tsx: answer markdown upload + extracted IDs display
  • interactive-workbook.tsx: generated workbook interaction UI
  • markdown-editor.tsx: markdown editor + validation preview
  • block-renderer.tsx: existing block renderer (legacy/parallel workflow support)
  • answer-alignment.tsx: existing manual alignment UI (available but not required for workbook generation)

src/lib

  • workbook.ts: chapter parsing, exercise extraction, answer parsing
  • match-exercises.ts: exercise-answer ID matching helper
  • supabase-client.ts: Supabase browser client factory
  • validators.ts: markdown structural validation utilities
  • schema.ts: zod block schema types

Data Flow: End-to-End Processing

  1. User uploads chapter markdown (.md).
  2. User uploads answer markdown (.md).
  3. Both files are read on the client and stored in page-level React state.
  4. Local matcher runs first using direct ID intersections.
  5. Unmatched exercise IDs are sent to /api/align-answers for Gemini alignment.
  6. Chapter markdown is sent to /api/convert-json to generate structured block JSON.
  7. Processing metadata is written to Supabase table workbook_runs when configured.
  8. Workbook parser splits content into chapters and extracts exercise IDs.
  9. Answer parser extracts answer entries using ID regex pattern.
  10. Interactive workbook renders:
  • chapter markdown
  • per-exercise answer input
  • check/reveal controls
  1. User actions update local state:
  • typed responses
  • checked status
  • revealed answers
  1. Progress bars update in real-time based on checked/completed items.

Parsing and Matching Logic

Chapter Parsing

Implemented in src/lib/workbook.ts.

  • Splits chapters by markdown headings (## ...).
  • Creates chapter objects:
    • id
    • title
    • body
    • exerciseIds

If no chapter headings exist, the full markdown is treated as one chapter.

Exercise ID Extraction

Uses regex pattern for headings like:

  • ## Exercise A1
  • ## Exercise B12

Answer Extraction

Answer markdown uses line format:

  • A1: answer text
  • A1. answer text

Regex captures:

  • answer ID (A1)
  • answer content (answer text)

Matching

src/lib/match-exercises.ts does ID-based matching:

  • extract exercise IDs from content markdown
  • extract answer IDs from answer markdown
  • return intersections as initial matches

AI Alignment + Conversion

  • POST /api/align-answers
    • input: unmatchedExercises, answerKeyText
    • output: aligned exercise-answer mappings with confidence
  • POST /api/convert-json
    • input: chapter markdown
    • output: structured block JSON validated by Zod schema

Interactive Workbook Logic

Implemented in src/components/interactive-workbook.tsx.

UI Behaviors

  • Collapsible chapter cards
  • Smooth open/close transitions
  • Inline input field per exercise ID
  • "Check" button marks an exercise as checked
  • "Reveal Answer" toggles expected answer visibility

Completion and Progress

  • checked state tracks completed checks by exercise ID
  • Per-chapter completion:
    • checked_in_chapter / total_exercises_in_chapter
  • Overall completion:
    • total_checked / total_exercises
  • Progress bars update instantly

Response Evaluation

  • Compares user input and expected answer with trimmed + lowercase normalization
  • Shows:
    • Correct
    • Not exact match yet
    • No answer found in answer markdown

Validation Rules

Upload-level validation:

  • file type must be markdown (.md, markdown mime types)
  • max size 10MB

Editor-level validation (markdown-editor.tsx):

  • page markers format checks (<!-- page X -->)
  • blank token sequence checks ([0], [1], ...)
  • exercise heading format checks

Processing-level resilience (src/app/page.tsx):

  • local matching is always applied first
  • if Gemini alignment fails, app continues with local matches
  • if conversion fails, interactive workbook still works
  • clear status/error messages are shown in the Auto Matching panel

Removed PDF Pipeline

This project has been refactored away from PDF extraction.

Removed:

  • PDF upload UI/components
  • PDF extraction API routes
  • PDF debug docs/scripts
  • PDF-related dependencies (pdfjs-dist, OCR/canvas support stack)

Current primary ingestion path is markdown-only.


Running Locally

Environment Variables

Create .env.local with:

NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
GEMINI_API_KEY=your_gemini_api_key

Notes:

  • Supabase storage is optional at runtime (processing still works without successful insert).
  • Gemini key is required for /api/align-answers and /api/convert-json AI steps.
  • Local matching + interactive workbook UI still operate even if AI steps fail.
npm install
npm run dev

Open:

For production checks:

npm run lint
npm run build

Troubleshooting Upload/Processing

If markdown upload appears to "not work":

  1. Upload both files (chapter.md and answers.md) and wait for Auto Matching status.
  2. Confirm answer IDs follow expected format:
    • A1: ... or A1. ...
  3. Confirm chapter exercise headings include IDs:
    • ## Exercise A1
  4. Check .env.local has valid values for:
    • GEMINI_API_KEY
    • NEXT_PUBLIC_SUPABASE_URL
    • NEXT_PUBLIC_SUPABASE_ANON_KEY
  5. If AI service is unavailable, app should still continue with local matching.

Future Extension Ideas

  • richer chapter parsing (custom frontmatter/metadata)
  • scoring policies beyond exact match
  • persistent learner sessions
  • export workbook results as markdown/json
  • teacher dashboard for completion analytics

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors