Task: Retire per-entity history dialog templates for the generic HistoryDialog

Table of Contents

This page documents a task in the Consolidate history dialogs onto HistoryDialogBase story. It captures the goal, current status, acceptance, and any notes or results.

Goal

Implement History Diff Architecture end to end, replacing every one of the 67 *HistoryDialog classes (the 6 hand-rolled ones migrated onto HistoryDialogBase earlier in this story, plus the 61 codegen-generated ones this task was originally scoped to) with a single, non-templated HistoryDialog widget. This supersedes the original "adopt HistoryDialogBase in the template" scope: rather than migrating per-entity generated dialogs onto a shared base class, the per-entity dialog classes and their generating templates are retired outright.

Was gated on the codegen org-model migration: that migration (Codegen unified model — org-mode migration) completed 2026-06-11 — the gate is clear. This task additionally depended on Redesign server-side history-diff architecture (DONE 2026-07-11) for the design it implements.

Status

Field Value
State ABANDONED
Parent story Consolidate history dialogs onto HistoryDialogBase
Now Split into six finer-grained sibling tasks below; this umbrella task closed with no code changes.
Waiting on Nothing.
Next Pick up ores.diff: intra-value diff spans first (nothing else depends on it, and everything downstream needs it).
Last touched 2026-07-11

Acceptance

  • One generic NATS history subject (history.v1.get) exists, with a server-side dispatch table keyed by entity_type_of(); every entity's typed get_<entity>_history subject is removed.
  • Every entity has a codegen'd, plain (not hand-written, not generic- reflection) field-to-string mapper, registered as a history provider.
  • ores.diff::diff_entry carries old_spans=/=new_spans; the test coverage list in the redesign task's Notes is satisfied.
  • HistoryDialogBase and all per-entity *HistoryDialog classes are deleted, along with cpp_qt_history_dialog.{hpp,cpp}.mustache and qt_history_dialog_ui.mustache; a single HistoryDialog widget replaces them, taking (entity_type, entity_id).
  • Open=/=Revert dispatch through a codegen'd per-entity action registry (client side); no typed domain payload flows through HistoryDialog signals.
  • ores.shell's disabled currencies history-diff command is replaced by one generic entity-parameterised shell renderer, re-enabled for every entity.
  • History responses carry no full domain payload; open/revert fetch the typed entity by id/version through each entity's existing typed request when needed.
  • Zero-diff regeneration checks green for whatever codegen facets remain (field mapper, history-provider/action registrations); no facet still emits a per-entity dialog class.

Plan

  1. ores.diff: add diff_span to diff_entry; implement span computation in engine::compute (prefix/suffix for single-line, line-LCS + per-line token diff for multiline); cover the test list from the redesign task's Notes.
  2. Entity identifier: add the entity_type_of() codegen facet, generating the free-function trait per entity.
  3. Server side: add the per-entity field-mapper codegen facet; introduce the generic history.v1.get subject and its dispatch-table handler (reapplying Entity-composed registrars); register each entity's mapper as a history provider; remove the per-entity get_<entity>_history subjects and handlers as each entity migrates.
  4. Qt: build the single HistoryDialog widget (version list, async load, toolbar, changes-tab rendering with diff_span colour highlighting per the GitHub-style capture); add the codegen'd per-entity Open=/=Revert action registry; wire callers (list windows/controllers) to construct HistoryDialog(entity_type, entity_id) instead of a typed dialog subclass.
  5. Retire the old shape: delete HistoryDialogBase, every per-entity *HistoryDialog class, and cpp_qt_history_dialog.{hpp,cpp}.mustache=/=qt_history_dialog_ui.mustache once every entity has migrated; zero-diff guardrails confirm no facet still emits them.
  6. Shell: replace the disabled currencies history-diff command with the generic entity-parameterised renderer, re-enabled for every entity.
  7. Composite entities: wire the "Details" affordance for child-driven versions (per the architecture doc's composite section) — opens another HistoryDialog instance with the child's (entity_type, entity_id).

Given the size, this likely wants splitting into sub-tasks by phase (ores.diff spans; server dispatch; Qt widget; shell; retirement sweep) once implementation starts — revisit before diving in.

Notes

PRs

PR Title
   

Review

Comment summary File Decision Notes
       

Result

Split into six finer-grained sibling tasks, one per Plan phase, before any implementation started — this task's own scope was too large to track as a single unit of work:

  1. ores.diff: intra-value diff spans
  2. Codegen the entity_type_of() identifier trait
  3. Generic server-side history dispatch: one subject, per-entity handlers
  4. Single generic HistoryDialog widget in ores.qt
  5. Retire HistoryDialogBase, per-entity dialogs, and their templates
  6. Generic unified-diff history renderer in ores.shell

Dependency order: (1) and (2) are independent and can run in either order; (3) needs both; (4) and (6) each need (3); (5) needs (4) and (6) — it retires the old shape only once nothing still depends on it. This task closes with no code changes; its Plan and Acceptance were distributed into the six tasks above.

Emacs 29.3 (Org mode 9.6.15)