class MaterialVersionRecorder < VersionRecorder EVENT_TYPES = ['create', 'update', 'discard', 'restore', 'suppress'].freeze def self.record! material:, event_type:, created_by_user:, file_snapshot: nil new(material:, event_type:, created_by_user:, file_snapshot:).record! end def initialize material:, event_type:, created_by_user:, file_snapshot: nil @file_snapshot = file_snapshot super(record: material, event_type:, created_by_user:) end def self.ensure_snapshot! material, created_by_user: return if material.material_versions.exists? record!(material:, event_type: :create, created_by_user: material.created_by_user || created_by_user) end private def version_class = MaterialVersion def version_association = :material_versions def record_key = :material def snapshot_attributes blob = @record.file.attached? ? @record.file.blob : nil file_snapshot = build_file_snapshot(blob) { url: @record.url, parent: @record.parent, tag: @record.tag, tag_name: @record.tag&.name, tag_category: @record.tag&.category, export_paths_json: @record.snapshot_export_paths, discarded_at: @record.discarded_at, file_blob_id: file_snapshot[:file_blob_id], file_filename: file_snapshot[:file_filename], file_content_type: file_snapshot[:file_content_type], file_byte_size: file_snapshot[:file_byte_size], file_checksum: file_snapshot[:file_checksum], file_sha256: file_snapshot[:file_sha256], file_suppressed_at: @record.file_suppressed_at, file_suppression_reason: @record.file_suppression_reason } end def build_file_snapshot blob return @file_snapshot if @file_snapshot return empty_file_snapshot unless blob blob.metadata['sha256'] ||= MaterialFileSha256.from_blob(blob) blob.save! if blob.changed? { file_blob_id: blob.id, file_filename: blob.filename.to_s, file_content_type: blob.content_type, file_byte_size: blob.byte_size, file_checksum: blob.checksum, file_sha256: blob.metadata['sha256'] } end def empty_file_snapshot { file_blob_id: nil, file_filename: nil, file_content_type: nil, file_byte_size: nil, file_checksum: nil, file_sha256: nil } end def event_types = self.class::EVENT_TYPES end