From eac1dac180de1d2c257c2096719a3b834af58b26 Mon Sep 17 00:00:00 2001 From: xRangerDE Date: Mon, 11 May 2026 22:17:22 +0200 Subject: [PATCH] docs(plan): Plan 04 Smart-Resume Foundation (storage layer only) Co-Authored-By: Claude Opus 4.7 (1M context) --- tasks/v5.0.0-plan-04-resume-foundation.md | 145 ++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 tasks/v5.0.0-plan-04-resume-foundation.md diff --git a/tasks/v5.0.0-plan-04-resume-foundation.md b/tasks/v5.0.0-plan-04-resume-foundation.md new file mode 100644 index 0000000..0a8510d --- /dev/null +++ b/tasks/v5.0.0-plan-04-resume-foundation.md @@ -0,0 +1,145 @@ +# Plan 04: Smart-Resume Foundation (Pillar 6 — Storage-Layer) + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans. + +**Goal:** Chunk-Index-Schema in SQLite + sha1-Hash-Helper-Modul. Vorbereitung fuer den eigentlichen Smart-Resume-Mechanismus, der in einem Folgeplan in den bestehenden Recorder integriert wird. Plan 04 ist rein additiv — kein bestehender Code wird modifiziert. + +**Architecture:** Neue Tabelle `chunk_index` (additiv im Schema). Hash-Helpers als pure infra-Modul (sha1 von Buffer + Streaming-File-Hash). Store-Modul (CRUD) folgt dem Pattern von `token-store`. + +**Tech Stack:** Node `crypto` (sha1), better-sqlite3, vitest. + +--- + +## Out of Scope + +- Integration in den bestehenden Recorder/Downloader (kommt in Plan 04b) +- Resume-Logik beim App-Start (Plan 04b) +- HLS-Manifest-Parser (vielleicht Plan 04b) + +--- + +## File Structure + +**Neu:** +- `src/main/infra/chunk-hash.ts` — sha1-Helper (Buffer + File) +- `src/main/infra/chunk-hash.test.ts` +- `src/main/domain/chunk-index-store.ts` — CRUD auf chunk_index +- `src/main/domain/chunk-index-store.test.ts` + +**Modifiziert:** +- `src/main/infra/schema-v5.ts` — neue Tabelle `chunk_index` +- `src/main/infra/db.test.ts` — 1 Test fuer neue Tabelle +- `CLAUDE.md` +- `tasks/v5.0.0-roadmap.md` + +--- + +## Tasks + +### Task 1: Schema-Extension chunk_index + +In schema-v5.ts vor `migrations_applied`: + +```sql +CREATE TABLE IF NOT EXISTS chunk_index ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + item_id TEXT NOT NULL, + chunk_seq INTEGER NOT NULL, + sha1_hex TEXT NOT NULL, + bytes INTEGER NOT NULL, + created_at INTEGER NOT NULL DEFAULT (strftime('%s','now')), + UNIQUE(item_id, chunk_seq) +); + +CREATE INDEX IF NOT EXISTS idx_chunk_item ON chunk_index(item_id); +CREATE INDEX IF NOT EXISTS idx_chunk_sha1 ON chunk_index(sha1_hex); +``` + +- [ ] Schema-Konstante erweitern +- [ ] db.test.ts: 1 neuer Test fuer chunk_index +- [ ] Commit: `feat(db): add chunk_index table (sha1 of recorded HLS segments)` + +--- + +### Task 2: chunk-hash Modul + +**API:** +```typescript +export function hashBuffer(b: Buffer): string; // sha1 hex +export function hashFile(filePath: string): Promise; // streaming sha1 +``` + +**Tests:** +- known input → known sha1 (fixture: `'hello'` → `aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d`) +- empty buffer → `da39a3ee5e6b4b0d3255bfef95601890afd80709` +- File hash via tmp file matches buffer hash for same content +- Large file (1MB+) hashes successfully + +- [ ] Tests + Modul +- [ ] Commit: `feat(resume): chunk-hash sha1 helpers (4 tests)` + +--- + +### Task 3: chunk-index-store Modul + +**API:** +```typescript +export interface ChunkRecord { + id: number; + itemId: string; + chunkSeq: number; + sha1Hex: string; + bytes: number; + createdAt: number; +} + +export interface ChunkIndexStore { + record(itemId: string, chunkSeq: number, sha1Hex: string, bytes: number): ChunkRecord; + listForItem(itemId: string): ChunkRecord[]; + countForItem(itemId: string): number; + lookupBySha1(sha1Hex: string): ChunkRecord[]; + deleteForItem(itemId: string): number; // returns deleted-row count +} + +export function createChunkIndexStore(db: DbHandle): ChunkIndexStore; +``` + +**Tests (mit MemorySecureStorage NICHT noetig — kein encryption hier):** +1. record + listForItem +2. UNIQUE(item_id, chunk_seq) — zweimal gleicher (itemId, chunkSeq) → INSERT OR REPLACE (latest wins) +3. countForItem +4. lookupBySha1 (dedupe-Erkennung) +5. deleteForItem +6. Ordering — listForItem nach chunk_seq ASC +7. Bytes-Roundtrip + +- [ ] Tests + Modul +- [ ] Commit: `feat(resume): chunk-index-store CRUD (7 tests)` + +--- + +### Task 4: Full Verification + Bump 5.0.0-alpha.3 + +- [ ] `npm run test:e2e:release` Exit 0 (unit jetzt >= 138) +- [ ] `npm version 5.0.0-alpha.3 --no-git-tag-version` +- [ ] Commit + Tag v5.0.0-alpha.3 + +--- + +### Task 5: Docs + +CLAUDE.md "Smart-Resume" Notiz: +> Recorded HLS-Segments koennen mit sha1-Hash in `chunk_index` Tabelle protokolliert werden (`src/main/domain/chunk-index-store.ts`). Vorbereitung fuer Crash-Recovery + Integrity-Check; eigentliche Integration in den Recorder kommt in Folgeplan. + +Roadmap: Plan 04 → DONE, Plan 04b "Resume Integration" als naechster Eintrag. + +--- + +## Done-Definition + +1. `chunk_index` Tabelle existiert nach openDatabase +2. hashBuffer + hashFile getestet (known-input + roundtrip) +3. ChunkIndexStore CRUD getestet +4. test:e2e:release Exit 0 +5. >= 12 neue unit tests +6. v5.0.0-alpha.3 getaggt