Story: Book codegen drift remediation

Table of Contents

This page documents a story in Sprint 23. It captures the goal, current status, acceptance criteria, and the tasks that compose it.

Goal

Get book, book_status, and regulatory_book_type onto a clean, fully-regenerated, end-to-end-tested codegen baseline, then migrate book to composite-entity versioning and re-verify — so the new-work tasks parked in Book data model cleanup (book_purpose_type, ledger_feed_type, is_sweepable, Wash risk-book link, child-entity toolbar buttons) build on solid ground rather than compounding existing drift.

Discovered via compass codegen entity show: book has almost no ✅ files (nearly every layer stale against current templates) despite being fully codegen-synced as recently as PR #1449 (Sprint 22, "Commission: book") — the templates themselves have evolved since (composite-entity versioning support, NATS event registrars, a Qt client-model bug fix, license-header format). That same PR's history is a cautionary tale worth repeating here: its first regeneration attempt silently dropped book's 5 insert-trigger validations (soft FKs on parent_portfolio_id/party_id/owner_unit_id; value checks on ledger_ccy/book_status) because book.org lacked * Foreign keys=/=* Insert trigger sections at the time — caught only by 3 independent PR review bot passes, not by the regen itself.

Status

Field Value
State DONE
Parent sprint Sprint 23
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-07-12

Acceptance

  • book, book_status, and regulatory_book_type show all-✅ in compass codegen entity show (fully regenerated against current templates).
  • The 5 insert-trigger validations identified in PR #1449 (and any others found stale) are confirmed present in the regenerated SQL — via paste blocks or variability knobs in the .org models, not hand-patched post-generation.
  • book builds cleanly on the configured preset; end-to-end manual test (login, list, add, edit, save, rename, history) passes with no regressions.
  • Portfolio/Book are migrated to composite-entity versioning per Temporal Composite Entity Versioning: Target State (Portfolio is the composite parent, Book the child via parent_portfolio_id — not book_status/regulatory_book_type, which are enum-like FK attributes, not composite children), regenerated, and re-tested end to end.
  • Book data model cleanup's remaining new-work tasks are unblocked.

Tasks

Task State Start End Description
Regenerate book_status as a drift canary DONE 2026-07-11 2026-07-11 Regenerated and manually verified; found and fixed 2 real bugs (missing has_change_reason_cache, stale TradingPlugin.cpp call site) beyond the mechanical regen.
Regenerate regulatory_book_type DONE 2026-07-12 2026-07-12 Regenerated (had the same missing has_change_reason_cache gap as book_status, fixed proactively this time). Manual QA: all 6 steps PASS, zero ERROR-level log lines.
Regenerate book and restore insert-trigger validations DONE 2026-07-12 2026-07-12 Regenerated (all 40 files ✅); all 6 insert-trigger validations confirmed present and firing (direct SQL insert rejected on bad parent_portfolio_id). Manual QA: all 6 steps PASS.
End-to-end test book after regeneration ABANDONED     Superseded by the regen task's own manual QA scenario (login, list, add, edit, save, history, badges, change-reason) – a separate identical pass would be pure duplication.
Migrate Portfolio/Book to composite-entity versioning DONE 2026-07-12 2026-07-12 Rescoped: book_status/regulatory_book_type are enum-like FK attributes, not composite children – the real 1-to-many relationship is Portfolio (parent) -> Book (child, via parent_portfolio_id), matching the proven party/party_identifier shape.
Regenerate and re-test book after composite migration ABANDONED     Superseded by the composite-migration task's own full book regen and manual QA scenario – a separate identical pass would be pure duplication.

Decisions

  • book_status and regulatory_book_type are enum-like FK attributes (many books reference one lookup row), not composite children of Book – :bump_parent_version: there would be wrong (editing a status definition would spuriously bump every book referencing it).
  • The real 1-to-many composite relationship is Portfolio (parent) -> Book (child, via parent_portfolio_id), matching the proven party/party_identifier and counterparty/counterparty_identifier shape.
  • Portfolio's own parent_portfolio_id self-reference is registered as composite parent-and-child of itself so a grandchild book's write recursively bumps every ancestor portfolio up the tree, not just the immediate parent.
  • As-of resolution of an FK's meaning at a historical version (e.g. what "book_status" meant at time t) is a distinct, common concern from composite parent/child version bumping – scoped out to its own story, As-of lookup resolution codegen facet, rather than folded in here.
  • Portfolio's own Qt layer remains fully unmigrated/stale and out of scope for this story – its History dialog not live-refreshing on a sibling entity's (Book's) NATS events is a known, separately captured gap, not a regression from this work.

Out of scope

  • book_purpose_type, ledger_feed_type, is_sweepable, Wash risk-book link, and child-entity toolbar buttons – picked up next in Book data model cleanup, now unblocked.
  • As-of lookup resolution (resolving a historical FK value's meaning) – scoped to its own story.
  • Portfolio's own Qt-layer relocation/regeneration.

Result

book, book_status, and regulatory_book_type are fully regenerated against current codegen templates (all ✅ in compass codegen entity show), with the insert-trigger validations from PR #1449 confirmed present and firing. Portfolio/Book are migrated to composite-entity versioning: adding, editing, or deleting a book bumps its parent portfolio's version (and recursively bumps every ancestor up a nested portfolio tree), and "portfolio as of version N" correctly composes the books it contained at that point in time – verified directly via SQL, not just via generated code, at up to 3 levels deep. A real codegen-template bug (touch-function generation order vs. Postgres's eager CREATE RULE resolution, affecting self-referencing composite entities) was found and fixed along the way, confirmed safe for the existing party/counterparty pilot. All manual QA scenarios PASSED. Book data model cleanup's remaining new-work tasks are unblocked.

Emacs 29.3 (Org mode 9.6.15)