Class: DecisionAgent::Dmn::DmnVersionManager

Inherits:
Object
  • Object
show all
Defined in:
lib/decision_agent/dmn/versioning.rb

Overview

DMN Versioning Support Integrates DMN models with the DecisionAgent versioning system

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(version_manager: nil) ⇒ DmnVersionManager

Returns a new instance of DmnVersionManager.



14
15
16
# File 'lib/decision_agent/dmn/versioning.rb', line 14

def initialize(version_manager: nil)
  @version_manager = version_manager || Versioning::VersionManager.new
end

Instance Attribute Details

#version_managerObject (readonly)

Returns the value of attribute version_manager.



12
13
14
# File 'lib/decision_agent/dmn/versioning.rb', line 12

def version_manager
  @version_manager
end

Instance Method Details

#compare_dmn_versions(version_id_1:, version_id_2:) ⇒ Object

Compare two DMN versions



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/decision_agent/dmn/versioning.rb', line 111

def compare_dmn_versions(version_id_1:, version_id_2:)
  comparison = @version_manager.compare(
    version_id_1: version_id_1,
    version_id_2: version_id_2
  )

  return nil unless comparison

  # Parse both versions
  parser = Parser.new

  model_1 = if comparison[:version_1][:content].is_a?(Hash) && comparison[:version_1][:content][:format] == "dmn"
              parser.parse(comparison[:version_1][:content][:xml])
            end

  model_2 = if comparison[:version_2][:content].is_a?(Hash) && comparison[:version_2][:content][:format] == "dmn"
              parser.parse(comparison[:version_2][:content][:xml])
            end

  # Compare DMN models
  diff = compare_models(model_1, model_2)

  comparison.merge(
    model_diff: diff,
    model_1: model_1 ? { id: model_1.id, name: model_1.name, decisions: model_1.decisions.size } : nil,
    model_2: model_2 ? { id: model_2.id, name: model_2.name, decisions: model_2.decisions.size } : nil
  )
end

#delete_dmn_tag(model_id:, name:) ⇒ Boolean

Delete a tag by name.

Parameters:

  • model_id (String)

    The model identifier

  • name (String)

    The tag name

Returns:

  • (Boolean)

    True if deleted, false if the tag did not exist



174
175
176
# File 'lib/decision_agent/dmn/versioning.rb', line 174

def delete_dmn_tag(model_id:, name:)
  @version_manager.delete_tag(model_id: model_id, name: name)
end

#delete_dmn_version(version_id:) ⇒ Object

Delete a DMN version



141
142
143
# File 'lib/decision_agent/dmn/versioning.rb', line 141

def delete_dmn_version(version_id:)
  @version_manager.delete_version(version_id: version_id)
end

#get_active_dmn_version(model_id:) ⇒ Object

Get active DMN version for a model



179
180
181
182
183
184
185
# File 'lib/decision_agent/dmn/versioning.rb', line 179

def get_active_dmn_version(model_id:)
  versions = @version_manager.get_versions(rule_id: model_id, limit: 1)
  return nil if versions.empty?

  active_version = versions.find { |v| v[:is_active] } || versions.first
  get_dmn_version(version_id: active_version[:version_id])
end

#get_dmn_history(model_id:) ⇒ Object

Get DMN version history with full details



81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/decision_agent/dmn/versioning.rb', line 81

def get_dmn_history(model_id:)
  history = @version_manager.get_history(rule_id: model_id)

  history.map do |entry|
    if entry[:content].is_a?(Hash) && entry[:content][:format] == "dmn"
      entry.merge(
        model_name: entry[:content][:name],
        model_namespace: entry[:content][:namespace]
      )
    else
      entry
    end
  end
end

#get_dmn_tag(model_id:, name:) ⇒ Hash?

Resolve a tag to its tag hash for the given model.

Parameters:

  • model_id (String)

    The model identifier

  • name (String)

    The tag name

Returns:

  • (Hash, nil)

    Tag hash or nil if not found



159
160
161
# File 'lib/decision_agent/dmn/versioning.rb', line 159

def get_dmn_tag(model_id:, name:)
  @version_manager.get_tag(model_id: model_id, name: name)
end

#get_dmn_version(version_id:) ⇒ Object

Get a specific DMN version



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/decision_agent/dmn/versioning.rb', line 45

def get_dmn_version(version_id:)
  version = @version_manager.get_version(version_id: version_id)
  return nil unless version

  # Parse DMN from version content
  return unless version[:content].is_a?(Hash) && version[:content][:format] == "dmn"

  parser = Parser.new
  model = parser.parse(version[:content][:xml])

  {
    version_id: version[:version_id],
    model: model,
    created_at: version[:created_at],
    created_by: version[:created_by],
    changelog: version[:changelog],
    is_active: version[:is_active]
  }
end

#get_dmn_versions(model_id:, limit: nil) ⇒ Object

Get all versions of a DMN model



66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/decision_agent/dmn/versioning.rb', line 66

def get_dmn_versions(model_id:, limit: nil)
  versions = @version_manager.get_versions(rule_id: model_id, limit: limit)

  versions.map do |version|
    {
      version_id: version[:version_id],
      created_at: version[:created_at],
      created_by: version[:created_by],
      changelog: version[:changelog],
      is_active: version[:is_active]
    }
  end
end

#list_dmn_tags(model_id:) ⇒ Array<Hash>

List all tags for a DMN model.

Parameters:

  • model_id (String)

    The model identifier

Returns:

  • (Array<Hash>)

    Tag hashes sorted by name



166
167
168
# File 'lib/decision_agent/dmn/versioning.rb', line 166

def list_dmn_tags(model_id:)
  @version_manager.list_tags(model_id: model_id)
end

#rollback_dmn(version_id:, performed_by: "system") ⇒ Object

Rollback to a previous DMN version



97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/decision_agent/dmn/versioning.rb', line 97

def rollback_dmn(version_id:, performed_by: "system")
  version = @version_manager.rollback(
    version_id: version_id,
    performed_by: performed_by
  )

  # Parse and return the model
  return unless version[:content].is_a?(Hash) && version[:content][:format] == "dmn"

  parser = Parser.new
  parser.parse(version[:content][:xml])
end

#save_dmn_version(model:, created_by: "system", changelog: nil, tag: nil) ⇒ Hash

Save a DMN model as a new version

Parameters:

  • model (Object)

    The DMN model to save

  • created_by (String) (defaults to: "system")

    Who is saving this version

  • changelog (String, nil) (defaults to: nil)

    Human-readable description of what changed

  • tag (String, nil) (defaults to: nil)

    Optional tag name to apply to the new version at creation time

Returns:

  • (Hash)

    The created version



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/decision_agent/dmn/versioning.rb', line 24

def save_dmn_version(model:, created_by: "system", changelog: nil, tag: nil)
  # Serialize the in-memory DMN model to XML (no DB lookup needed)
  exporter = Exporter.new
  xml_content = exporter.serialize_model(model)

  # Save as version (with optional tag applied atomically)
  @version_manager.save_version(
    rule_id: model.id,
    rule_content: {
      format: "dmn",
      xml: xml_content,
      name: model.name,
      namespace: model.namespace
    },
    created_by: created_by,
    changelog: changelog || "DMN model updated",
    tag: tag
  )
end

#tag_dmn!(model_id:, version_id:, name:) ⇒ Hash

Tag a specific DMN version after the fact. Creates the tag if it does not exist; re-points it if the name is already in use.

Parameters:

  • model_id (String)

    The model identifier

  • version_id (String)

    The version to tag

  • name (String)

    The tag name (e.g. "release-candidate")

Returns:

  • (Hash)

    The tag ({ name:, version_id:, created_at: })



151
152
153
# File 'lib/decision_agent/dmn/versioning.rb', line 151

def tag_dmn!(model_id:, version_id:, name:)
  @version_manager.tag!(model_id, version_id, name)
end