legion-data 1.1.5 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +16 -0
- data/.gitignore +10 -2
- data/.rubocop.yml +41 -18
- data/CHANGELOG.md +82 -15
- data/CLAUDE.md +199 -0
- data/Gemfile +11 -1
- data/LICENSE +201 -0
- data/README.md +163 -19
- data/exe/legionio_migrate +0 -0
- data/legion-data.gemspec +22 -35
- data/lib/legion/data/connection.rb +39 -25
- data/lib/legion/data/encryption/cipher.rb +49 -0
- data/lib/legion/data/encryption/key_provider.rb +45 -0
- data/lib/legion/data/encryption/sequel_plugin.rb +54 -0
- data/lib/legion/data/event_store/projection.rb +56 -0
- data/lib/legion/data/event_store.rb +112 -0
- data/lib/legion/data/local.rb +77 -0
- data/lib/legion/data/migration.rb +5 -3
- data/lib/legion/data/migrations/001_add_schema_columns.rb +9 -3
- data/lib/legion/data/migrations/002_add_nodes.rb +18 -0
- data/lib/legion/data/migrations/003_add_settings.rb +18 -0
- data/lib/legion/data/migrations/004_add_extensions.rb +23 -0
- data/lib/legion/data/migrations/005_add_runners.rb +21 -0
- data/lib/legion/data/migrations/006_add_functions.rb +21 -0
- data/lib/legion/data/migrations/{015_add_default_extensions.rb → 007_add_default_extensions.rb} +3 -0
- data/lib/legion/data/migrations/008_add_tasks.rb +23 -0
- data/lib/legion/data/migrations/009_add_digital_workers.rb +45 -0
- data/lib/legion/data/migrations/010_add_value_metrics.rb +19 -0
- data/lib/legion/data/migrations/011_add_extensions_registry.rb +30 -0
- data/lib/legion/data/migrations/012_add_apollo_tables.rb +66 -0
- data/lib/legion/data/migrations/013_add_relationships.rb +21 -0
- data/lib/legion/data/migrations/014_add_relationship_columns.rb +27 -0
- data/lib/legion/data/migrations/015_add_rbac_tables.rb +49 -0
- data/lib/legion/data/migrations/016_add_worker_health.rb +33 -0
- data/lib/legion/data/migrations/017_add_audit_log.rb +30 -0
- data/lib/legion/data/migrations/018_add_governance_events.rb +21 -0
- data/lib/legion/data/migrations/019_add_audit_hash_chain.rb +29 -0
- data/lib/legion/data/migrations/020_add_webhooks.rb +37 -0
- data/lib/legion/data/model.rb +5 -2
- data/lib/legion/data/models/apollo_access_log.rb +13 -0
- data/lib/legion/data/models/apollo_entry.rb +18 -0
- data/lib/legion/data/models/apollo_expertise.rb +12 -0
- data/lib/legion/data/models/apollo_relation.rb +14 -0
- data/lib/legion/data/models/audit_log.rb +34 -0
- data/lib/legion/data/models/digital_worker.rb +44 -0
- data/lib/legion/data/models/extension.rb +0 -0
- data/lib/legion/data/models/function.rb +0 -2
- data/lib/legion/data/models/node.rb +17 -3
- data/lib/legion/data/models/rbac_cross_team_grant.rb +33 -0
- data/lib/legion/data/models/rbac_role_assignment.rb +29 -0
- data/lib/legion/data/models/rbac_runner_grant.rb +21 -0
- data/lib/legion/data/models/relationship.rb +3 -6
- data/lib/legion/data/models/runner.rb +0 -0
- data/lib/legion/data/models/setting.rb +0 -0
- data/lib/legion/data/models/task.rb +0 -0
- data/lib/legion/data/models/task_log.rb +0 -0
- data/lib/legion/data/settings.rb +37 -8
- data/lib/legion/data/version.rb +3 -1
- data/lib/legion/data.rb +31 -13
- metadata +64 -139
- data/.circleci/config.yml +0 -174
- data/.rspec +0 -1
- data/Gemfile.lock +0 -85
- data/Rakefile +0 -55
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/bitbucket-pipelines.yml +0 -26
- data/lib/legion/data/migrations/002_add_users.rb +0 -17
- data/lib/legion/data/migrations/003_add_groups.rb +0 -16
- data/lib/legion/data/migrations/004_add_chains.rb +0 -25
- data/lib/legion/data/migrations/005_add_envs.rb +0 -24
- data/lib/legion/data/migrations/006_add_dcs.rb +0 -24
- data/lib/legion/data/migrations/007_add_nodes.rb +0 -26
- data/lib/legion/data/migrations/008_add_settings.rb +0 -18
- data/lib/legion/data/migrations/009_add_extensions.rb +0 -25
- data/lib/legion/data/migrations/010_add_runners.rb +0 -21
- data/lib/legion/data/migrations/011_add_functions.rb +0 -29
- data/lib/legion/data/migrations/012_add_tasks.rb +0 -28
- data/lib/legion/data/migrations/013_add_task_logs.rb +0 -23
- data/lib/legion/data/migrations/014_add_relationships.rb +0 -27
- data/lib/legion/data/migrations/016_change_task_args.rb +0 -7
- data/lib/legion/data/migrations/017_add_payload_task.rb +0 -7
- data/lib/legion/data/migrations/018_add_migration_column.rb +0 -7
- data/lib/legion/data/migrations/019_add_debug_to_relationships.rb +0 -7
- data/lib/legion/data/migrations/020_add_delay_debug_to_tasks.rb +0 -8
- data/lib/legion/data/models/chain.rb +0 -11
- data/lib/legion/data/models/datacenter.rb +0 -11
- data/lib/legion/data/models/environment.rb +0 -11
- data/lib/legion/data/models/group.rb +0 -10
- data/lib/legion/data/models/user.rb +0 -10
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'sequel'
|
|
4
|
+
require 'sequel/extensions/migration'
|
|
5
|
+
|
|
6
|
+
module Legion
|
|
7
|
+
module Data
|
|
8
|
+
module Local
|
|
9
|
+
class << self
|
|
10
|
+
attr_reader :connection, :db_path
|
|
11
|
+
|
|
12
|
+
def setup(database: nil, **)
|
|
13
|
+
return if @connected
|
|
14
|
+
|
|
15
|
+
db_file = database || local_settings[:database] || 'legionio_local.db'
|
|
16
|
+
@db_path = db_file
|
|
17
|
+
@connection = ::Sequel.sqlite(db_file)
|
|
18
|
+
@connected = true
|
|
19
|
+
run_migrations
|
|
20
|
+
Legion::Logging.info "Legion::Data::Local connected to #{db_file}" if defined?(Legion::Logging)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def shutdown
|
|
24
|
+
@connection&.disconnect
|
|
25
|
+
@connection = nil
|
|
26
|
+
@connected = false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def connected?
|
|
30
|
+
@connected == true
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def register_migrations(name:, path:)
|
|
34
|
+
@registered_migrations ||= {}
|
|
35
|
+
@registered_migrations[name] = path
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def registered_migrations
|
|
39
|
+
@registered_migrations || {}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def model(table_name)
|
|
43
|
+
raise 'Legion::Data::Local not connected' unless connected?
|
|
44
|
+
|
|
45
|
+
::Sequel::Model(connection[table_name])
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def reset!
|
|
49
|
+
@connection = nil
|
|
50
|
+
@connected = false
|
|
51
|
+
@db_path = nil
|
|
52
|
+
@registered_migrations = nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def run_migrations
|
|
58
|
+
return unless local_settings.dig(:migrations, :auto_migrate) != false
|
|
59
|
+
|
|
60
|
+
registered_migrations.each_value do |path|
|
|
61
|
+
next unless File.directory?(path)
|
|
62
|
+
|
|
63
|
+
::Sequel::TimestampMigrator.new(@connection, path).run
|
|
64
|
+
rescue StandardError => e
|
|
65
|
+
Legion::Logging.warn "Local migration failed for #{path}: #{e.message}" if defined?(Legion::Logging)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def local_settings
|
|
70
|
+
return {} unless defined?(Legion::Settings)
|
|
71
|
+
|
|
72
|
+
Legion::Settings[:data]&.dig(:local) || {}
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'sequel/extensions/migration'
|
|
2
4
|
|
|
3
5
|
module Legion
|
|
4
6
|
module Data
|
|
5
7
|
module Migration
|
|
6
8
|
class << self
|
|
7
|
-
def migrate(connection = Legion::Data.connection, path = "#{__dir__}/migrations", **
|
|
8
|
-
Legion::Settings[:data][:migrations][:version] = Sequel::Migrator.run(connection, path, **
|
|
9
|
-
Legion::Logging.info("Legion::Data::Migration ran successfully to version #{Legion::Settings[:data][:migrations][:version]}")
|
|
9
|
+
def migrate(connection = Legion::Data.connection, path = "#{__dir__}/migrations", **)
|
|
10
|
+
Legion::Settings[:data][:migrations][:version] = Sequel::Migrator.run(connection, path, **)
|
|
11
|
+
Legion::Logging.info("Legion::Data::Migration ran successfully to version #{Legion::Settings[:data][:migrations][:version]}")
|
|
10
12
|
Legion::Settings[:data][:migrations][:ran] = true
|
|
11
13
|
end
|
|
12
14
|
end
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'sequel/extensions/migration'
|
|
2
4
|
|
|
3
5
|
Sequel.migration do
|
|
4
6
|
up do
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
alter_table(:schema_info) do
|
|
8
|
+
# SQLite does not support non-constant defaults in ALTER TABLE ADD COLUMN,
|
|
9
|
+
# so we omit the default here and let the application set timestamps.
|
|
10
|
+
add_column :created_at, DateTime, null: true
|
|
11
|
+
add_column :updated_at, DateTime, null: true
|
|
12
|
+
add_column :catalog, String, size: 255, null: true
|
|
13
|
+
end
|
|
8
14
|
end
|
|
9
15
|
|
|
10
16
|
down do
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
create_table(:nodes) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
String :name, size: 128, null: false, default: '', unique: true
|
|
8
|
+
String :status, size: 255, null: false, default: 'unknown', index: true
|
|
9
|
+
TrueClass :active, null: false, default: true, index: true
|
|
10
|
+
DateTime :created, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
11
|
+
DateTime :updated, null: true
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
down do
|
|
16
|
+
drop_table :nodes
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
create_table(:settings) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
String :key, size: 128, null: false, unique: true
|
|
8
|
+
String :value, size: 256, null: false
|
|
9
|
+
TrueClass :encrypted, null: false, default: false
|
|
10
|
+
DateTime :created, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
11
|
+
DateTime :updated, null: true
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
down do
|
|
16
|
+
drop_table :settings
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
create_table(:extensions) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
TrueClass :active, null: false, default: true, index: true
|
|
8
|
+
String :name, size: 128, null: false, index: true
|
|
9
|
+
String :namespace, size: 128, null: false, default: '', index: true
|
|
10
|
+
String :exchange, size: 255, null: true
|
|
11
|
+
String :uri, size: 256, null: true
|
|
12
|
+
Integer :schema_version, null: false, default: 0, index: true
|
|
13
|
+
DateTime :updated, null: true
|
|
14
|
+
DateTime :created, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
15
|
+
|
|
16
|
+
unique %i[name namespace]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
down do
|
|
21
|
+
drop_table :extensions
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
create_table(:runners) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
foreign_key :extension_id, :extensions, null: false, on_delete: :cascade, on_update: :cascade
|
|
8
|
+
String :name, size: 256, null: false, default: ''
|
|
9
|
+
String :namespace, size: 256, null: false, default: ''
|
|
10
|
+
TrueClass :active, null: false, default: true
|
|
11
|
+
String :queue, size: 256, null: true
|
|
12
|
+
String :uri, size: 256, null: true
|
|
13
|
+
DateTime :created, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
14
|
+
DateTime :updated, null: true
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
down do
|
|
19
|
+
drop_table :runners
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
create_table(:functions) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
String :name, size: 128, null: false, index: true
|
|
8
|
+
TrueClass :active, null: false, default: true, index: true
|
|
9
|
+
foreign_key :runner_id, :runners, null: false, on_delete: :cascade, on_update: :cascade, index: true
|
|
10
|
+
String :args, text: true, null: true
|
|
11
|
+
DateTime :created, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
12
|
+
DateTime :updated, null: true
|
|
13
|
+
|
|
14
|
+
unique %i[runner_id name]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
down do
|
|
19
|
+
drop_table :functions
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/legion/data/migrations/{015_add_default_extensions.rb → 007_add_default_extensions.rb}
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
Sequel.migration do
|
|
2
4
|
up do
|
|
3
5
|
lex = from(:extensions).insert(namespace: 'Legion::Extensions::Lex', name: 'lex', exchange: 'lex', uri: 'lex')
|
|
@@ -17,6 +19,7 @@ Sequel.migration do
|
|
|
17
19
|
from(:runners).insert row
|
|
18
20
|
end
|
|
19
21
|
end
|
|
22
|
+
|
|
20
23
|
down do
|
|
21
24
|
from(:extensions).where(namespace: 'Legion::Extensions::Lex').delete
|
|
22
25
|
from(:extensions).where(namespace: 'Legion::Extensions::Node').delete
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
create_table(:tasks) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
Integer :relationship_id, null: true
|
|
8
|
+
foreign_key :function_id, :functions, null: true
|
|
9
|
+
String :status, size: 255, null: false, index: true
|
|
10
|
+
foreign_key :parent_id, :tasks, null: true, on_delete: :set_null, on_update: :cascade, index: true
|
|
11
|
+
foreign_key :master_id, :tasks, null: true, on_delete: :set_null, on_update: :cascade, index: true
|
|
12
|
+
String :function_args, text: true, null: true
|
|
13
|
+
String :results, text: true, null: true
|
|
14
|
+
String :payload, text: true, null: true
|
|
15
|
+
DateTime :created, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
16
|
+
DateTime :updated, null: true
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
down do
|
|
21
|
+
drop_table :tasks
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
create_table(:digital_workers) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
String :worker_id, null: false, unique: true, size: 36
|
|
8
|
+
String :name, null: false, size: 255
|
|
9
|
+
String :entra_app_id, null: false, unique: true, size: 255
|
|
10
|
+
String :entra_object_id, null: true, size: 255
|
|
11
|
+
String :owner_msid, null: false, size: 255
|
|
12
|
+
String :owner_name, null: true, size: 255
|
|
13
|
+
String :extension_name, null: false, size: 255
|
|
14
|
+
String :business_role, null: true, size: 255
|
|
15
|
+
String :risk_tier, null: true, size: 50
|
|
16
|
+
String :lifecycle_state, null: false, default: 'bootstrap', size: 50
|
|
17
|
+
String :consent_tier, null: false, default: 'supervised', size: 50
|
|
18
|
+
Float :trust_score, null: false, default: 0.0
|
|
19
|
+
String :team, null: true, size: 255
|
|
20
|
+
String :manager_msid, null: true, size: 255
|
|
21
|
+
DateTime :created_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
22
|
+
DateTime :updated_at, null: true
|
|
23
|
+
DateTime :retired_at, null: true
|
|
24
|
+
String :retired_by, null: true, size: 255
|
|
25
|
+
String :retired_reason, null: true, text: true
|
|
26
|
+
index :owner_msid
|
|
27
|
+
index :lifecycle_state
|
|
28
|
+
index :team
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
alter_table(:tasks) do
|
|
32
|
+
add_column :worker_id, String, null: true, size: 36
|
|
33
|
+
add_index :worker_id
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
down do
|
|
38
|
+
alter_table(:tasks) do
|
|
39
|
+
drop_index :worker_id
|
|
40
|
+
drop_column :worker_id
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
drop_table :digital_workers
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
create_table(:value_metrics) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
String :worker_id, null: false, size: 36, index: true
|
|
8
|
+
String :metric_name, null: false, size: 255, index: true
|
|
9
|
+
String :metric_type, null: false, size: 50
|
|
10
|
+
Float :value, null: false, default: 0.0
|
|
11
|
+
String :metadata, text: true, null: true
|
|
12
|
+
DateTime :recorded_at, null: false, default: Sequel::CURRENT_TIMESTAMP, index: true
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
down do
|
|
17
|
+
drop_table :value_metrics
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
change do
|
|
5
|
+
create_table(:extensions_registry) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
String :name, null: false, unique: true, size: 100
|
|
8
|
+
String :module_name, null: false, size: 100
|
|
9
|
+
String :category, null: false, size: 50, default: 'cognition'
|
|
10
|
+
String :description, text: true
|
|
11
|
+
String :cognitive_concept, text: true
|
|
12
|
+
String :metaphor_description, text: true
|
|
13
|
+
Integer :build_batch
|
|
14
|
+
DateTime :build_date
|
|
15
|
+
String :status, null: false, size: 20, default: 'active'
|
|
16
|
+
Integer :spec_count, default: 0
|
|
17
|
+
Integer :spec_pass_count, default: 0
|
|
18
|
+
String :wired_phase, size: 100
|
|
19
|
+
Float :health_score, default: 1.0
|
|
20
|
+
Integer :invocation_count, default: 0
|
|
21
|
+
DateTime :last_invoked_at
|
|
22
|
+
DateTime :created_at
|
|
23
|
+
DateTime :updated_at
|
|
24
|
+
|
|
25
|
+
index :category
|
|
26
|
+
index :status
|
|
27
|
+
index :health_score
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
next unless adapter_scheme == :postgres
|
|
6
|
+
|
|
7
|
+
run 'CREATE EXTENSION IF NOT EXISTS vector'
|
|
8
|
+
run 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp"'
|
|
9
|
+
|
|
10
|
+
create_table(:apollo_entries) do
|
|
11
|
+
column :id, :uuid, default: Sequel.lit('uuid_generate_v4()'), primary_key: true
|
|
12
|
+
String :content, text: true, null: false
|
|
13
|
+
String :content_type, null: false, size: 50
|
|
14
|
+
Float :confidence, default: 0.5
|
|
15
|
+
String :source_agent, null: false, size: 100
|
|
16
|
+
column :source_context, :jsonb, default: Sequel.lit("'{}'::jsonb")
|
|
17
|
+
column :tags, :'text[]', default: Sequel.lit("'{}'::text[]")
|
|
18
|
+
String :status, null: false, size: 20, default: 'candidate'
|
|
19
|
+
Integer :access_count, default: 0
|
|
20
|
+
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
|
|
21
|
+
DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP
|
|
22
|
+
DateTime :confirmed_at
|
|
23
|
+
|
|
24
|
+
index :status
|
|
25
|
+
end
|
|
26
|
+
run 'ALTER TABLE apollo_entries ADD COLUMN embedding vector(1536)'
|
|
27
|
+
run 'CREATE INDEX idx_apollo_entries_embedding ON apollo_entries USING hnsw (embedding vector_cosine_ops)'
|
|
28
|
+
run 'CREATE INDEX idx_apollo_entries_tags ON apollo_entries USING gin (tags)'
|
|
29
|
+
|
|
30
|
+
create_table(:apollo_relations) do
|
|
31
|
+
column :id, :uuid, default: Sequel.lit('uuid_generate_v4()'), primary_key: true
|
|
32
|
+
foreign_key :from_entry_id, :apollo_entries, type: :uuid, null: false, index: true
|
|
33
|
+
foreign_key :to_entry_id, :apollo_entries, type: :uuid, null: false, index: true
|
|
34
|
+
String :relation_type, null: false, size: 50
|
|
35
|
+
Float :weight, default: 1.0
|
|
36
|
+
String :source_agent, size: 100
|
|
37
|
+
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
create_table(:apollo_expertise) do
|
|
41
|
+
column :id, :uuid, default: Sequel.lit('uuid_generate_v4()'), primary_key: true
|
|
42
|
+
String :agent_id, null: false, size: 100, index: true
|
|
43
|
+
String :domain, null: false, size: 100, index: true
|
|
44
|
+
Float :proficiency, default: 0.0
|
|
45
|
+
Integer :entry_count, default: 0
|
|
46
|
+
DateTime :last_active_at, default: Sequel::CURRENT_TIMESTAMP
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
create_table(:apollo_access_log) do
|
|
50
|
+
column :id, :uuid, default: Sequel.lit('uuid_generate_v4()'), primary_key: true
|
|
51
|
+
foreign_key :entry_id, :apollo_entries, type: :uuid, index: true
|
|
52
|
+
String :agent_id, null: false, size: 100
|
|
53
|
+
String :action, null: false, size: 20
|
|
54
|
+
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
down do
|
|
59
|
+
next unless adapter_scheme == :postgres
|
|
60
|
+
|
|
61
|
+
drop_table(:apollo_access_log) if table_exists?(:apollo_access_log)
|
|
62
|
+
drop_table(:apollo_expertise) if table_exists?(:apollo_expertise)
|
|
63
|
+
drop_table(:apollo_relations) if table_exists?(:apollo_relations)
|
|
64
|
+
drop_table(:apollo_entries) if table_exists?(:apollo_entries)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
create_table(:relationships) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
foreign_key :trigger_id, :functions, null: true, on_delete: :set_null, index: true
|
|
8
|
+
foreign_key :action_id, :functions, null: true, on_delete: :set_null, index: true
|
|
9
|
+
String :name, size: 255, null: true
|
|
10
|
+
String :status, size: 50, null: false, default: 'active', index: true
|
|
11
|
+
String :relationship_type, size: 50, null: false, default: 'chain'
|
|
12
|
+
String :options, text: true, null: true
|
|
13
|
+
DateTime :created, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
14
|
+
DateTime :updated, null: true
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
down do
|
|
19
|
+
drop_table :relationships
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
alter_table(:relationships) do
|
|
6
|
+
add_column :delay, Integer, null: false, default: 0
|
|
7
|
+
add_column :chain_id, Integer, null: true, index: true
|
|
8
|
+
add_column :debug, TrueClass, null: false, default: false
|
|
9
|
+
add_column :allow_new_chains, TrueClass, null: false, default: false
|
|
10
|
+
add_column :conditions, String, text: true, null: true
|
|
11
|
+
add_column :transformation, String, text: true, null: true
|
|
12
|
+
add_column :active, TrueClass, null: false, default: true, index: true
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
down do
|
|
17
|
+
alter_table(:relationships) do
|
|
18
|
+
drop_column :delay
|
|
19
|
+
drop_column :chain_id
|
|
20
|
+
drop_column :debug
|
|
21
|
+
drop_column :allow_new_chains
|
|
22
|
+
drop_column :conditions
|
|
23
|
+
drop_column :transformation
|
|
24
|
+
drop_column :active
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
create_table(:rbac_role_assignments) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
String :principal_type, null: false, size: 10
|
|
8
|
+
String :principal_id, null: false, size: 255
|
|
9
|
+
String :role, null: false, size: 100
|
|
10
|
+
String :team, null: true, size: 255
|
|
11
|
+
String :granted_by, null: false, size: 255
|
|
12
|
+
DateTime :granted_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
13
|
+
DateTime :expires_at, null: true
|
|
14
|
+
unique %i[principal_type principal_id role team]
|
|
15
|
+
index :principal_id
|
|
16
|
+
index :team
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
create_table(:rbac_runner_grants) do
|
|
20
|
+
primary_key :id
|
|
21
|
+
String :team, null: false, size: 255
|
|
22
|
+
String :runner_pattern, null: false, size: 500
|
|
23
|
+
String :actions, null: false, size: 255
|
|
24
|
+
String :granted_by, null: false, size: 255
|
|
25
|
+
DateTime :granted_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
26
|
+
unique %i[team runner_pattern]
|
|
27
|
+
index :team
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
create_table(:rbac_cross_team_grants) do
|
|
31
|
+
primary_key :id
|
|
32
|
+
String :source_team, null: false, size: 255
|
|
33
|
+
String :target_team, null: false, size: 255
|
|
34
|
+
String :runner_pattern, null: false, size: 500
|
|
35
|
+
String :actions, null: false, size: 255
|
|
36
|
+
String :granted_by, null: false, size: 255
|
|
37
|
+
DateTime :granted_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
38
|
+
DateTime :expires_at, null: true
|
|
39
|
+
unique %i[source_team target_team runner_pattern]
|
|
40
|
+
index :source_team
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
down do
|
|
45
|
+
drop_table :rbac_cross_team_grants
|
|
46
|
+
drop_table :rbac_runner_grants
|
|
47
|
+
drop_table :rbac_role_assignments
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
alter_table(:digital_workers) do
|
|
6
|
+
add_column :health_status, String, size: 20, default: 'unknown', null: false
|
|
7
|
+
add_column :last_heartbeat_at, DateTime, null: true
|
|
8
|
+
add_column :health_node, String, size: 255, null: true
|
|
9
|
+
add_index :health_status
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
alter_table(:nodes) do
|
|
13
|
+
add_column :metrics, :text, null: true
|
|
14
|
+
add_column :hosted_worker_ids, :text, null: true
|
|
15
|
+
add_column :version, String, size: 50, null: true
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
down do
|
|
20
|
+
alter_table(:digital_workers) do
|
|
21
|
+
drop_index :health_status
|
|
22
|
+
drop_column :health_node
|
|
23
|
+
drop_column :last_heartbeat_at
|
|
24
|
+
drop_column :health_status
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
alter_table(:nodes) do
|
|
28
|
+
drop_column :version
|
|
29
|
+
drop_column :hosted_worker_ids
|
|
30
|
+
drop_column :metrics
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
create_table(:audit_log) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
String :event_type, null: false, size: 50
|
|
8
|
+
String :principal_id, null: false, size: 255
|
|
9
|
+
String :principal_type, null: false, size: 20
|
|
10
|
+
String :action, null: false, size: 100
|
|
11
|
+
String :resource, null: false, size: 500
|
|
12
|
+
String :source, null: false, size: 20
|
|
13
|
+
String :node, null: false, size: 255
|
|
14
|
+
String :status, null: false, size: 20
|
|
15
|
+
Integer :duration_ms, null: true
|
|
16
|
+
column :detail, :text, null: true
|
|
17
|
+
String :record_hash, null: false, size: 64
|
|
18
|
+
String :prev_hash, null: false, size: 64
|
|
19
|
+
DateTime :created_at, null: false
|
|
20
|
+
|
|
21
|
+
index :event_type
|
|
22
|
+
index :principal_id
|
|
23
|
+
index :created_at
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
down do
|
|
28
|
+
drop_table :audit_log
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
change do
|
|
5
|
+
create_table(:governance_events) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
String :stream_id, null: false
|
|
8
|
+
String :event_type, null: false
|
|
9
|
+
Integer :sequence_number, null: false
|
|
10
|
+
column :data_json, :text
|
|
11
|
+
column :metadata_json, :text
|
|
12
|
+
String :event_hash, size: 64
|
|
13
|
+
String :previous_hash, size: 64
|
|
14
|
+
DateTime :created_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
15
|
+
|
|
16
|
+
index %i[stream_id sequence_number], unique: true
|
|
17
|
+
index :event_type
|
|
18
|
+
index :created_at
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
return unless table_exists?(:audit_log)
|
|
6
|
+
|
|
7
|
+
cols = schema(:audit_log).map(&:first)
|
|
8
|
+
|
|
9
|
+
alter_table(:audit_log) do
|
|
10
|
+
add_column :record_hash, String, size: 64 unless cols.include?(:record_hash)
|
|
11
|
+
add_column :previous_hash, String, size: 64 unless cols.include?(:previous_hash)
|
|
12
|
+
add_column :retention_tier, String, size: 10, default: 'hot' unless cols.include?(:retention_tier)
|
|
13
|
+
add_index :record_hash, unique: true, if_not_exists: true
|
|
14
|
+
add_index :retention_tier, if_not_exists: true
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
down do
|
|
19
|
+
return unless table_exists?(:audit_log)
|
|
20
|
+
|
|
21
|
+
cols = schema(:audit_log).map(&:first)
|
|
22
|
+
|
|
23
|
+
alter_table(:audit_log) do
|
|
24
|
+
drop_column :record_hash if cols.include?(:record_hash)
|
|
25
|
+
drop_column :previous_hash if cols.include?(:previous_hash)
|
|
26
|
+
drop_column :retention_tier if cols.include?(:retention_tier)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|