From c268c6050ee9f6d296f149b80b05ba949b7d30d8 Mon Sep 17 00:00:00 2001 From: Markus Graf Date: Sun, 29 Mar 2026 11:57:53 +0200 Subject: [PATCH] docs(02-01): complete config loader & Gemini API client plan - SUMMARY.md with 18 tests, 6 files, 3min execution - STATE.md advanced to plan 2/5, 70% progress - ROADMAP.md updated with plan progress - Requirements GAPI-01, GAPI-02, GAPI-03, GAPI-06 marked complete Co-Authored-By: Claude Opus 4.6 (1M context) --- .planning/REQUIREMENTS.md | 16 +-- .planning/ROADMAP.md | 2 +- .planning/STATE.md | 16 ++- .../02-01-SUMMARY.md | 135 ++++++++++++++++++ 4 files changed, 154 insertions(+), 15 deletions(-) create mode 100644 .planning/phases/02-gemini-integration-asset-pipeline/02-01-SUMMARY.md diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 0ab51d3..959ab09 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -51,12 +51,12 @@ Requirements for initial release (MVP). Each maps to roadmap phases. ### Gemini API -- [ ] **GAPI-01**: Config-Loader: `public/config.json` via fetch laden, typisiertes Interface -- [ ] **GAPI-02**: Text-API-Client: `generateText(prompt, systemPrompt)` mit Retry und Fehlerbehandlung -- [ ] **GAPI-03**: Bild-API-Client: `generateImage(prompt, referenceImages[])` mit Character Consistency +- [x] **GAPI-01**: Config-Loader: `public/config.json` via fetch laden, typisiertes Interface +- [x] **GAPI-02**: Text-API-Client: `generateText(prompt, systemPrompt)` mit Retry und Fehlerbehandlung +- [x] **GAPI-03**: Bild-API-Client: `generateImage(prompt, referenceImages[])` mit Character Consistency - [x] **GAPI-04**: Fallback-Texte: 10 Begrüssungen, 10 Wald-Kommentare, Buchstaben-Vorstellungen Stufe 1–6 - [x] **GAPI-05**: Fallback-Bilder: 5–10 statische SVG/PNG-Bilder als Backup -- [ ] **GAPI-06**: Rate-Limiting: Max 1 Bild + 1 Text pro Übungseinheit +- [x] **GAPI-06**: Rate-Limiting: Max 1 Bild + 1 Text pro Übungseinheit ### Assets @@ -173,12 +173,12 @@ Which phases cover which requirements. Updated during roadmap creation. | FRST-04 | Phase 1 | Complete | | FRST-05 | Phase 1 | Complete | | PLSH-06 | Phase 1 | Complete | -| GAPI-01 | Phase 2 | Pending | -| GAPI-02 | Phase 2 | Pending | -| GAPI-03 | Phase 2 | Pending | +| GAPI-01 | Phase 2 | Complete | +| GAPI-02 | Phase 2 | Complete | +| GAPI-03 | Phase 2 | Complete | | GAPI-04 | Phase 2 | Complete | | GAPI-05 | Phase 2 | Complete | -| GAPI-06 | Phase 2 | Pending | +| GAPI-06 | Phase 2 | Complete | | ASST-01 | Phase 2 | Pending | | ASST-02 | Phase 2 | Pending | | ASST-03 | Phase 2 | Pending | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index e266d78..cf56a15 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -52,7 +52,7 @@ Plans: **Plans:** 5 plans Plans: -- [ ] 02-01-PLAN.md — Config loader, Gemini API client (text + image), retry logic, rate-limiting (TDD) +- [x] 02-01-PLAN.md — Config loader, Gemini API client (text + image), retry logic, rate-limiting (TDD) - [x] 02-02-PLAN.md — Fallback texts (greetings, forest comments, letter intros) and fallback SVG images - [ ] 02-03-PLAN.md — IndexedDB store accessors, build script for asset generation, generate all character assets - [ ] 02-04-PLAN.md — Companion text module (getGreeting, getLetterIntro, getForestComment) with API-first fallback diff --git a/.planning/STATE.md b/.planning/STATE.md index 9474355..7b74ea4 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: executing -stopped_at: Completed 02-02-PLAN.md -last_updated: "2026-03-29T09:56:04.201Z" +stopped_at: Completed 02-01-PLAN.md +last_updated: "2026-03-29T09:57:41.199Z" last_activity: 2026-03-29 progress: total_phases: 4 completed_phases: 1 total_plans: 10 - completed_plans: 6 + completed_plans: 7 percent: 0 --- @@ -26,7 +26,7 @@ See: .planning/PROJECT.md (updated 2026-03-29) ## Current Position Phase: 02 (gemini-integration-asset-pipeline) — EXECUTING -Plan: 2 of 5 +Plan: 3 of 5 Status: Ready to execute Last activity: 2026-03-29 @@ -58,6 +58,7 @@ Progress: [░░░░░░░░░░] 0% | Phase 01 P04 | 2min | 2 tasks | 6 files | | Phase 01 P05 | 2min | 2 tasks | 4 files | | Phase 02 P02 | 2min | 2 tasks | 8 files | +| Phase 02 P01 | 3min | 1 tasks | 6 files | ## Accumulated Context @@ -77,6 +78,9 @@ Recent decisions affecting current work: - [Phase 01]: Forest screen re-initializes on every navigation to reflect updated progress - [Phase 02]: Fallback texts use ue/oe/ae transliteration for umlauts, consistent with existing codebase convention - [Phase 02]: SVGs use gradient-based rendering under 2KB each for watercolor feel +- [Phase 02]: Rate limiting stored in Settings singleton, no new IndexedDB store +- [Phase 02]: Image generation no retry (expensive), text retries 3x exponential backoff +- [Phase 02]: Config loader caches after first fetch, resetConfigCache() for testing ### Pending Todos @@ -88,6 +92,6 @@ None yet. ## Session Continuity -Last session: 2026-03-29T09:56:04.194Z -Stopped at: Completed 02-02-PLAN.md +Last session: 2026-03-29T09:57:41.192Z +Stopped at: Completed 02-01-PLAN.md Resume file: None diff --git a/.planning/phases/02-gemini-integration-asset-pipeline/02-01-SUMMARY.md b/.planning/phases/02-gemini-integration-asset-pipeline/02-01-SUMMARY.md new file mode 100644 index 0000000..02c8852 --- /dev/null +++ b/.planning/phases/02-gemini-integration-asset-pipeline/02-01-SUMMARY.md @@ -0,0 +1,135 @@ +--- +phase: 02-gemini-integration-asset-pipeline +plan: 01 +subsystem: api +tags: [gemini, rest-api, fetch, indexeddb, rate-limiting, config-loader] + +# Dependency graph +requires: + - phase: 01-grundgeruest-tippmechanik + provides: "IndexedDB wrapper (openDB, getSettings, saveSettings) and Settings type" +provides: + - "GeminiConfig interface and loadConfig() with caching" + - "generateText() with 3x exponential backoff retry" + - "generateImage() with reference image support as base64 inlineData" + - "checkRateLimit() and incrementApiCall() for daily API call tracking" + - "Extended Settings type with apiCallsToday and lastApiCallDate" +affects: [02-02, 02-03, 02-04, 02-05, asset-pipeline, companion-system, forest-rewards] + +# Tech tracking +tech-stack: + added: [] + patterns: [gemini-rest-client, exponential-backoff-retry, config-caching, rate-limit-via-settings-store] + +key-files: + created: + - src/api/config.ts + - src/api/config.test.ts + - src/api/gemini.ts + - src/api/gemini.test.ts + modified: + - src/types.ts + - src/storage/db.test.ts + +key-decisions: + - "Rate limiting stored in Settings singleton via getSettings/saveSettings (no new store)" + - "Image generation has no retry (too expensive), text generation retries 3x with [1s, 2s, 4s] backoff" + - "Config loader caches after first successful fetch, resetConfigCache() for testing" + - "loadConfigFromObject() provided for Node.js build script usage" + +patterns-established: + - "Gemini REST pattern: POST to v1beta/models/{model}:generateContent with key param" + - "Null-return pattern: all API functions return null on failure, callers use fallback" + - "Daily reset pattern: compare lastApiCallDate to today, reset counters if different" + +requirements-completed: [GAPI-01, GAPI-02, GAPI-03, GAPI-06] + +# Metrics +duration: 3min +completed: 2026-03-29 +--- + +# Phase 02 Plan 01: Config Loader & Gemini API Client Summary + +**Isomorphic Gemini REST client with config caching, text/image generation, exponential backoff retry, and per-day rate limiting via IndexedDB Settings store** + +## Performance + +- **Duration:** 3 min +- **Started:** 2026-03-29T09:52:49Z +- **Completed:** 2026-03-29T09:56:41Z +- **Tasks:** 1 (TDD: RED + GREEN) +- **Files modified:** 6 + +## Accomplishments +- Config loader fetches and caches public/config.json with typed GeminiConfig interface +- generateText sends correct Gemini REST request with systemInstruction, retries 3x on failure with exponential backoff [1s, 2s, 4s] +- generateImage converts reference Blobs to base64 inlineData parts, sets responseModalities: ["IMAGE"] +- Rate limiting tracks text/image API calls per day in Settings store with automatic daily reset +- 18 tests across config.test.ts and gemini.test.ts, all passing (55 total project tests) + +## Task Commits + +Each task was committed atomically: + +1. **Task 1 (RED): Failing tests** - `b31b9fd` (test) +2. **Task 1 (GREEN): Implementation** - `2bea324` (feat) + +_TDD task with RED (failing tests) and GREEN (implementation) commits._ + +## Files Created/Modified +- `src/api/config.ts` - GeminiConfig interface, loadConfig() with caching, resetConfigCache() +- `src/api/config.test.ts` - 6 tests for config loader (fetch, errors, caching) +- `src/api/gemini.ts` - generateText(), generateImage(), checkRateLimit(), incrementApiCall() +- `src/api/gemini.test.ts` - 12 tests for text/image generation and rate limiting +- `src/types.ts` - Extended Settings with apiCallsToday and lastApiCallDate +- `src/storage/db.test.ts` - Updated Settings test fixture with new fields + +## Decisions Made +- Rate limiting stored in existing Settings singleton (no new IndexedDB store needed) +- Image generation has no retry logic (too expensive per plan spec), only text retries +- Config loader includes loadConfigFromObject() for future Node.js build script usage +- Blob-to-base64 conversion uses arrayBuffer + manual binary encoding (no FileReader needed) + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] Fixed TypeScript strict null errors in array indexing** +- **Found during:** Task 1 GREEN phase +- **Issue:** TypeScript strict mode flagged RETRY_DELAYS[attempt] and split("T")[0] as possibly undefined +- **Fix:** Added nullish coalescing fallbacks (e.g., `?? 1000`, `?? ""`) +- **Files modified:** src/api/gemini.ts, src/api/gemini.test.ts +- **Verification:** `npx tsc --noEmit` passes for all api/ files +- **Committed in:** 2bea324 + +**2. [Rule 1 - Bug] Updated db.test.ts Settings fixture for extended type** +- **Found during:** Task 1 GREEN phase +- **Issue:** Existing db.test.ts Settings object missing new apiCallsToday and lastApiCallDate fields +- **Fix:** Added missing fields to test fixture +- **Files modified:** src/storage/db.test.ts +- **Verification:** All 55 tests pass +- **Committed in:** 2bea324 + +--- + +**Total deviations:** 2 auto-fixed (2 bugs) +**Impact on plan:** Both fixes required for type safety and test correctness. No scope creep. + +## Issues Encountered +- Pre-existing TypeScript errors in src/companion/fallbacks.ts (not caused by this plan, out of scope) + +## Known Stubs +None - all functions are fully implemented with real logic. + +## User Setup Required +None - no external service configuration required. + +## Next Phase Readiness +- Gemini API client ready for use by prompt templates (02-02), image pipeline (02-03), and companion dialog (02-04) +- Config must exist at public/config.json with geminiApiKey, geminiModel, imageModel fields +- No blockers for subsequent plans + +--- +*Phase: 02-gemini-integration-asset-pipeline* +*Completed: 2026-03-29*