diff --git a/devlog/2026-05-12/data.json b/devlog/2026-05-12/data.json new file mode 100644 index 0000000..4c8656c --- /dev/null +++ b/devlog/2026-05-12/data.json @@ -0,0 +1,183 @@ +{ + "date": "2026-05-12", + "day_number": 1, + "weekday": "Dienstag", + "commits": 10, + "authors": [ + { + "name": "Till JS", + "count": 10 + } + ], + "additions": 6964, + "deletions": 326, + "net_lines": 6638, + "files_changed": 77, + "new_files": 0, + "deleted_files": 0, + "session": { + "first_commit_at": "2026-05-12T17:29:45.000Z", + "last_commit_at": "2026-05-12T23:56:54.000Z", + "total_span_minutes": 387, + "active_minutes": 67, + "pauses": [ + { + "from": "19:29", + "to": "00:06", + "minutes": 277 + }, + { + "from": "01:13", + "to": "01:56", + "minutes": 43 + } + ], + "longest_focus_minutes": 67 + }, + "top_dirs": [ + { + "path": "PLAN.md", + "pct": 7 + }, + { + "path": "Sources/Features/Decks", + "pct": 7 + }, + { + "path": "Sources/Core/Domain", + "pct": 7 + }, + { + "path": "Sources/Core/Sync", + "pct": 6 + }, + { + "path": "Sources/Core/API", + "pct": 5 + } + ], + "top_extensions": [ + { + "ext": ".swift", + "count": 79 + }, + { + "ext": ".md", + "count": 12 + }, + { + "ext": ".yml", + "count": 6 + }, + { + "ext": ".json", + "count": 5 + }, + { + "ext": ".entitlements", + "count": 3 + }, + { + "ext": ".plist", + "count": 3 + } + ], + "tags": [], + "commits_list": [ + { + "hash": "28b20cd", + "short": "v0.1.0 — Phase β-0 Setup", + "type": null, + "scope": null, + "additions": 896, + "deletions": 0, + "timestamp": "2026-05-12T19:29:45+02:00" + }, + { + "hash": "f664a00", + "short": "v0.2.0 — Phase β-1 Decks lesen", + "type": null, + "scope": null, + "additions": 809, + "deletions": 85, + "timestamp": "2026-05-13T00:06:28+02:00" + }, + { + "hash": "3b861af", + "short": "v0.3.0 — Phase β-2 Study-Loop", + "type": null, + "scope": null, + "additions": 1013, + "deletions": 23, + "timestamp": "2026-05-13T00:16:11+02:00" + }, + { + "hash": "cf1160b", + "short": "v0.4.0 — Phase β-3 Editor", + "type": null, + "scope": null, + "additions": 933, + "deletions": 22, + "timestamp": "2026-05-13T00:24:43+02:00" + }, + { + "hash": "80eb370", + "short": "v0.5.0 — Phase β-4 Media + Advanced Card-Types", + "type": null, + "scope": null, + "additions": 922, + "deletions": 43, + "timestamp": "2026-05-13T00:35:36+02:00" + }, + { + "hash": "07ada72", + "short": "v0.6.0 — Phase β-5 Marketplace", + "type": null, + "scope": null, + "additions": 1015, + "deletions": 24, + "timestamp": "2026-05-13T00:51:12+02:00" + }, + { + "hash": "a1770fb", + "short": "v0.7.0 — Phase β-6 Native-Polish", + "type": null, + "scope": null, + "additions": 580, + "deletions": 13, + "timestamp": "2026-05-13T01:00:04+02:00" + }, + { + "hash": "55359c5", + "short": "chore: gitignore widget-generated Info.plist + entitlements", + "type": null, + "scope": null, + "additions": 0, + "deletions": 39, + "timestamp": "2026-05-13T01:00:22+02:00" + }, + { + "hash": "0b2ae16", + "short": "v0.8.0 — Phase β-7 App-Store-Vorbereitung", + "type": null, + "scope": null, + "additions": 786, + "deletions": 62, + "timestamp": "2026-05-13T01:13:27+02:00" + }, + { + "hash": "bf23968", + "short": "docs: AASA-Endpoint markiert als done (Code-side)", + "type": null, + "scope": null, + "additions": 10, + "deletions": 15, + "timestamp": "2026-05-13T01:56:54+02:00" + } + ], + "review_state": "auto", + "llm": { + "model": null, + "generated_at": null + } +} diff --git a/devlog/2026-05-12/macher.md b/devlog/2026-05-12/macher.md new file mode 100644 index 0000000..0144364 --- /dev/null +++ b/devlog/2026-05-12/macher.md @@ -0,0 +1,105 @@ +--- +date: 2026-05-12 +day: 1 +view: macher +weekday: Dienstag +commits: 10 +review: written +--- +# Dienstag, 2026-05-12 — Tag 1 (Macher-Sicht) + +Phasen β-0 bis β-7 aus dem Greenfield-Playbook in einer Marathon- +Session. Skeleton → App-Store-Vorbereitung. Web-Parität als +Leitprinzip, FSRS bleibt server-authoritative, alles andere ist +Native-Re-Implementation des Web-Cardecky. + +## Stats + +10 Commits, +6 964 / −326 LoC, 77 Files. 79× `.swift`. Session +17:29 → 01:56, 67 aktive Minuten, längster Fokus 67 Min. Top-Dirs +sind sehr verteilt (alle 5–7 %) — Greenfield-Tag, der jeden +Subsystem-Bereich anfasst. + +## Versions-Tags + +- **v0.1.0 — β-0 Setup.** XcodeGen-Manifest, ManaCore + ManaTokens- + Package-Dependency, ManaCore-Login + Healthz-Probe gegen + cardecky-api.mana.how. +- **v0.2.0 — β-1 Decks lesen.** SwiftData-Cache, + `/api/v1/decks`-Liste, Detail-View mit Karten-Anzahl, + Stats-Sektion. +- **v0.3.0 — β-2 Study-Loop.** Grading gegen `POST /api/v1/reviews/ + :cardId/:subIndex/grade`. `ReviewQueue` für Offline-Grades, + Replay bei Reconnect. SubIndex-Berechnung für Cloze bleibt + server-side. +- **v0.4.0 — β-3 Editor.** Basic, Cloze, Typing, Multiple-Choice + als Editor-Surfaces. Content-Hash-Berechnung am Server. +- **v0.5.0 — β-4 Media + Advanced Card-Types.** Image- und + Audio-Front-Karten, Image-Occlusion-Mask via PencilKit + (einzige UIKit-Bridge), `mana-media`-Upload-Pfad. +- **v0.6.0 — β-5 Marketplace.** `/api/v1/marketplace/*`-Routen, + Subscribe-Flow, Universal-Links für Deck-Slugs. +- **v0.7.0 — β-6 Native-Polish.** WidgetKit (Due-Cards-Counter + + Heute-Streak), Local-Notifications für Review-Reminder, Share- + Extension „Save as Card". +- **chore: gitignore widget-generated Info.plist + entitlements.** + XcodeGen generiert die, sollen nicht im Git. +- **v0.8.0 — β-7 App-Store-Vorbereitung.** `PrivacyInfo.xcprivacy`, + AASA-Endpoint im Cards-API, Submission-Checkliste. +- **AASA-Endpoint als done markiert** code-seitig — DNS-/Cloudflare- + Roundtrip steht aus (gleiche Falle wie zitare-native). + +## Architektur-Entscheidungen + +- **Server-authoritative FSRS.** Grading-Calls immer an `POST + /api/v1/reviews/:cardId/:subIndex/grade`. Kein lokaler + ts-fsrs-Port. Vorteil: Algorithmen-Updates wirken sofort in + Native, ohne App-Update. Nachteil: Grading ist online-bedingt + (Offline-Queue löst das mit Round-Trip-Delay). +- **Offline-Read, Online-Write.** Decks + Due-Cards via SwiftData + gecacht (offline lesbar). Grades werden offline in einer + `ReviewQueue` persistiert, beim Reconnect der Reihe nach + abgesendet. +- **Cards-Domain-Logik bleibt am Server.** SubIndex-Berechnung + für Cloze, Image-Occlusion-Mask-Validation, Content-Hash — + alles Server. Native zeigt nur, was vom Server kommt. +- **Pure SwiftUI**, einzige UIKit-Bridge: `PencilKit` für Image- + Occlusion. SwiftUI hat keinen Pencil-Picker, nicht-vermeidbar. +- **mana-auth via ManaCore.** Eigene Auth-Implementierung verboten. +- **`forest`-Theme**, lokal in `CardsTheme.swift` aus + `mana/packages/themes/src/variants/forest.css` gespiegelt. + Migration auf ManaTokens-Theme-Switch ist Phase ε. +- **Web gewinnt bei Konflikt.** Eleganteres Native-Verhalten geht + zuerst in Web, dann nach hier. Verhindert Drift. + +## Trade-offs + +- **67 Min Active für β-0 bis β-7** klingt absurd komprimiert. + Realer Grund: jeder β-Schritt ist „Web-Funktion X als SwiftUI + spiegeln" — die Domain-Arbeit (FSRS, Cloze, Content-Hash) ist + alles Server-side bereits gelöst. Native = Wire-Format + + Codable + View. +- **PencilKit-Bridge** als einzige UIKit-Konzession. Beschränkt; + Image-Occlusion kann sonst nicht ergonomisch sein. +- **Local-Notifications für Review-Reminder** sind Best-Effort. + iOS budgetiert hart; bei vielen Decks kann eine Erinnerung + verschoben werden. +- **+6 638 LoC netto in einer Schicht** — keine Architektur-Arbeit, + reine Übersetzung. Wäre das nicht so identisch zum Web-Modell, + wäre der Tag dreimal so lang. + +## Offene Punkte + +- **AASA-DNS-Roundtrip** für Universal-Links. Code da, DNS-Setup + in Cloudflare offen. +- **TestFlight-Build** mit allem an Bord — Apple-Submission Folge- + Tag. +- **Endurance-Test auf echtem Gerät** über mehrere Tage — + Battery-Drain durch Notifications, ReviewQueue-Drift bei langem + Offline, Widget-Refresh-Verhalten. +- **WebKit-Local-Cache** für rich-content-Karten (HTML-Rich-Text) + nicht implementiert — heute Plain-Text-Fallback. +- **Cards-Domain `forest`-Theme** ist hartcodiert; ManaTokens- + Theme-Switch kommt mit Plattform-Variants-Release. +- **ShareExtension** vorbereitet, aber App-Group-Entitlement + muss in Apple-Dev-Portal aktiviert werden. diff --git a/devlog/2026-05-12/spieler.md b/devlog/2026-05-12/spieler.md new file mode 100644 index 0000000..d839067 --- /dev/null +++ b/devlog/2026-05-12/spieler.md @@ -0,0 +1,45 @@ +--- +date: 2026-05-12 +day: 1 +view: spieler +weekday: Dienstag +commits: 10 +review: written +--- +# Dienstag, 2026-05-12 — Tag 1 + +Cardecky gibt es bald auch als App. Heute ist die Basis entstanden: +Anmelden, Decks ansehen, lernen, Karten bearbeiten, Bilder dazulegen, +Marketplace durchsehen — alles offline-tauglich. + +## Was die App heute schon kann + +- **Anmelden** über deinen Verein-Account. +- **Deine Decks** sehen — und auch offline weiterhin, weil die App + sie zwischenspeichert. +- **Lernen** mit dem üblichen Bewerten-System (1–4). Wenn du gerade + kein Netz hast, sammelt die App die Bewertungen und schickt sie + später durch. +- **Karten bearbeiten** — die vier Standard-Typen: Vorder-/Rückseite, + Cloze, Tippen, Mehrfachauswahl. +- **Bilder + Audio** auf Karten — inkl. Bildausblenden (Image-Occlusion) + und „Audio zuerst, dann Antwort". +- **Marketplace** durchstöbern und Decks abonnieren. +- **Universal-Links** — Marketplace-Links aus Messenger öffnen direkt + die App. +- **Widget für den Home-Screen** und „Karte aus dem Web speichern"- + Share-Extension sind vorbereitet. + +## Was offen ist + +- **TestFlight + App Store** — Codeseitig ist alles fertig, der + Vertriebs-Slot bei Apple folgt. +- **Endurance-Test auf echtem iPhone** über mehrere Tage — heute + alles im Simulator getestet. + +## Hintergrund + +Cardecky lebt im Browser; manche Leute lernen aber lieber mit der +Hand am Telefon. Die App ist deshalb keine neue Cardecky, sondern +dieselbe Cardecky in iOS-Form — gleiche Karten, gleiches FSRS, +gleicher Account. diff --git a/devlog/2026-05-13/data.json b/devlog/2026-05-13/data.json new file mode 100644 index 0000000..47dc633 --- /dev/null +++ b/devlog/2026-05-13/data.json @@ -0,0 +1,317 @@ +{ + "date": "2026-05-13", + "day_number": 2, + "weekday": "Mittwoch", + "commits": 22, + "authors": [ + { + "name": "Till JS", + "count": 22 + } + ], + "additions": 6206, + "deletions": 1511, + "net_lines": 4695, + "files_changed": 87, + "new_files": 0, + "deleted_files": 0, + "session": { + "first_commit_at": "2026-05-13T11:17:41.000Z", + "last_commit_at": "2026-05-14T00:04:29.000Z", + "total_span_minutes": 767, + "active_minutes": 167, + "pauses": [ + { + "from": "13:29", + "to": "14:06", + "minutes": 37 + }, + { + "from": "15:11", + "to": "15:46", + "minutes": 35 + }, + { + "from": "16:02", + "to": "17:20", + "minutes": 77 + }, + { + "from": "18:15", + "to": "19:08", + "minutes": 54 + }, + { + "from": "19:26", + "to": "01:23", + "minutes": 357 + }, + { + "from": "01:23", + "to": "02:03", + "minutes": 40 + } + ], + "longest_focus_minutes": 65 + }, + "top_dirs": [ + { + "path": "Sources/Core/Domain", + "pct": 11 + }, + { + "path": "project.yml", + "pct": 9 + }, + { + "path": "Sources/Features/Decks", + "pct": 9 + }, + { + "path": "Sources/Features/Study", + "pct": 8 + }, + { + "path": "Sources/Core/Sync", + "pct": 6 + } + ], + "top_extensions": [ + { + "ext": ".swift", + "count": 115 + }, + { + "ext": ".yml", + "count": 15 + }, + { + "ext": ".md", + "count": 10 + }, + { + "ext": ".xcstrings", + "count": 4 + }, + { + "ext": ".json", + "count": 2 + }, + { + "ext": ".gitignore", + "count": 1 + } + ], + "tags": [ + "decks", + "auth", + "study", + "editor", + "ui" + ], + "commits_list": [ + { + "hash": "468ef29", + "short": "feat: DEVELOPMENT_TEAM=QP3GLU8PH3 für Code-Signing", + "type": null, + "scope": null, + "additions": 13, + "deletions": 8, + "timestamp": "2026-05-13T13:17:41+02:00" + }, + { + "hash": "4dfb32b", + "short": "chore: Rebrand auf ev.mana.cardecky", + "type": null, + "scope": null, + "additions": 203, + "deletions": 94, + "timestamp": "2026-05-13T13:29:04+02:00" + }, + { + "hash": "6d9a191", + "short": "chore: Archive-Polish — Versions-Sync + Orientations + Mac-Icon", + "type": null, + "scope": null, + "additions": 32, + "deletions": 7, + "timestamp": "2026-05-13T14:06:11+02:00" + }, + { + "hash": "6a4d66f", + "short": "chore: Sendable-Warning + AppIcon-Asset-Cleanup", + "type": null, + "scope": null, + "additions": 19, + "deletions": 14, + "timestamp": "2026-05-13T14:12:29+02:00" + }, + { + "hash": "e24e0e6", + "short": "fix(editor): PhotosPicker Sendable-Warning durch Sub-View struct", + "type": "fix", + "scope": "editor", + "additions": 105, + "deletions": 17, + "timestamp": "2026-05-13T14:39:09+02:00" + }, + { + "hash": "2eb7f61", + "short": "fix: ITMS-90129 — DisplayName Cards → Cardecky + Build 2", + "type": null, + "scope": null, + "additions": 11, + "deletions": 11, + "timestamp": "2026-05-13T15:05:33+02:00" + }, + { + "hash": "b5edf5c", + "short": "fix: User-facing Strings Cards → Cardecky komplett, Build 3", + "type": null, + "scope": null, + "additions": 19, + "deletions": 19, + "timestamp": "2026-05-13T15:11:11+02:00" + }, + { + "hash": "f528ea4", + "short": "fix: PublicDeckOwner.pseudonym ist Bool, nicht String?", + "type": null, + "scope": null, + "additions": 10, + "deletions": 6, + "timestamp": "2026-05-13T15:46:20+02:00" + }, + { + "hash": "e8b898a", + "short": "feat(decks): Card-Liste im DeckDetailView + listCards-API", + "type": "feat", + "scope": "decks", + "additions": 169, + "deletions": 17, + "timestamp": "2026-05-13T16:02:59+02:00" + }, + { + "hash": "0b0872c", + "short": "fix: 404 auf allen Query-Endpoints — pulls ManaCore v1.0.1 fix", + "type": null, + "scope": null, + "additions": 3, + "deletions": 3, + "timestamp": "2026-05-13T17:20:03+02:00" + }, + { + "hash": "aa94601", + "short": "feat(ui): Cardecky-Web-Design — Fan-Stack-Tiles + CardSurface", + "type": "feat", + "scope": "ui", + "additions": 396, + "deletions": 162, + "timestamp": "2026-05-13T17:28:11+02:00" + }, + { + "hash": "8b1dd51", + "short": "feat(study): Multiple-Choice-Karten gerendert", + "type": "feat", + "scope": "study", + "additions": 225, + "deletions": 4, + "timestamp": "2026-05-13T17:34:07+02:00" + }, + { + "hash": "505aa9d", + "short": "feat(study): Typing-Karten + Levenshtein-Match-Logik", + "type": "feat", + "scope": "study", + "additions": 323, + "deletions": 4, + "timestamp": "2026-05-13T17:39:39+02:00" + }, + { + "hash": "33101d7", + "short": "feat(auth): DEBUG-Auto-Login (Memoro-Pattern)", + "type": "feat", + "scope": "auth", + "additions": 52, + "deletions": 12, + "timestamp": "2026-05-13T17:50:29+02:00" + }, + { + "hash": "90201d7", + "short": "feat(decks): Tile-Redesign — Tap=Study, Edit-Icon, Explore-Konsistenz", + "type": "feat", + "scope": "decks", + "additions": 154, + "deletions": 74, + "timestamp": "2026-05-13T18:03:47+02:00" + }, + { + "hash": "0e90f4b", + "short": "chore: PLAN.md auf v0.9.4-Stand + Localizable.xcstrings", + "type": null, + "scope": null, + "additions": 67, + "deletions": 8, + "timestamp": "2026-05-13T18:15:22+02:00" + }, + { + "hash": "6805bd7", + "short": "feat(decks): iOS-26 tabViewBottomAccessory für „Neues Deck\"-Pille", + "type": "feat", + "scope": "decks", + "additions": 57, + "deletions": 10, + "timestamp": "2026-05-13T19:08:57+02:00" + }, + { + "hash": "710ede6", + "short": "fix(api): code:nil bei AuthError.serverError-Calls", + "type": "fix", + "scope": "api", + "additions": 3, + "deletions": 3, + "timestamp": "2026-05-13T19:09:01+02:00" + }, + { + "hash": "da66797", + "short": "feat(auth): ManaAuthUI-Migration — vollständige Auth-Reise nativ", + "type": "feat", + "scope": "auth", + "additions": 173, + "deletions": 99, + "timestamp": "2026-05-13T19:26:12+02:00" + }, + { + "hash": "8ca7bd3", + "short": "feat(auth): Guest-Mode + Login-optionale Surface", + "type": "feat", + "scope": "auth", + "additions": 271, + "deletions": 155, + "timestamp": "2026-05-14T01:23:30+02:00" + }, + { + "hash": "73f9081", + "short": "feat(decks): γ-1 bis γ-8 — AI/CSV-Import, Card-Edit, Pull-Update, Marketplace-Publish + Moderation + PDF", + "type": "feat", + "scope": "decks", + "additions": 3412, + "deletions": 435, + "timestamp": "2026-05-14T02:03:59+02:00" + }, + { + "hash": "aece169", + "short": "chore(lint): SwiftLint-Config + 0-Warnings-Pass + Swift-6-Concurrency-Fixes", + "type": "chore", + "scope": "lint", + "additions": 489, + "deletions": 349, + "timestamp": "2026-05-14T02:04:29+02:00" + } + ], + "review_state": "auto", + "llm": { + "model": null, + "generated_at": null + } +} diff --git a/devlog/2026-05-13/macher.md b/devlog/2026-05-13/macher.md new file mode 100644 index 0000000..93f7168 --- /dev/null +++ b/devlog/2026-05-13/macher.md @@ -0,0 +1,119 @@ +--- +date: 2026-05-13 +day: 2 +view: macher +weekday: Mittwoch +commits: 22 +review: written +--- +# Mittwoch, 2026-05-13 — Tag 2 (Macher-Sicht) + +Großer Polish-Tag mit Funktions-Vollausbau. Web-Design adaptiert, +alle 7 Karten-Typen rendern, ManaAuthUI-Migration zog die Auth-Reise +nativ, Guest-Mode landete, und der γ-1-bis-γ-8-Block brachte AI-/ +CSV-Import, Card-Edit, Pull-Update, Marketplace-Publish, Moderation +und PDF-Export — alles in einer Schicht. + +## Stats + +22 Commits, +6 206 / −1 511 LoC, 87 Files. 115× `.swift`. Session +11:17 → 02:04, 167 aktive Minuten in 7 Blöcken, längster Fokus +65 Min. Top-Dirs: Domain (11 %), project.yml (9 %), Decks (9 %), +Study (8 %), Sync (6 %). Tags: decks, auth, study, editor, ui. + +## Schritte (chronologisch) + +- **DEVELOPMENT_TEAM=QP3GLU8PH3** für Code-Signing. Erstmal + Apple-Konto-Setup. +- **Rebrand auf `ev.mana.cardecky`.** Bundle-ID, DisplayName, Strings, + Icon-Asset. Vorher hieß die App intern „Cards", öffentlich aber + „Cardecky". +- **Archive-Polish** — Versions-Sync, Orientations, Mac-Icon. +- **Sendable-Warnings**: PhotosPicker zog Sub-View struct (Sendable- + Compliance für `PHPickerViewController`). +- **ITMS-90129** (Apple-Validation): DisplayName Cards → Cardecky in + Info.plist, Build 2. +- **User-facing Strings Cards → Cardecky** komplett, Build 3. +- **PublicDeckOwner.pseudonym ist Bool**, nicht `String?` — + Wire-Format-Drift gegen Server-Schema gefangen. +- **Card-Liste im DeckDetailView + listCards-API.** Vorher zeigte + Detail nur Metadaten. +- **ManaCore v1.0.1 pull** — 404 auf Query-Endpoints (URL-Encoding + von `?`, siehe mana-swift-core Tag 2). +- **Cardecky-Web-Design — Fan-Stack-Tiles + CardSurface.** Tiles + fächern Karten auf, einheitlicher Card-Frame über Front/Back/ + Cloze. +- **Multiple-Choice-Karten rendern.** UI-Render-Layer für MC, Server + liefert Choices + correctIndex. +- **Typing-Karten + Levenshtein-Match.** Antwort-Vergleich verzeiht + kleine Tippfehler (Edit-Distance ≤ 2). +- **DEBUG-Auto-Login** wie in Memoro-Native — schneller Iteration. +- **Tile-Redesign — Tap=Study, Edit-Icon, Explore-Konsistenz.** + Vorher war Tap = Edit, was niemandes Erwartung war. +- **iOS-26 `tabViewBottomAccessory` für „Neues Deck"-Pille.** Nutzt + den neuen iOS-26-API. +- **code:nil bei AuthError.serverError**-Fix in API-Wrapper. +- **ManaAuthUI-Migration** — alle Auth-Surfaces (Login/Signup/Verify/ + Reset/Account/Delete) auf das frische `mana-swift-ui`-Package. + Eigene Views weg. +- **Guest-Mode + Login-optionale Surface.** Public-Marketplace-Decks + + Read-only Study ohne Account. ManaAuthGate eskaliert pro Aktion. +- **γ-1 bis γ-8** — AI-Import-Sheet (Text-Prompt → mana-llm-Deck- + Generator), CSV-Import (Header-Parser + Map-Field), Card-Edit- + Sheet inkl. Image/Audio, Pull-Update (subscribed deck → new + version), Marketplace-Publish (Pseudonym oder echter Name), + Moderation-Surface (Report-Reason-Picker), PDF-Export + (PDFKit-Renderer). **3 412 / −435 LoC** in einem Commit — viel + generierter Sheet-Code, viel Wire-Format-Codable. +- **SwiftLint-Config + 0-Warnings-Pass + Swift-6-Concurrency-Fixes.** + CI-Bremse weg. + +## Architektur-Entscheidungen + +- **Auth-UI extern**, nicht selbst gebaut. Migration auf ManaAuthUI + (mana-swift-ui v0.1+) sparte ~600 LoC eigene Auth-Views und + zwang die anderen Apps in dieselbe Optik. +- **Guest-Mode als eigene Surface-Schicht**, nicht „signed-out". + Marketplace + Public-Study laufen ohne Account, ManaAuthGate + eskaliert pro Aktion (z.B. „Deck speichern"). +- **Levenshtein für Typing-Match.** Edit-Distance ≤ 2 verzeiht + Tippfehler ohne triviale Lösungen zu akzeptieren. Server kennt + diese Logik nicht (Web hat sie ebenfalls clientseitig). +- **Card-Surface als shared View**, statt 7× Custom-Layout. Ein + Frame, in den 7 Content-Types einsteigen. +- **iOS-26-Features als progressive enhancement** — + `tabViewBottomAccessory` ist nur ab iOS 26 verfügbar. + `#available`-Gate. +- **PDF-Export client-side** mit PDFKit, nicht Server. Server- + Render würde mana-pdf-Service nötig machen; client-Side ist + einfacher und privater. +- **DEBUG-Auto-Login-Pattern** aus Memoro übernommen — Iteration + ist 10× schneller wenn der Login-Step weg ist. + +## Trade-offs + +- **22 Commits in einer Session** ist viele Sinn-Abschnitte. Jeder + einzeln klein genug, dass `git log` lesbar bleibt. PR-Review + würde leiden, aber als Solo-Sprint OK. +- **AI-Import braucht mana-llm online.** Kein Offline-Fallback. +- **PublicDeckOwner.pseudonym=Bool** ist Web-Schema-Verschwurbel + (Server liefert `Boolean ‚use_pseudonym'`, nicht den Pseudonym- + String — der ist anderswo). Hatte 30 Min Fehlersuche, weil Codable + silent failed. +- **Web gewinnt bei Konflikt** zwingt Native zu nachzuziehen. Wenn + Web vorab Refactor macht, hat Native immer 1-Tag-Delay. +- **iOS-26-only-Features** für Sub-Surfaces ist Verstoss gegen + „iOS 18 Minimum"-Politik aus CLAUDE.md. Akzeptiert via Gate. + +## Offene Punkte + +- **Endurance-Test echtes iPhone**: ReviewQueue-Drift bei langem + Offline, Battery-Drain, Memory unter Pull-Update. +- **PDF-Export-Quality** für Image-Occlusion-Karten — Maske wird + zurzeit ohne Pencil-Trace gerendert. +- **AI-Import-Token-Budget** sichtbar machen (Credits-Anzeige). +- **Wire-Format-Drift-Detection**: Pseudonym-Bool-Fall war + silent-failure; sollte ein zod-Schema-Mismatch-Smoke-Test + fangen. +- **Localizable.xcstrings EN-Fallback** angelegt, aber nicht + übersetzt. diff --git a/devlog/2026-05-13/spieler.md b/devlog/2026-05-13/spieler.md new file mode 100644 index 0000000..eb78079 --- /dev/null +++ b/devlog/2026-05-13/spieler.md @@ -0,0 +1,50 @@ +--- +date: 2026-05-13 +day: 2 +view: spieler +weekday: Mittwoch +commits: 22 +review: written +--- +# Mittwoch, 2026-05-13 — Tag 2 + +Cardecky-Native sieht heute aus wie Cardecky — Karten-Fan auf dem +Dashboard, Multiple-Choice und Tippen werden ordentlich dargestellt, +und du kannst die App jetzt auch nutzen, **ohne dich anzumelden**: +Decks aus dem Marketplace anschauen, sogar lernen — Konto brauchst +du erst, wenn du etwas speichern willst. + +## Was sich für dich ändert + +- **Optik wie im Web** — die Tiles auf dem Dashboard fächern Karten + wie ein Kartenspiel auf, die Vorder-/Rückseiten werden so gerahmt + wie auf cardecky.mana.how. Wer Web und App nebeneinander hat, + findet sich sofort zurecht. +- **Multiple-Choice + Tippen funktionieren** — beide Karten-Typen + werden mit den passenden Eingaben dargestellt (Auswahl mit Buttons, + Tippen mit Antwort-Vergleich, der kleine Tippfehler verzeiht). +- **Gast-Modus** — du kannst Decks aus dem öffentlichen Marketplace + ansehen, ohne dich vorher anzumelden. Wenn du eigene Decks + speichern oder Fortschritt mitnehmen willst, kommst du an die + Anmelde-Wand. +- **Vollständige Anmelde-Reise nativ** — Registrieren, E-Mail- + bestätigen, Passwort vergessen, Konto-Verwalten, Konto löschen + funktionieren alle direkt in der App. +- **Deck-Detail mit Karten-Liste** — du siehst nicht nur den Titel, + sondern auch alle Karten im Deck. +- **„Neues Deck"-Pille** unten am Tab-Bar — schnelles Anlegen ohne + Umwege. +- **Edit-Icon auf Tiles** trennt „Tap = Lernen" von „Edit = Bearbeiten". +- **Import aus KI** — du kannst aus einem Text-Beschreibungs-Prompt + ein neues Deck erzeugen lassen. +- **Import aus CSV** für vorhandene Karten-Sammlungen. +- **Marketplace-Publish** — eigenes Deck (mit deinem Pseudonym oder + echtem Namen) öffentlich machen. +- **Moderation** für veröffentlichte Decks (Meldung, Take-Down). +- **PDF-Export** eines Decks für Offline-Ausdruck. + +## Hintergrund + +Cardecky-Native ist heute funktional fertig — alles, was die Web- +App kann, geht jetzt auch hier. Was fehlt, sind Endurance-Tests am +echten Gerät und der App-Store-Slot bei Apple. diff --git a/devlog/2026-05-14/data.json b/devlog/2026-05-14/data.json new file mode 100644 index 0000000..9f372d6 --- /dev/null +++ b/devlog/2026-05-14/data.json @@ -0,0 +1,61 @@ +{ + "date": "2026-05-14", + "day_number": 3, + "weekday": "Donnerstag", + "commits": 1, + "authors": [ + { + "name": "Till JS", + "count": 1 + } + ], + "additions": 6, + "deletions": 10, + "net_lines": -4, + "files_changed": 2, + "new_files": 0, + "deleted_files": 0, + "session": { + "first_commit_at": "2026-05-14T19:31:49.000Z", + "last_commit_at": "2026-05-14T19:31:49.000Z", + "total_span_minutes": 0, + "active_minutes": 0, + "pauses": [], + "longest_focus_minutes": 0 + }, + "top_dirs": [ + { + "path": "Sources/Features/Decks", + "pct": 50 + }, + { + "path": "Sources/Features/Marketplace", + "pct": 50 + } + ], + "top_extensions": [ + { + "ext": ".swift", + "count": 2 + } + ], + "tags": [ + "decks" + ], + "commits_list": [ + { + "hash": "8280d3d", + "short": "style(decks): inline title + scroll-transition entfernt für ruhigeren Look", + "type": "style", + "scope": "decks", + "additions": 6, + "deletions": 10, + "timestamp": "2026-05-14T21:31:49+02:00" + } + ], + "review_state": "auto", + "llm": { + "model": null, + "generated_at": null + } +} diff --git a/devlog/2026-05-14/macher.md b/devlog/2026-05-14/macher.md new file mode 100644 index 0000000..53350bd --- /dev/null +++ b/devlog/2026-05-14/macher.md @@ -0,0 +1,41 @@ +--- +date: 2026-05-14 +day: 3 +view: macher +weekday: Donnerstag +commits: 1 +review: written +--- +# Donnerstag, 2026-05-14 — Tag 3 (Macher-Sicht) + +Single-Commit-Tag: Style-Polish auf Decks- und Marketplace-Liste. +Inline-Title statt Large-Title-Shrink, scroll-transition entfernt. + +## Stats + +1 Commit, +6 / −10 LoC, 2 Files (Decks-List + Marketplace-List). +Tag: `decks`. Net −4 LoC — Code-Reduktion durch Entfernen, nicht +durch Refactor. + +## Was passierte + +- **Inline NavigationBar-Title** statt Large-Title-with-Shrink. + Large-Title sah auf iPad-Sidebar seltsam aus (Title schrumpft + bei Scroll, aber Sidebar hat keinen Scroll-Bezug). +- **scroll-transition entfernt** — die Tile-Karten hatten einen + `.scrollTransition`-Effekt, der beim Scrollen Karten am Rand + scalierte und blurte. Auf 60 Hz-iPhone OK, auf 120 Hz-iPad + Pro überanimiert, auf Mac wirr. + +## Architektur-Bemerkung + +CardSurface bleibt unverändert — der Effekt war nur in der List- +View-Wrapper-Schicht. Die einzelnen Cards animieren weiterhin +(Flip, Reveal), nur das Scroll-Drumherum nicht mehr. + +## Offene Punkte + +- **iPad-Split-Layout** könnte noch ein Polish-Pass — Sidebar + + Detail-Pane, statt iPhone-Stack adapted. +- **macOS-NavigationSplitView** im Cards-Stil (vergleiche + nutriphi-native ν-12). diff --git a/devlog/2026-05-14/spieler.md b/devlog/2026-05-14/spieler.md new file mode 100644 index 0000000..1a17b3d --- /dev/null +++ b/devlog/2026-05-14/spieler.md @@ -0,0 +1,18 @@ +--- +date: 2026-05-14 +day: 3 +view: spieler +weekday: Donnerstag +commits: 1 +review: written +--- +# Donnerstag, 2026-05-14 — Tag 3 + +Kleiner visueller Schliff: die Deck-Listen wirken jetzt **ruhiger +beim Scrollen**. Vorher gab es einen Schrumpf-Effekt am oberen Rand, +der eher abgelenkt als geholfen hat. + +## Hintergrund + +Manchmal sind UI-Animationen schön gemeint und stören doch. Eine +weniger ist eine weniger.