feat(01-01): implement TypeScript interfaces and IndexedDB wrapper

- All shared interfaces: Progress, Settings, ForestElement, CompanionAssets, etc.
- IndexedDB wrapper with 5 stores (progress, companionAssets, styleReference, forestElements, settings)
- CRUD for progress and settings stores
- 5 passing tests with fake-indexeddb

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-29 11:02:43 +02:00
co-authored by Claude Opus 4.6
parent 35c1ef1b80
commit 9912bfa387
5 changed files with 160 additions and 4 deletions
+72
View File
@@ -0,0 +1,72 @@
// Companion types
export type CompanionType = "fee" | "einhorn" | "fuchs" | "eule";
export type KeyboardLayout = "de" | "ch";
// Level status for the forest map
export type LevelStatus = "locked" | "current" | "completed";
// Progress store
export interface Progress {
id: 1; // singleton row
currentLevel: number;
completedLevels: number[];
totalSessions: number;
sessionDates: string[]; // ISO date strings (days only)
selectedCharacter: CompanionType;
selectedLayout: KeyboardLayout;
}
// Companion assets store
export interface CompanionAssets {
characterType: CompanionType;
characterSheet: Blob;
avatarImage: Blob;
generatedAt: string; // ISO date
}
// Style reference store
export interface StyleReference {
id: 1; // singleton
imageBlob: Blob;
generatedAt: string;
}
// Forest element store
export interface ForestElement {
id?: number; // auto-increment
levelCompleted: number;
imageBlob: Blob;
imagePrompt: string;
description: string;
companionText: string;
position: { x: number; y: number };
createdAt: string;
}
// Settings store
export interface Settings {
id: 1; // singleton
audioEnabled: boolean;
apiKey: string;
}
// Level definition (used in game/levels.ts)
export interface Level {
level: number;
newKeys: string[];
allKeys: string[]; // cumulative keys up to this level
fingerMap: Record<string, string>; // key -> CSS variable name for finger color
}
// Typing exercise state
export interface TypingExerciseState {
currentLetterIndex: number;
letters: string[];
intervalMs: number;
correctStreak: number;
totalCorrect: number;
totalErrors: number;
}
// Screen names
export type ScreenName = "welcome" | "forest" | "lesson" | "reward" | "parent";