146 lines
4.4 KiB
Markdown
146 lines
4.4 KiB
Markdown
# 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<string>; // 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
|