Files
Zauberwald/.planning/phases/04-polish-audio/04-03-PLAN.md
T

232 lines
9.0 KiB
Markdown
Raw Normal View History

2026-03-29 18:12:06 +02:00
---
phase: 04-polish-audio
plan: 03
type: execute
wave: 1
depends_on: []
files_modified:
- src/ui/parent.ts
- index.html
- src/styles/main.css
- src/storage/db.ts
autonomous: true
requirements: [PRNT-05, PRNT-06, PRNT-07]
must_haves:
truths:
- "Export-Button ladet JSON-Datei mit Progress und Settings herunter (keine Blobs)"
- "Import-Button oeffnet Dateiauswahl, validiert JSON, ueberschreibt nach Bestaetigung"
- "Reset loescht alle 5 IndexedDB Stores nach doppelter Bestaetigung und reloaded"
artifacts:
- path: "src/ui/parent.ts"
provides: "Export, Import, Reset functions"
exports: ["exportData", "importData", "resetAllData"]
- path: "index.html"
provides: "Daten section in parent screen with Export/Import/Reset buttons"
contains: "export-btn"
key_links:
- from: "src/ui/parent.ts"
to: "src/storage/db.ts"
via: "getProgress, getSettings for export; saveProgress, saveSettings for import; db.clear for reset"
pattern: "getProgress.*getSettings|clear"
---
<objective>
Export/Import/Reset im Elternbereich: Fortschritt als JSON exportieren, JSON importieren mit Validierung, alles zuruecksetzen mit doppelter Bestaetigung.
Purpose: Datensicherung und Reset-Moeglichkeit per D-12 bis D-14 aus CONTEXT.md. Eltern koennen Fortschritt sichern und bei Bedarf wiederherstellen.
Output: Daten-Sektion im Parent-Screen mit drei Buttons, Logik in parent.ts.
</objective>
<execution_context>
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
@$HOME/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/phases/04-polish-audio/04-CONTEXT.md
@src/ui/parent.ts
@src/storage/db.ts
@src/types.ts
@index.html
@src/styles/main.css
</context>
<interfaces>
<!-- Key types the executor needs from existing code -->
From src/types.ts:
```typescript
export interface Progress {
id: 1;
currentLevel: number;
completedLevels: number[];
totalSessions: number;
sessionDates: string[];
selectedCharacter: CompanionType;
selectedLayout: KeyboardLayout;
totalCorrect: number;
totalErrors: number;
errorKeyCounts: Record<string, number>;
lastPlayedLevels: number[];
}
export interface Settings {
id: 1;
audioEnabled: boolean;
apiKey: string;
apiCallsToday: { text: number; image: number };
lastApiCallDate: string;
}
```
From src/storage/db.ts:
```typescript
export function getProgress(db: IDBDatabase): Promise<Progress | null>;
export function saveProgress(db: IDBDatabase, progress: Progress): Promise<void>;
export function getSettings(db: IDBDatabase): Promise<Settings | null>;
export function saveSettings(db: IDBDatabase, settings: Settings): Promise<void>;
```
From src/ui/parent.ts:
```typescript
export function showParentCodePrompt(): void;
export function initParentScreen(db: IDBDatabase, onBack: () => void): void;
```
</interfaces>
<tasks>
<task type="auto">
<name>Task 1: HTML Daten-Section + Export/Import/Reset buttons</name>
<files>index.html, src/styles/main.css</files>
<read_first>index.html, src/styles/main.css</read_first>
<action>
1. In `index.html`: Add a third `<section>` inside `#parent-content`, after the Einstellungen section (per D-12, D-13, D-14):
```html
<section class="parent__section">
<h2>Daten</h2>
<div class="parent__data-actions">
<button class="parent__action-btn" id="export-btn">Fortschritt exportieren</button>
<div class="parent__import-row">
<button class="parent__action-btn" id="import-btn">Fortschritt importieren</button>
<input type="file" id="import-file" accept=".json" style="display:none">
</div>
<button class="parent__action-btn parent__action-btn--danger" id="reset-btn">Alles zuruecksetzen</button>
</div>
<p class="parent__data-info" id="data-feedback" style="display:none"></p>
</section>
```
2. In `src/styles/main.css`: Add styles for data section:
```css
.parent__data-actions {
display: flex;
flex-direction: column;
gap: 0.75rem;
max-width: 300px;
}
.parent__action-btn {
font-family: 'Quicksand', sans-serif;
font-size: 1rem;
padding: 0.6rem 1.2rem;
border: 2px solid var(--accent-green);
background: var(--bg-cream);
color: var(--text-dark);
border-radius: 8px;
cursor: pointer;
transition: background 0.2s;
}
.parent__action-btn:hover {
background: var(--bg-forest);
}
.parent__action-btn--danger {
border-color: #D46A6A;
color: #D46A6A;
}
.parent__action-btn--danger:hover {
background: #FDE8E8;
}
.parent__data-info {
font-size: 0.9rem;
color: var(--accent-green);
margin-top: 0.5rem;
}
```
</action>
<verify>
<automated>cd /home/dev/workspace/zauberwald && grep -c "export-btn\|import-btn\|reset-btn\|import-file\|parent__action-btn" index.html src/styles/main.css</automated>
</verify>
<acceptance_criteria>
- index.html contains section with h2 "Daten" inside parent-content
- index.html contains buttons with ids export-btn, import-btn, reset-btn
- index.html contains hidden input#import-file with accept=".json"
- main.css contains .parent__action-btn and .parent__action-btn--danger styles
</acceptance_criteria>
<done>Daten section visible in parent area with Export, Import, Reset buttons properly styled</done>
</task>
<task type="auto">
<name>Task 2: Export/Import/Reset logic in parent.ts</name>
<files>src/ui/parent.ts, src/storage/db.ts</files>
<read_first>src/ui/parent.ts, src/storage/db.ts, src/types.ts</read_first>
<action>
1. In `src/ui/parent.ts`, add Export function (per D-12):
- `async function exportData(db: IDBDatabase)`: Get progress + settings via existing functions. Build JSON object `{ version: 1, exportedAt: new Date().toISOString(), progress, settings }`. Create Blob, create object URL, create temporary `<a>` link with download="zauberwald-backup.json", click it, revoke URL. Show feedback "Exportiert!" in `#data-feedback`.
2. Add Import function (per D-13):
- `async function importData(db: IDBDatabase, file: File)`: Read file as text. Parse JSON. Validate structure:
- Must have `progress` object with required fields (currentLevel: number, completedLevels: array, totalSessions: number, selectedCharacter: string, selectedLayout: string)
- Must have `settings` object with required fields (audioEnabled: boolean)
- If validation fails, show error in `#data-feedback` ("Ungueltige Datei") and return
- Show confirm dialog: `confirm("Fortschritt ueberschreiben? Aktuelle Daten gehen verloren.")`
- If confirmed: `saveProgress(db, { ...parsed.progress, id: 1 })`, `saveSettings(db, { ...parsed.settings, id: 1 })`. Show "Importiert!" feedback. Reload after 1.5s.
3. Add Reset function (per D-14):
- `async function resetAllData(db: IDBDatabase)`: First confirm: `confirm("Wirklich alles loeschen?")`. Second confirm: `confirm("Alle Fortschritte und Einstellungen werden geloescht. Bist du sicher?")`. If both confirmed:
- Clear all 5 stores: `db.transaction(storeName, 'readwrite').objectStore(storeName).clear()` for each of: progress, companionAssets, styleReference, forestElements, settings
- After all clear: `location.reload()`
- Optionally add a helper `clearStore(db, name)` returning a Promise.
4. Wire buttons in `loadParentData()` (called after code entry):
- `document.getElementById('export-btn')!.onclick = () => exportData(db)`
- `document.getElementById('import-btn')!.onclick = () => document.getElementById('import-file')!.click()`
- `document.getElementById('import-file')!.addEventListener('change', (e) => { const file = (e.target as HTMLInputElement).files?.[0]; if (file) importData(db, file); })`
- `document.getElementById('reset-btn')!.onclick = () => resetAllData(db)`
</action>
<verify>
<automated>cd /home/dev/workspace/zauberwald && npx tsc --noEmit 2>&1 | head -20</automated>
</verify>
<acceptance_criteria>
- parent.ts contains exportData function that creates JSON download
- parent.ts contains importData function that validates and confirms before overwriting
- parent.ts contains resetAllData function with double confirmation
- Export excludes Blobs (only progress + settings)
- Import validates required fields before saving
- Reset clears all 5 IndexedDB stores
- All three buttons wired in loadParentData
- TypeScript compiles without errors
</acceptance_criteria>
<done>Export downloads zauberwald-backup.json, Import validates+confirms+overwrites, Reset double-confirms+clears+reloads</done>
</task>
</tasks>
<verification>
- `npx tsc --noEmit` passes
- `npm run lint` passes
- grep confirms export-btn, import-btn, reset-btn in index.html
- grep confirms exportData, importData, resetAllData in parent.ts
</verification>
<success_criteria>
Parent area has working Export (JSON download), Import (file upload + validation + confirmation), and Reset (double confirmation + full wipe).
</success_criteria>
<output>
After completion, create `.planning/phases/04-polish-audio/04-03-SUMMARY.md`
</output>