Phase 7c: Backfill Migration (HTML → Blocks)
Goal: Convert all 256 existing notes from monolithic
html_content to typed blocks. Populate compiled_pages with compiled HTML + TOC. One-time backfill.Owner: Dev agent
Repo: pal-e-docs
Depends on: Phase 7a (tables exist), Phase 7b (parser + compiler)
Parent phase: Phase 7 (Block-Structured Content Model)
Forgejo Issue: #100
PR: #101 (MERGED)
Status: IN PROGRESS — Deliverable 1 (migration script) complete. Deliverables 2-3 (run against production + validation) pending.
Why This Phase
The parser and compiler are proven by unit tests in 7b. Now we run them against the full corpus and populate the blocks table. This is a one-time data migration — the most critical step in Phase 7.
Deliverables
- Migration script: For each note, run the parser on
html_content, store resulting blocks in theblockstable with correct positions and anchor IDs. COMPLETE — PR #101 merged. - Compiled pages: For each note, compile blocks back to HTML, generate TOC JSON, compute content hash, store in
compiled_pages. PENDING — requires running script against production. - Validation report: Compare
compiled_pages.htmlvs originalhtml_contentfor all 256 notes. Flag any semantic differences. PENDING — requires running script against production. - Nest orphaned docs: After hierarchy relaxation (7a), set
parent_note_idfor the 6 identified orphans.
Migration Strategy
- Run as a one-time Alembic data migration or standalone script
html_contentstays populated (backward compat — existing MCP tools still read it)- Blocks are additive — they coexist with
html_content, not replace it - Use
kubectl exec+kubectl cppattern (port-forward is unreliable on k3s)
Acceptance Criteria
- All 256 notes have blocks in the
blockstable - All 256 notes have a
compiled_pagesentry - Round-trip validation: compiled HTML is semantically equivalent to original for 95%+ of notes
- Remaining notes (if any) have documented differences with manual review
- 6 orphaned docs nested under their logical parents
- Existing API / MCP behavior unchanged
Expected Block Counts
Based on baseline data (avg 7.7 headings/note, plus paragraphs/tables/lists between them):
- Estimated ~15-25 blocks per note average
- Total estimated blocks: ~4,000-6,500
- This is well within Postgres performance for indexed queries
Related
phase-postgres-7a-schema-hierarchy— tables must existphase-postgres-7b-parser-compiler— parser + compiler must be provenbenchmark-phase7-block-baseline— corpus metrics