Materialize the trash — store, undo, and the container universe
Phase 2 swaps every consumer: Liveness and its ancestor walk are gone, replaced by ItemContainer — a UUID set plus the container side it lives on, presence the whole test, one selection boundary instead of the old liveness law. Deletion stages by place: board cards move to the trash at a store-minted head rank, trash-side delete is permanent behind its confirmation, Delete Immediately skips the trash from anywhere, lane delete captures the subtree and removes the folder. Restore has no method at all — moveCards resolves members in either container, so drag-out and cut-paste are the ordinary moves 13 calls them, registering ordinary Move steps. The delete inverse moves the card back to its captured lane and rank; redo replays the captured trash rank, a value the gesture actually wrote; lane undo recreates the subtree byte-faithfully in session. Purges register nothing — where 13's trash section contradicts its own Rules on that, Rules wins, filed for ruling. Staleness collapsed to present-or-absent: a container is a path, so a foreign restore fails the delete step's expectation structurally. Legacy tombstones migrate on the loose-file tail hook, cards oldest-first so minting above top reproduces the retired newest-first column, lanes returning live, one folded loss row naming both directions. Put Back, restoreByDrag, receiveRestoredCards, TrashEntry, and the kind machinery are deleted; the trash column renders the container correctly with its full face rework left to phase 3. Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -109,7 +109,7 @@ struct StyleEditorSessionTests {
|
||||
let store = try BoardStore(rootURL: fixture.root)
|
||||
store.transient.beginStyleEditor(for: .items([card1, card2]))
|
||||
|
||||
try fixture.item("\(Ident.lane1)/\(Ident.card2)", tombstoned(order: "2048", title: "Second"))
|
||||
try fixture.move("\(Ident.lane1)/\(Ident.card2)", toTrash: Ident.card2)
|
||||
await reload(store)
|
||||
|
||||
let session = try #require(store.transient.styleEditor)
|
||||
@@ -126,7 +126,7 @@ struct StyleEditorSessionTests {
|
||||
let store = try BoardStore(rootURL: fixture.root)
|
||||
store.transient.beginStyleEditor(for: .items([card3]))
|
||||
|
||||
try fixture.item(Ident.lane2, tombstoned(order: "2048", title: "Doing"))
|
||||
try FileManager.default.removeItem(at: fixture.url(Ident.lane2))
|
||||
await reload(store)
|
||||
|
||||
// The card's own flag never changed — its lane's did. Effective liveness is ancestor-walked,
|
||||
@@ -141,7 +141,7 @@ struct StyleEditorSessionTests {
|
||||
let store = try BoardStore(rootURL: fixture.root)
|
||||
store.transient.beginStyleEditor(for: .items([card1]))
|
||||
|
||||
try fixture.item("\(Ident.lane1)/\(Ident.card1)", tombstoned(order: "1024", title: "First"))
|
||||
try fixture.move("\(Ident.lane1)/\(Ident.card1)", toTrash: Ident.card1)
|
||||
await reload(store)
|
||||
|
||||
#expect(store.transient.styleEditor?.target != .board)
|
||||
@@ -155,8 +155,8 @@ struct StyleEditorSessionTests {
|
||||
let store = try BoardStore(rootURL: fixture.root)
|
||||
store.transient.beginStyleEditor(for: .board)
|
||||
|
||||
try fixture.item(Ident.lane1, tombstoned(order: "1024", title: "Todo"))
|
||||
try fixture.item(Ident.lane2, tombstoned(order: "2048", title: "Doing"))
|
||||
try FileManager.default.removeItem(at: fixture.url(Ident.lane1))
|
||||
try FileManager.default.removeItem(at: fixture.url(Ident.lane2))
|
||||
await reload(store)
|
||||
|
||||
#expect(store.transient.styleEditor?.target == .board)
|
||||
|
||||
Reference in New Issue
Block a user