Commit graph

6 commits

Author SHA1 Message Date
Till JS
35366ed4f2 Phase 9b: Cloze-Editor in /cards/new
Type-Picker um Cloze ergänzt. Formular schaltet auf Single-Textarea
(text + optionales extra) um, sobald Cloze gewählt wird. Cluster-
Counter, Inline-Hint und Live-Preview (erstes Cluster maskiert)
sind dieselben Helpers wie im Edit-Flow (@cards/domain/src/cloze.ts).

Submit-Validation: bei Cloze muss mindestens ein {{cN::…}}-Cluster
existieren — Submit-Button bleibt sonst disabled. Toast nennt nach
dem Anlegen die Anzahl initialisierter Reviews.

svelte-check 354 files 0 errors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 17:52:55 +02:00
Till JS
0a403679e3 Phase 9a: Card-Edit-Page für alle 3 CardTypes
Neue Route /cards/[id]/edit. Lädt die Karte, zeigt typ-spezifisches
Form (basic/basic-reverse: front+back, cloze: text+extra mit
Cluster-Counter und Live-Preview), PATCHt die fields. CardType ist
read-only — Type-Wechsel würde die Reviews-Tabelle brechen.

Cloze-Editor zeigt erkannte Cluster-IDs ("c1, c2 → 2 Reviews") und
warnt, wenn Text ohne {{cN::…}}-Markup gespeichert würde. Live-
Vorschau rendert den Prompt mit dem ersten Cluster maskiert.

Decks-Detail-Page: Karten-Eintrag verlinkt jetzt aufs Edit, Cloze-
Karten zeigen ihren `text`-Anschnitt statt "(leer) → (leer)". Delete-
Button bleibt am rechten Rand.

svelte-check 354 files 0 errors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 17:51:42 +02:00
Till JS
2ca09fe0c3 Phase 8c: Anki-Import via portiertem Parser
Strategie-B-Ausnahme: parse.ts (Anki-Format-Parser via JSZip + sql.js)
und AnkiImport.svelte (UI-Stages) sind aus mana-monorepo portiert,
mit Source-Comment-Header dokumentiert. Anki-Format ist standalone
Parser-Logik, kein Architektur-Schmuggel.

Neuer server-authoritative import.ts schreibt direkt gegen die
cards-api ($lib/api/decks + cards) — keine Stores, keine Dexie.
Anki "::"-Hierarchie wird zu " / "-Strings flach. Fallback-Deck
"Anki-Import" für Karten ohne explizites Deck. Cloze-Karten kommen
first-class durch (Sub-Index pro Cluster, Sprint 8a/8b).

Phase-8-MVP-Scope: Bilder + Audio werden gedroppt (Option A) — der
sanitizeAnkiHtml entfernt <img> und [sound:…] ersatzlos. Späterer
Media-Pfad (lokaler Cards-Upload oder mana-media nach Phase 2) ist
additiv.

Neue Route /import + Top-Nav-Link. Hermetic Vitest (5 Cases): baut
zur Laufzeit ein Mini-.apkg via sql.js + JSZip und prüft den
Parser-Output (basic, basic-reverse, cloze, sanitize, dedupe auf
Note-Ebene). svelte-check 0 errors, prod-Build sauber.

sql-wasm.wasm liegt in static/ (660kB) — fix für sql.js 1.14.1, vom
Browser einmal geladen.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 17:43:12 +02:00
Till JS
0b609c46fd Phase 8b: Cloze-Render im Study-View
Study-View hat jetzt Cloze-Branch in promptMarkdown/answerMarkdown.
Aktiver Cluster wird im Prompt zu […], in der Answer fett markiert,
restliche Cluster sind expanded. Optionales `extra`-Feld wird unter
der Answer angehängt (Anki-kompatibel).

Render-Helpers (clusterIdForSubIndex, renderClozePrompt,
renderClozeAnswer) leben in @cards/domain (Phase 8a) und sind dort
12-fach getestet — die Svelte-Komponente bleibt dünn.

E2E-Smoke gegen lokale DB: Cloze-Card mit zwei Clustern
({{c1::Frankreich}} {{c2::Paris}}) erzeugt 2 Reviews (sub_index 0+1).
Type-check + svelte-check 0 errors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 17:37:53 +02:00
Till
89a7a9250b Phase 4: Frontend-Core MVP — Decks, Cards, Study mit FSRS-Loop
Stack:
- Tailwind 4 via @tailwindcss/vite (oklch-Theme + Dark-Mode-Auto)
- marked + DOMPurify für Markdown (sanitized, SSR-Safe)
- Svelte 5 runes durchgängig ($state, $derived, $effect)
- @sveltejs/adapter-node für Production-Build

Infrastruktur:
- $lib/auth/dev-stub.svelte.ts: User-ID via sessionStorage (Phase 2
  ersetzt durch echtes JWT via @mana/shared-auth)
- $lib/api/{client,decks,cards,reviews}.ts: typed Fetch-Wrapper, ruft
  cards-api auf 3081 mit X-User-Id-Header
- $lib/stores/toasts.svelte.ts: Toast-Store mit info/success/warning/error
- $lib/markdown.ts: marked → DOMPurify-Pipeline
- $lib/components/{Header,ToastStack}.svelte: Layout-Shell

Routes:
- / → Dev-Login-Form oder Redirect zu /decks (wenn eingeloggt)
- /decks → Liste mit Color-Dot, Hover-Delete-Button
- /decks/new → Create-Form (Name, Beschreibung, Color-Picker)
- /decks/[id] → Detail mit Cards-Liste + dueCount + "Lernen"-Button
- /cards/new?deck=... → Type-Picker (basic|basic-reverse) +
  Side-by-Side Markdown-Editor mit Live-Preview
- /study → Übersicht aller Decks mit Due-Counts
- /study/[deckId] → Session-View mit Queue-Snapshot, Reveal/Grade,
  Hotkeys (Space/Enter=Reveal & Good, 1-4=Again/Hard/Good/Easy),
  INPUT-Skip im Keyboard-Handler

CORS auf cards-api für localhost-Origins + cardecky.mana.how.

Verifiziert:
- pnpm run type-check  4/4 packages, svelte-check 0 errors
- pnpm build (cards-web)  adapter-node bundle 140 kB server,
  alle Routen bundled
- Tailwind-CSS inlined in SSR-HTML, oklch-Theme korrekt
- CORS-Preflight funktioniert (OPTIONS 204 mit korrekten Allow-*-Headers)
- Live-Smoke-Test gegen localhost:3081 (cards-api) + localhost:3082
  (cards-web): Beide laufen parallel, Web → API CORS-fetch grün

Outside scope (Phase 4):
- Card-Edit-Page (/cards/[id]/edit) — heute nur Create + Delete
- Settings/Account/Credits/DSGVO-Pages — Phase 9 (Polish)
- Anki-Import — Phase 8

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 16:52:31 +02:00
Till
8605b1b517 Phase 0+1: Repo-Skelett für Cards-Greenfield
Strategie B (beschlossen 2026-05-08): Cards wird als eigenständige
föderierte App neu gebaut, ohne Code-Übernahme aus mana-monorepo.

Skelett enthält:
- apps/api: Hono+Bun mit /healthz, /version, Manifest-Endpoint, leere
  pgSchema('cards'), Drizzle-Config, erstem Vitest
- apps/web: SvelteKit 2 + Svelte 5 (runes), Vite auf 3082
- packages/cards-domain: Pure-TS, CardType-Discriminated-Union,
  SubIndex-Granularität für Reviews, Future-CardType-Set vorbereitet
- infrastructure/docker-compose.yml: Postgres 16 auf 5435
- app-manifest.json: v1.0.0, Verein-owned, beta-tier
- .github/workflows/ci.yml
- docs/LESSONS_FROM_MANA_MONOREPO.md (Read-Day-Output, 15 Lehren)

Pre-Flight für Phase 2 (Auth-Föderation): DNS cardecky.mana.how,
GitHub-Repo mana-ev/cards, Cards-App-Registrierung in mana-auth,
NPM_AUTH_TOKEN für Verdaccio.

Plan: mana/docs/playbooks/CARDS_GREENFIELD.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 14:08:41 +02:00