Skip to content

Fix/snap savemodifiedtree#47

Merged
willwade merged 2 commits intomainfrom
fix/snap-savemodifiedtree
May 1, 2026
Merged

Fix/snap savemodifiedtree#47
willwade merged 2 commits intomainfrom
fix/snap-savemodifiedtree

Conversation

@willwade
Copy link
Copy Markdown
Collaborator

@willwade willwade commented May 1, 2026

Snap: ship saveModifiedTree properly on main
main was missing two things vs feature-mutationAPI:

The whole SnapProcessor.saveModifiedTree method (~280 lines) — copies the original .sps verbatim, then replays pendingMutations as targeted SQL INSERT/UPDATE for Button, ElementReference, CommandSequence, ElementPlacement. Capability flag preservesAssetsOnSave flipped false → true.
Tests — the merged PR didn't include any, which dragged Snap coverage from ~58% → 54%, pulled global coverage below thresholds, and red-CI'd main.
This branch cherry-picks the implementation onto main, then layers two more changes on top:

test/snapProcessor.saveModifiedTree.test.ts — 6 cases: capabilities flag, zero-mutation round-trip preserving the full 23-table schema, addButton full row + per-layout placement invariant, updateButton, removeButton, WordList no-op.
ElementPlacement.GridSpan='1,1' set explicitly on every INSERT. Surfaced by the tests: Core_First_Scanning.sps declares the column with DEFAULT '1,1', but test/assets/snap/example.sps doesn't, so the implicit default crashes on stricter schemas.
CI locally: npm run lint ✓, npm run type-check ✓, npm run test:ci ✓ (87 suites, 756 tests, coverage above thresholds). Tested in TD Snap on Core First Scanning — both Topic: My Family and Google Home Speaker (the dashboard page that previously crashed) load and render correctly with the new buttons.

Closes the regression introduced by PR #45.

willwade and others added 2 commits May 1, 2026 10:03
Snap: implement saveModifiedTree (asset-preserving SQL replay)

- Copy original .sps verbatim then replay pendingMutations as targeted UPDATE/INSERT
- addButton inserts Button + ElementReference + CommandSequence + one
  ElementPlacement per PageLayout (Visible=1 at free cell, Visible=0
  out-of-bounds otherwise)
- capabilities.preservesAssetsOnSave: false → true
- load path uses _loadButton to keep pendingMutations clean
- Tested round-trip + addButton on Core First Scanning .sps;
  loads cleanly in TD Snap on dashboard and topic pages
The cherry-picked saveModifiedTree (parent commit) was untested. This
adds test/snapProcessor.saveModifiedTree.test.ts with 6 cases:

- capabilities flag is preservesAssetsOnSave: true
- zero-mutation round-trip is byte-identical (full 23-table schema preserved)
- addButton inserts a complete Button + ElementReference + CommandSequence
  + one ElementPlacement per existing PageLayout for the target page,
  with all the modal-non-NULL columns TD Snap requires
  (ContentType=6, CommandFlags=8, ForegroundColor / BackgroundColor set,
  ElementType=0, fresh GUID, MessageAction:0 in CommandSequence)
- updateButton patches Label/Message on the matching Button.Id
- removeButton flips Visible=0 on every placement
- WordList mutations are silent no-ops (capability: wordList=none)

Bug surfaced + fixed by the tests: ElementPlacement.GridSpan is NOT NULL,
and not every Snap schema has a default of '1,1' (Core_First_Scanning.sps
does, test/assets/snap/example.sps does not). All 5 ElementPlacement
INSERTs now specify GridSpan='1,1' explicitly.

Restores main CI: coverage thresholds were dropping below limit because
saveModifiedTree was added without tests in the merged PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@willwade willwade merged commit 4a290dc into main May 1, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant