summaryrefslogtreecommitdiff
path: root/app/models/node.rb
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-07-16 02:40:03 +0200
committererdgeist <erdgeist@erdgeist.org>2026-07-16 02:40:03 +0200
commitc0c9250141c2fa64fed967b8b9ad9bada3694c3d (patch)
tree8a36020521dafc0d259d5d78461c59a4635b6ba4 /app/models/node.rb
parentfb7b8233f1bbf7acb88d48f96e6f81cefe168d1c (diff)
Record the full lifecycle contract in NodeAction entries
A contract comment above NodeAction.record! now specifies every verb's metadata shape. NodeAction.head_diff computes the publish diff between an outgoing head and its replacement -- default-locale title pair always, author/tags pairs and template/assets/abstract/ body flags only when changed, and a per-locale translation_diff with added/removed/changed status. It is a pure function of its two pages, shared by publish, rollback, and the future backfill, and reads translation rows directly so fallbacks never masquerade as content. publish entries carry via ("draft" or "revision"); restore_revision! is now transactional, takes the acting user, and logs through the same diff. Staged slug/parent changes applied at publish log a move entry with the path pair. Node creation logs a create entry with initial title and path. The draft-scoped translation_destroy writer is retired -- locale removal is recorded by the publish diff, where it becomes public fact.
Diffstat (limited to 'app/models/node.rb')
-rw-r--r--app/models/node.rb29
1 files changed, 21 insertions, 8 deletions
diff --git a/app/models/node.rb b/app/models/node.rb
index b41df06..6ca607d 100644
--- a/app/models/node.rb
+++ b/app/models/node.rb
@@ -194,17 +194,19 @@ class Node < ApplicationRecord
194 # Return nil if nothing to publish and no staged changes 194 # Return nil if nothing to publish and no staged changes
195 return nil unless self.draft || staged_slug || staged_parent_id 195 return nil unless self.draft || staged_slug || staged_parent_id
196 196
197 path_before = self.unique_name
198
197 ActiveRecord::Base.transaction do 199 ActiveRecord::Base.transaction do
198 if self.draft 200 if self.draft
199 previous_title = self.head ? Globalize.with_locale(I18n.default_locale) { self.head.title } : nil 201 outgoing_head = self.head
200 self.head = self.draft 202 self.head = self.draft
201 self.head.published_at ||= Time.now 203 self.head.published_at ||= Time.now
202 self.head.save! 204 self.head.save!
203 self.draft = nil 205 self.draft = nil
204 206
205 new_title = Globalize.with_locale(I18n.default_locale) { self.head.title }
206 NodeAction.record!(:node => self, :page => self.head, :user => current_user, 207 NodeAction.record!(:node => self, :page => self.head, :user => current_user,
207 :action => "publish", :from => previous_title, :to => new_title) 208 :action => "publish", :via => "draft",
209 **NodeAction.head_diff(outgoing_head, self.head))
208 end 210 end
209 211
210 if staged_slug && (staged_slug != slug) 212 if staged_slug && (staged_slug != slug)
@@ -231,17 +233,28 @@ class Node < ApplicationRecord
231 self.reload 233 self.reload
232 self.update_unique_name 234 self.update_unique_name
233 self.send(:update_unique_names_of_children) 235 self.send(:update_unique_names_of_children)
236 if self.unique_name != path_before
237 NodeAction.record!(:node => self, :user => current_user, :action => "move",
238 :path => { "from" => path_before, "to" => self.unique_name })
239 end
234 self.unlock! 240 self.unlock!
235 self 241 self
236 end 242 end
237 end 243 end
238 244
239 def restore_revision! revision 245 def restore_revision! revision, current_user = nil
240 if page = self.pages.find_by_revision(revision) 246 page = self.pages.find_by_revision(revision)
247 return nil unless page
248
249 ActiveRecord::Base.transaction do
250 outgoing_head = self.head
241 self.head = page 251 self.head = page
242 self.save 252 self.save!
243 else 253
244 nil 254 NodeAction.record!(:node => self, :page => page, :user => current_user,
255 :action => "publish", :via => "revision",
256 **NodeAction.head_diff(outgoing_head, page))
257 self
245 end 258 end
246 end 259 end
247 260