Module: LcpRuby::Metadata::PermissionMerger
- Defined in:
- lib/lcp_ruby/metadata/permission_merger.rb
Overview
Coverage-merges a per-model PermissionDefinition with the ‘_default` entry. Whole-entry replacement at the keyed level — see docs/design/permissions_default_role_coverage.md.
Class Method Summary collapse
- .merge(default:, per_model:) ⇒ Object
-
.merge_default_role(default, per_model) ⇒ Object
default_role sentinel: PermissionDefinition#initialize defaults to “viewer”, so the constructed attribute can’t distinguish “author wrote nothing” from “author wrote viewer”.
-
.merge_keyed(default_block, per_model_block) ⇒ Object
Whole-entry replacement keyed by name.
-
.merge_record_rules(default, per_model) ⇒ Object
record_rules: per-model rules first (preserves authoring order; per- model rules thus evaluate first).
Class Method Details
.merge(default:, per_model:) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/lcp_ruby/metadata/permission_merger.rb', line 7 def self.merge(default:, per_model:) roles, role_sources = merge_keyed(default.roles, per_model.roles) overrides, override_sources = merge_keyed(default.field_overrides, per_model.field_overrides) rules, rule_sources = merge_record_rules(default, per_model) default_role, default_role_source = merge_default_role(default, per_model) inherits_from = per_model.inherits_from PermissionDefinition.new( model: per_model.model, roles: roles, default_role: default_role, field_overrides: overrides, record_rules: rules, inherits_from: per_model.raw_hash&.[]("inherits_from"), source_path: per_model.source_path, source_type: per_model.source_type, source_map: { roles: role_sources, field_overrides: override_sources, record_rules: rule_sources, default_role: default_role_source, inherits_from: inherits_from ? :per_model : nil } ) end |
.merge_default_role(default, per_model) ⇒ Object
default_role sentinel: PermissionDefinition#initialize defaults to “viewer”, so the constructed attribute can’t distinguish “author wrote nothing” from “author wrote viewer”. raw_hash key presence disambiguates.
73 74 75 76 77 78 |
# File 'lib/lcp_ruby/metadata/permission_merger.rb', line 73 def self.merge_default_role(default, per_model) return [ per_model.default_role, :per_model ] if per_model.raw_hash&.key?("default_role") return [ default.default_role, :default ] if default.raw_hash&.key?("default_role") [ per_model.default_role, :default ] end |
.merge_keyed(default_block, per_model_block) ⇒ Object
Whole-entry replacement keyed by name. Per-model wins on collision; entries only in default are copied. Used for both ‘roles` and `field_overrides` — same shape, only the dictionary differs.
37 38 39 40 41 42 43 |
# File 'lib/lcp_ruby/metadata/permission_merger.rb', line 37 def self.merge_keyed(default_block, per_model_block) merged = {} sources = {} default_block.each { |k, v| merged[k] = v; sources[k] = :default } per_model_block.each { |k, v| merged[k] = v; sources[k] = :per_model } [ merged, sources ] end |
.merge_record_rules(default, per_model) ⇒ Object
record_rules: per-model rules first (preserves authoring order; per- model rules thus evaluate first). Then append default rules whose ‘name:` is not already used by a per-model rule, in default’s original order.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/lcp_ruby/metadata/permission_merger.rb', line 49 def self.merge_record_rules(default, per_model) merged = [] sources = {} per_model.record_rules.each do |rule| merged << rule name = PermissionDefinition.rule_name(rule) sources[name] = :per_model if name end default.record_rules.each do |rule| name = PermissionDefinition.rule_name(rule) next if name && sources.key?(name) merged << rule sources[name] = :default if name end [ merged, sources ] end |