devlog: 3 Tage geschrieben (v0.1.0 → v0.9.4)
Tag 1: β-0 bis β-7 Marathon (Skelett → App-Store-Vorbereitung). Tag 2: Cardecky-Web-Look + alle 7 Card-Types + ManaAuthUI + Guest-Mode + γ-1 bis γ-8 (AI/CSV-Import, Marketplace, PDF). Tag 3: kleiner Style-Polish. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8280d3d0ba
commit
c0b0c902bc
9 changed files with 939 additions and 0 deletions
183
devlog/2026-05-12/data.json
Normal file
183
devlog/2026-05-12/data.json
Normal file
|
|
@ -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
|
||||
}
|
||||
}
|
||||
105
devlog/2026-05-12/macher.md
Normal file
105
devlog/2026-05-12/macher.md
Normal file
|
|
@ -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.
|
||||
45
devlog/2026-05-12/spieler.md
Normal file
45
devlog/2026-05-12/spieler.md
Normal file
|
|
@ -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.
|
||||
317
devlog/2026-05-13/data.json
Normal file
317
devlog/2026-05-13/data.json
Normal file
|
|
@ -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
|
||||
}
|
||||
}
|
||||
119
devlog/2026-05-13/macher.md
Normal file
119
devlog/2026-05-13/macher.md
Normal file
|
|
@ -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.
|
||||
50
devlog/2026-05-13/spieler.md
Normal file
50
devlog/2026-05-13/spieler.md
Normal file
|
|
@ -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.
|
||||
61
devlog/2026-05-14/data.json
Normal file
61
devlog/2026-05-14/data.json
Normal file
|
|
@ -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
|
||||
}
|
||||
}
|
||||
41
devlog/2026-05-14/macher.md
Normal file
41
devlog/2026-05-14/macher.md
Normal file
|
|
@ -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).
|
||||
18
devlog/2026-05-14/spieler.md
Normal file
18
devlog/2026-05-14/spieler.md
Normal file
|
|
@ -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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue