approval_cycle 0.1.0.pre → 0.1.1.pre

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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +35 -15
  3. data/app/models/approval_cycle/setup.rb +6 -3
  4. data/app/models/concerns/approval_cycle/approvable.rb +5 -5
  5. data/app/models/concerns/enums/approval_cycle/approval.rb +9 -1
  6. data/db/migrate/20240723091231_create_approval_cycle_setups.rb +3 -3
  7. data/lib/approval_cycle/configuration.rb +16 -1
  8. data/lib/approval_cycle/version.rb +1 -1
  9. data/lib/generators/approval_cycle/install/templates/approval_cycle.rb +13 -1
  10. data/lib/generators/approval_cycle/setup_types_generator.rb +49 -5
  11. data/lib/tasks/approval_cycle_tasks.rake +17 -17
  12. data/spec/dummy/app/models/dummy_request.rb +1 -0
  13. data/spec/dummy/config/initializers/approval_cycle.rb +24 -1
  14. data/spec/dummy/db/migrate/{20250731094005_create_approval_cycle_setups.rb → 20250731123034_create_approval_cycle_setups.rb} +3 -3
  15. data/spec/dummy/db/schema.rb +4 -5
  16. data/spec/dummy/log/development.log +121 -0
  17. data/spec/dummy/log/test.log +55486 -0
  18. data/spec/features/configurable_approval_statuses_demo_spec.rb +76 -0
  19. data/spec/lib/approval_cycle/configuration_spec.rb +81 -0
  20. data/spec/models/approval_cycle/approval_spec.rb +38 -9
  21. data/spec/models/approval_cycle/setup_spec.rb +2 -0
  22. data/spec/services/approval_cycle/setup_updater_spec.rb +5 -3
  23. metadata +19 -18
  24. data/db/migrate/20240723091230_enable_pg_trgm_extention.rb +0 -9
  25. data/spec/dummy/db/migrate/20250731094004_enable_pg_trgm_extention.rb +0 -9
  26. /data/spec/dummy/db/migrate/{20250731094006_create_approval_cycle_approvers.rb → 20250731123035_create_approval_cycle_approvers.rb} +0 -0
  27. /data/spec/dummy/db/migrate/{20250731094007_create_approval_cycle_watchers.rb → 20250731123036_create_approval_cycle_watchers.rb} +0 -0
  28. /data/spec/dummy/db/migrate/{20250731094008_create_approval_cycle_action_takers.rb → 20250731123037_create_approval_cycle_action_takers.rb} +0 -0
  29. /data/spec/dummy/db/migrate/{20250731094009_create_approval_cycle_object_activities.rb → 20250731123038_create_approval_cycle_object_activities.rb} +0 -0
  30. /data/spec/dummy/db/migrate/{20250731094010_create_approval_cycle_approvals.rb → 20250731123039_create_approval_cycle_approvals.rb} +0 -0
  31. /data/spec/dummy/db/migrate/{20250731094101_add_approval_cycle_to_configured_types.rb → 20250731123227_add_approval_cycle_to_configured_types.rb} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 31e74d107dc31d866113b5fc73974a1c01e16c3957d4119b647fe427e82ec65a
4
- data.tar.gz: 6994b749bc83ef675b1566a4318b5118a5fb93bf959ebf00f6250dea4546762e
3
+ metadata.gz: 7a26ab8391d8fbd00fffc4c0d0967557ddfbcf1d00da72bb966781e079d2155b
4
+ data.tar.gz: b8b4bd9e2adc6c244ffd384d45fb42c4d97682b239b954205cdde3fba2cd160c
5
5
  SHA512:
6
- metadata.gz: 7caab04d5f32ecc2a73c0d0569f4f27ab38c9c1a6ff3212de92867051666dc5d0d158de97a63ecb2fa50ccef35c9e1c7d76293cffc09ed9c81d37a31dacddab4
7
- data.tar.gz: 5d627d23839b19e6c468f116d74806e34df172f5837c547f4ad6e85f33fa82f6c5063164603e7cf95f6891500bf006165989eb9beb727336486c6e75ae5f25b0
6
+ metadata.gz: db1daaff18eb16ebf91b2d2a207fca4f84f27ba65e7863757528891c5925e1093fc5ff7157a0b302a9af23d935387e553b67f71bc97395e2283e7f0639588ab6
7
+ data.tar.gz: e8bf4cc8578b27cb1307499f62f80420f037d6f34969384161f9b8e2a9dc10c67ea46ec610e70631c7edc3ccd5186752ea9b636b2fe12eedda14ddfc9b22e2db
data/README.md CHANGED
@@ -62,25 +62,50 @@ The gem is available as open source under the terms of the [MIT License](https:/
62
62
  config.approval_cycle_setup_types = { dummy_request: 0 }
63
63
  end
64
64
  ```
65
+
66
+ ## Configuration Options
67
+
68
+ ### Approval Types
69
+ Define which models in your application can have approval workflows:
70
+ ```ruby
71
+ ApprovalCycle.configure do |config|
72
+ config.approval_cycle_setup_types = {
73
+ dummy_request: 0,
74
+ purchase_order: 1,
75
+ expense_report: 2
76
+ }
77
+ end
78
+ ```
79
+
80
+ ### Approval Statuses
81
+ Customize the approval statuses available in your application. If not provided, the gem will use the default statuses:
82
+ ```ruby
83
+ ApprovalCycle.configure do |config|
84
+ config.approval_statuses = {
85
+ pending: "pending",
86
+ approved: "approved",
87
+ rejected: "rejected",
88
+ cancelled: "cancelled",
89
+ on_hold: "on_hold"
90
+ }
91
+ end
92
+ ```
93
+
94
+ **Default statuses**: `pending`, `rejected`, `approved`, `skipped`, `auto_approved`, `skipped_after_rejection`, `skipped_after_withdrawal`
65
95
  5. Generate migrations for your configured types:
66
96
  ```bash
67
97
  # Check which columns are missing
68
98
  rails generate approval_cycle:setup_types --status
69
99
 
70
100
  # Generate migration to add approval cycle columns to your models
101
+ # This will also automatically add ApprovalCycle::Approvable to your model files
71
102
  rails generate approval_cycle:setup_types
72
103
  ```
73
104
  6. Run the migrations:
74
105
  ```bash
75
106
  rails db:migrate
76
107
  ```
77
- 7. Include `ApprovalCycle::Approvable` in your models that require approval workflows:
78
- ```ruby
79
- class YourModel < ApplicationRecord
80
- include ApprovalCycle::Approvable
81
- end
82
- ```
83
- 8. Approval cycle uses versioning for the approval cycle setups to not mess with old approvable records after updating the setup. To use the versioning, you must update your approval cycle setup with the `SetupUpdater` service:
108
+ 7. Approval cycle uses versioning for the approval cycle setups to not mess with old approvable records after updating the setup. To use the versioning, you must update your approval cycle setup with the `SetupUpdater` service:
84
109
  ```ruby
85
110
  ApprovalCycle::SetupUpdater.call(approval_cycle_setup: your_approval_cycle_setup_record, params: {attributes to update}, apply_to_versions: {true | false})
86
111
  ```
@@ -110,15 +135,10 @@ When you need to add new approval types to your application:
110
135
  rails db:migrate
111
136
  ```
112
137
 
113
- 4. Include the `ApprovalCycle::Approvable` concern in your new model:
114
- ```ruby
115
- class NewModel < ApplicationRecord
116
- include ApprovalCycle::Approvable
117
- end
118
- ```
138
+ Note: The `ApprovalCycle::Approvable` concern will be automatically added to your new model when you run the generator.
119
139
 
120
140
  ## Generator Commands
121
141
 
122
- - `rails generate approval_cycle:install` - Creates the initializer file
142
+ - `rails generate approval_cycle:install` - Creates the initializer file and copies migrations
123
143
  - `rails generate approval_cycle:setup_types --status` - Shows which approval cycle columns are missing for configured types
124
- - `rails generate approval_cycle:setup_types` - Generates migration to add missing approval cycle columns to your configured models
144
+ - `rails generate approval_cycle:setup_types` - Generates migration to add missing approval cycle columns to your configured models and automatically adds `ApprovalCycle::Approvable` concern to the model files
@@ -20,9 +20,12 @@ module ApprovalCycle
20
20
  private
21
21
 
22
22
  def update_previous_approval_cycle_versions
23
- Setup.where(level: level,
24
- latest_setup_version_id: latest_setup_version_id)
25
- .update_all(latest_setup_version_id: id)
23
+ # Mark all previous setups for the same level as not latest
24
+ previous_setups = Setup.where(level: level).where.not(id: id)
25
+ previous_setups.update_all(latest: false, latest_setup_version_id: id)
26
+
27
+ # Ensure this setup is marked as latest and points to itself
28
+ update_columns(latest: true, latest_setup_version_id: id)
26
29
  end
27
30
 
28
31
  def set_approvers_order
@@ -5,9 +5,9 @@ module ApprovalCycle::Approvable
5
5
  include ApprovalCycle::ActsAsTrackable
6
6
  acts_as_trackable
7
7
 
8
- belongs_to :approval_cycle_setup, class_name: "ApprovalCycle::Setup", foreign_key: "approval_cycle_setup_id"
9
- has_many :approval_cycle_approvers, through: :approval_cycle_setup, class_name: "ApprovalCycle::Approver"
10
- has_many :approval_cycle_approvals, foreign_key: :approvable_id, dependent: :destroy, class_name: "ApprovalCycle::Approval"
8
+ belongs_to :approval_cycle_setup, class_name: 'ApprovalCycle::Setup', foreign_key: 'approval_cycle_setup_id'
9
+ has_many :approval_cycle_approvers, through: :approval_cycle_setup, class_name: 'ApprovalCycle::Approver'
10
+ has_many :approval_cycle_approvals, foreign_key: :approvable_id, dependent: :destroy, class_name: 'ApprovalCycle::Approval'
11
11
 
12
12
  before_validation :link_to_approval_cycle_setup, on: %i[create update], if: -> { requires_linking_to_approval_cycle_setup? }
13
13
 
@@ -69,11 +69,11 @@ module ApprovalCycle::Approvable
69
69
  end
70
70
 
71
71
  def requires_building_approvals?
72
- approval_cycle_status_was == "draft" && approval_cycle_status_pending?
72
+ approval_cycle_status_was == 'draft' && approval_cycle_status_pending?
73
73
  end
74
74
 
75
75
  def allowed_to_resync_approval_cycle?
76
- raise "resync_approval_cycle! should only be called within the context of ApprovalCycle::SetupUpdater" unless caller.any? { |c| c.include?("setup_updater") }
76
+ raise 'resync_approval_cycle! should only be called within the context of ApprovalCycle::SetupUpdater' unless caller.any? { |c| c.include?('setup_updater') }
77
77
 
78
78
  new_approval_cycle_setup_version.present?
79
79
  end
@@ -2,6 +2,14 @@ module Enums::ApprovalCycle::Approval
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  included do
5
- enum status: { pending: "pending", rejected: "rejected", approved: "approved", skipped: "skipped", auto_approved: "auto_approved", skipped_after_rejection: "skipped_after_rejection", skipped_after_withdrawal: "skipped_after_withdrawal" }, _prefix: true
5
+ enum status: ApprovalCycle.configuration&.approval_statuses || {
6
+ pending: 'pending',
7
+ rejected: 'rejected',
8
+ approved: 'approved',
9
+ skipped: 'skipped',
10
+ auto_approved: 'auto_approved',
11
+ skipped_after_rejection: 'skipped_after_rejection',
12
+ skipped_after_withdrawal: 'skipped_after_withdrawal'
13
+ }, _prefix: true
6
14
  end
7
15
  end
@@ -4,12 +4,12 @@ class CreateApprovalCycleSetups < ActiveRecord::Migration[7.0]
4
4
  t.integer :approval_cycle_setup_type
5
5
  t.integer :skip_after
6
6
  t.string :name, null: false
7
- t.virtual :latest, type: :boolean, as: '(latest_setup_version_id = id)', stored: true
8
- t.references :latest_setup_version, foreign_key: { to_table: :approval_cycle_setups }, index: true, null: false, default: -> { "currval('approval_cycle_setups_id_seq'::regclass)" }
7
+ t.boolean :latest, default: true, null: false
8
+ t.references :latest_setup_version, foreign_key: { to_table: :approval_cycle_setups }, index: true, null: true
9
9
  t.references :level, index: true, null: false, polymorphic: true
10
10
  t.timestamps
11
11
  end
12
12
 
13
- add_index :approval_cycle_setups, :name, using: 'gin', opclass: 'gin_trgm_ops'
13
+ add_index :approval_cycle_setups, :name
14
14
  end
15
15
  end
@@ -1,9 +1,24 @@
1
1
  module ApprovalCycle
2
2
  class Configuration
3
- attr_accessor :approval_cycle_setup_types
3
+ attr_accessor :approval_cycle_setup_types, :approval_statuses
4
4
 
5
5
  def initialize
6
6
  @approval_cycle_setup_types = {}
7
+ @approval_statuses = default_approval_statuses
8
+ end
9
+
10
+ private
11
+
12
+ def default_approval_statuses
13
+ {
14
+ pending: 'pending',
15
+ rejected: 'rejected',
16
+ approved: 'approved',
17
+ skipped: 'skipped',
18
+ auto_approved: 'auto_approved',
19
+ skipped_after_rejection: 'skipped_after_rejection',
20
+ skipped_after_withdrawal: 'skipped_after_withdrawal'
21
+ }
7
22
  end
8
23
  end
9
24
  end
@@ -1,3 +1,3 @@
1
1
  module ApprovalCycle
2
- VERSION = '0.1.0.pre'.freeze
2
+ VERSION = '0.1.1.pre'.freeze
3
3
  end
@@ -3,7 +3,7 @@ ApprovalCycle.configure do |config|
3
3
  # Each type should have a unique integer value
4
4
  # Example:
5
5
  # config.approval_cycle_setup_types = {
6
- # purchase_order: 0,
6
+ # dummy_request: 0,
7
7
  # expense_report: 1,
8
8
  # document_approval: 2
9
9
  # }
@@ -12,4 +12,16 @@ ApprovalCycle.configure do |config|
12
12
  # Add your approvable models here
13
13
  # model_name: integer_value
14
14
  }
15
+
16
+ # Customize approval statuses (optional)
17
+ # If not specified, default statuses will be used:
18
+ # pending, rejected, approved, skipped, auto_approved, skipped_after_rejection, skipped_after_withdrawal
19
+ # Example:
20
+ # config.approval_statuses = {
21
+ # pending: "pending",
22
+ # approved: "approved",
23
+ # rejected: "rejected",
24
+ # cancelled: "cancelled",
25
+ # on_hold: "on_hold"
26
+ # }
15
27
  end
@@ -27,13 +27,14 @@ module ApprovalCycle
27
27
  def create_migration_file
28
28
  if no_changes_needed?
29
29
  say "All configured types already have approval cycle columns. No migration needed.", :green
30
- return
30
+ else
31
+ migration_template(
32
+ 'setup_types_migration.rb.erb',
33
+ 'db/migrate/add_approval_cycle_to_configured_types.rb'
34
+ )
31
35
  end
32
36
 
33
- migration_template(
34
- 'setup_types_migration.rb.erb',
35
- 'db/migrate/add_approval_cycle_to_configured_types.rb'
36
- )
37
+ add_approvable_concern_to_models
37
38
  end
38
39
 
39
40
  def show_status
@@ -87,6 +88,49 @@ module ApprovalCycle
87
88
  def approval_cycle_columns
88
89
  %w[approval_cycle_setup_id approval_cycle_status is_approval_cycle_reset]
89
90
  end
91
+
92
+ def add_approvable_concern_to_models
93
+ say "\nAdding ApprovalCycle::Approvable concern to models...", :blue
94
+
95
+ configured_types.each do |type|
96
+ model_name = type.to_s.camelize
97
+ model_file_path = "app/models/#{type}.rb"
98
+
99
+ if File.exist?(model_file_path)
100
+ add_concern_to_model(model_file_path, model_name, type)
101
+ else
102
+ say " ✗ Model file not found: #{model_file_path}", :red
103
+ end
104
+ end
105
+ end
106
+
107
+ def add_concern_to_model(model_file_path, model_name, type)
108
+ content = File.read(model_file_path)
109
+
110
+ if content.include?("include ApprovalCycle::Approvable")
111
+ say " ✓ #{model_name} already includes ApprovalCycle::Approvable", :green
112
+ return
113
+ end
114
+
115
+ # Find the class definition line
116
+ class_line_match = content.match(/^(\s*)class\s+#{model_name}\s*<.*$/)
117
+ unless class_line_match
118
+ say " ✗ Could not find class definition for #{model_name}", :red
119
+ return
120
+ end
121
+
122
+ # Insert the concern after the class definition
123
+ indent = class_line_match[1]
124
+ concern_line = "#{indent} include ApprovalCycle::Approvable\n"
125
+
126
+ updated_content = content.sub(
127
+ /(^#{Regexp.escape(class_line_match[0])}\n)/,
128
+ "\\1#{concern_line}\n"
129
+ )
130
+
131
+ File.write(model_file_path, updated_content)
132
+ say " ✓ Added ApprovalCycle::Approvable to #{model_name}", :green
133
+ end
90
134
  end
91
135
  end
92
136
  end
@@ -1,30 +1,30 @@
1
1
  namespace :approval_cycle do
2
2
  namespace :install do
3
- desc "Copy migrations from approval_cycle to application"
3
+ desc 'Copy migrations from approval_cycle to application'
4
4
  task :migrations do
5
- source = File.join(File.dirname(__FILE__), "..", "..", "db", "migrate")
6
- destination = Rails.root.join("db", "migrate")
5
+ source = File.join(File.dirname(__FILE__), '..', '..', 'db', 'migrate')
6
+ destination = Rails.root.join('db', 'migrate')
7
7
 
8
8
  migration_template = /\A(\d+)_(.*\.rb)\z/
9
9
 
10
- Dir[File.join(source, "*.rb")].each do |file|
10
+ Dir[File.join(source, '*.rb')].each do |file|
11
11
  basename = File.basename(file)
12
12
 
13
- if basename =~ migration_template
14
- name = $2
15
- # Generate new timestamp
16
- new_timestamp = Time.now.utc.strftime("%Y%m%d%H%M%S")
17
- new_name = "#{new_timestamp}_#{name}"
13
+ next unless basename =~ migration_template
18
14
 
19
- # Check if migration already exists
20
- existing = Dir[File.join(destination, "*_#{name}")].first
15
+ name = Regexp.last_match(2)
16
+ # Generate new timestamp
17
+ new_timestamp = Time.now.utc.strftime('%Y%m%d%H%M%S')
18
+ new_name = "#{new_timestamp}_#{name}"
21
19
 
22
- unless existing
23
- FileUtils.cp(file, File.join(destination, new_name))
24
- puts "Copied migration: #{new_name}"
25
- else
26
- puts "Migration already exists: #{File.basename(existing)}"
27
- end
20
+ # Check if migration already exists
21
+ existing = Dir[File.join(destination, "*_#{name}")].first
22
+
23
+ if existing
24
+ puts "Migration already exists: #{File.basename(existing)}"
25
+ else
26
+ FileUtils.cp(file, File.join(destination, new_name))
27
+ puts "Copied migration: #{new_name}"
28
28
  end
29
29
  end
30
30
  end
@@ -1,3 +1,4 @@
1
1
  class DummyRequest < ApplicationRecord
2
2
  include ApprovalCycle::Approvable
3
+
3
4
  end
@@ -3,7 +3,7 @@ ApprovalCycle.configure do |config|
3
3
  # Each type should have a unique integer value
4
4
  # Example:
5
5
  # config.approval_cycle_setup_types = {
6
- # purchase_order: 0,
6
+ # dummy_request: 0,
7
7
  # expense_report: 1,
8
8
  # document_approval: 2
9
9
  # }
@@ -13,4 +13,27 @@ ApprovalCycle.configure do |config|
13
13
  # model_name: integer_value
14
14
  dummy_request: 0
15
15
  }
16
+
17
+ # Customize approval statuses (optional)
18
+ # If not specified, default statuses will be used:
19
+ # pending, rejected, approved, skipped, auto_approved, skipped_after_rejection, skipped_after_withdrawal
20
+ # Example:
21
+ # config.approval_statuses = {
22
+ # pending: "pending",
23
+ # approved: "approved",
24
+ # rejected: "rejected",
25
+ # cancelled: "cancelled",
26
+ # on_hold: "on_hold"
27
+ # }
28
+
29
+ config.approval_statuses = {
30
+ pending: 'pending',
31
+ approved: 'approved',
32
+ rejected: 'rejected',
33
+ cancelled: 'cancelled',
34
+ on_hold: 'on_hold',
35
+ auto_approved: 'auto_approved',
36
+ skipped_after_rejection: 'skipped_after_rejection',
37
+ skipped_after_withdrawal: 'skipped_after_withdrawal'
38
+ }
16
39
  end
@@ -4,12 +4,12 @@ class CreateApprovalCycleSetups < ActiveRecord::Migration[7.0]
4
4
  t.integer :approval_cycle_setup_type
5
5
  t.integer :skip_after
6
6
  t.string :name, null: false
7
- t.virtual :latest, type: :boolean, as: '(latest_setup_version_id = id)', stored: true
8
- t.references :latest_setup_version, foreign_key: { to_table: :approval_cycle_setups }, index: true, null: false, default: -> { "currval('approval_cycle_setups_id_seq'::regclass)" }
7
+ t.boolean :latest, default: true, null: false
8
+ t.references :latest_setup_version, foreign_key: { to_table: :approval_cycle_setups }, index: true, null: true
9
9
  t.references :level, index: true, null: false, polymorphic: true
10
10
  t.timestamps
11
11
  end
12
12
 
13
- add_index :approval_cycle_setups, :name, using: 'gin', opclass: 'gin_trgm_ops'
13
+ add_index :approval_cycle_setups, :name
14
14
  end
15
15
  end
@@ -10,9 +10,8 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema[7.2].define(version: 2025_07_31_094101) do
13
+ ActiveRecord::Schema[7.2].define(version: 2025_07_31_123227) do
14
14
  # These are extensions that must be enabled in order to support this database
15
- enable_extension "pg_trgm"
16
15
  enable_extension "plpgsql"
17
16
 
18
17
  create_table "approval_cycle_action_takers", force: :cascade do |t|
@@ -63,15 +62,15 @@ ActiveRecord::Schema[7.2].define(version: 2025_07_31_094101) do
63
62
  t.integer "approval_cycle_setup_type"
64
63
  t.integer "skip_after"
65
64
  t.string "name", null: false
66
- t.virtual "latest", type: :boolean, as: "(latest_setup_version_id = id)", stored: true
67
- t.bigint "latest_setup_version_id", default: -> { "currval('approval_cycle_setups_id_seq'::regclass)" }, null: false
65
+ t.boolean "latest", default: true, null: false
66
+ t.bigint "latest_setup_version_id"
68
67
  t.string "level_type", null: false
69
68
  t.bigint "level_id", null: false
70
69
  t.datetime "created_at", null: false
71
70
  t.datetime "updated_at", null: false
72
71
  t.index ["latest_setup_version_id"], name: "index_approval_cycle_setups_on_latest_setup_version_id"
73
72
  t.index ["level_type", "level_id"], name: "index_approval_cycle_setups_on_level"
74
- t.index ["name"], name: "index_approval_cycle_setups_on_name", opclass: :gin_trgm_ops, using: :gin
73
+ t.index ["name"], name: "index_approval_cycle_setups_on_name"
75
74
  end
76
75
 
77
76
  create_table "approval_cycle_watchers", force: :cascade do |t|
@@ -2301,3 +2301,124 @@ FOREIGN KEY ("approval_cycle_setup_id")
2301
2301
  TRANSACTION (1.5ms) COMMIT
2302
2302
   (0.5ms) SELECT pg_advisory_unlock(7679382742404183405)
2303
2303
  ActiveRecord::SchemaMigration Load (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2304
+ ActiveRecord::SchemaMigration Load (3.4ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2305
+ ActiveRecord::InternalMetadata Load (3.6ms) SELECT * FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 ORDER BY "ar_internal_metadata"."key" ASC LIMIT 1 [[nil, "environment"]]
2306
+ ActiveRecord::SchemaMigration Load (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2307
+ ActiveRecord::InternalMetadata Load (0.3ms) SELECT * FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 ORDER BY "ar_internal_metadata"."key" ASC LIMIT 1 [[nil, "environment"]]
2308
+ ActiveRecord::SchemaMigration Load (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2309
+ ActiveRecord::InternalMetadata Load (0.3ms) SELECT * FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 ORDER BY "ar_internal_metadata"."key" ASC LIMIT 1 [[nil, "environment"]]
2310
+  (110.2ms) DROP DATABASE IF EXISTS "approval_cycle_development"
2311
+  (61.8ms) DROP DATABASE IF EXISTS "approval_cycle_test"
2312
+  (124.9ms) CREATE DATABASE "approval_cycle_development" ENCODING = 'unicode'
2313
+  (68.4ms) CREATE DATABASE "approval_cycle_test" ENCODING = 'unicode'
2314
+  (4.6ms) CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY)
2315
+  (1.5ms) CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp(6) NOT NULL, "updated_at" timestamp(6) NOT NULL)
2316
+  (0.5ms) SELECT pg_try_advisory_lock(7679382742404183405)
2317
+ ActiveRecord::SchemaMigration Load (0.7ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2318
+ ActiveRecord::InternalMetadata Load (1.2ms) SELECT * FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 ORDER BY "ar_internal_metadata"."key" ASC LIMIT 1 [[nil, "environment"]]
2319
+ ActiveRecord::InternalMetadata Create (1.8ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ('environment', 'development', '2025-07-31 12:28:56.272916', '2025-07-31 12:28:56.272920') RETURNING "key"
2320
+ Migrating to CreateCompanies (20241028115559)
2321
+ TRANSACTION (1.0ms) BEGIN
2322
+  (5.0ms) CREATE TABLE "companies" ("id" bigserial primary key, "name" character varying, "created_at" timestamp(6) NOT NULL, "updated_at" timestamp(6) NOT NULL)
2323
+ ActiveRecord::SchemaMigration Create (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20241028115559') RETURNING "version"
2324
+ TRANSACTION (0.5ms) COMMIT
2325
+ Migrating to CreateDummyUsers (20241028115633)
2326
+ TRANSACTION (0.2ms) BEGIN
2327
+  (3.0ms) CREATE TABLE "dummy_users" ("id" bigserial primary key, "name" character varying, "created_at" timestamp(6) NOT NULL, "updated_at" timestamp(6) NOT NULL)
2328
+ ActiveRecord::SchemaMigration Create (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20241028115633') RETURNING "version"
2329
+ TRANSACTION (0.2ms) COMMIT
2330
+ Migrating to CreateDummyRequests (20241030055459)
2331
+ TRANSACTION (0.2ms) BEGIN
2332
+  (2.7ms) CREATE TABLE "dummy_requests" ("id" bigserial primary key, "name" character varying, "created_at" timestamp(6) NOT NULL, "updated_at" timestamp(6) NOT NULL)
2333
+ ActiveRecord::SchemaMigration Create (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20241030055459') RETURNING "version"
2334
+ TRANSACTION (0.4ms) COMMIT
2335
+  (0.2ms) SELECT pg_advisory_unlock(7679382742404183405)
2336
+ ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2337
+  (0.2ms) SELECT pg_try_advisory_lock(7679382742404183405)
2338
+ ActiveRecord::SchemaMigration Load (2.4ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2339
+ ActiveRecord::InternalMetadata Load (3.5ms) SELECT * FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 ORDER BY "ar_internal_metadata"."key" ASC LIMIT 1 [[nil, "environment"]]
2340
+  (0.2ms) SELECT pg_advisory_unlock(7679382742404183405)
2341
+ ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2342
+  (0.2ms) SELECT pg_try_advisory_lock(7679382742404183405)
2343
+ ActiveRecord::SchemaMigration Load (2.6ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2344
+ ActiveRecord::InternalMetadata Load (2.9ms) SELECT * FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 ORDER BY "ar_internal_metadata"."key" ASC LIMIT 1 [[nil, "environment"]]
2345
+ Migrating to CreateApprovalCycleSetups (20250731123034)
2346
+ TRANSACTION (3.0ms) BEGIN
2347
+  (15.5ms) CREATE TABLE "approval_cycle_setups" ("id" bigserial primary key, "approval_cycle_setup_type" integer, "skip_after" integer, "name" character varying NOT NULL, "latest" boolean DEFAULT TRUE NOT NULL, "latest_setup_version_id" bigint, "level_type" character varying NOT NULL, "level_id" bigint NOT NULL, "created_at" timestamp(6) NOT NULL, "updated_at" timestamp(6) NOT NULL, CONSTRAINT "fk_rails_e28660e2c9"
2348
+ FOREIGN KEY ("latest_setup_version_id")
2349
+ REFERENCES "approval_cycle_setups" ("id")
2350
+ )
2351
+  (0.6ms) CREATE INDEX "index_approval_cycle_setups_on_latest_setup_version_id" ON "approval_cycle_setups" ("latest_setup_version_id")
2352
+  (0.6ms) CREATE INDEX "index_approval_cycle_setups_on_level" ON "approval_cycle_setups" ("level_type", "level_id")
2353
+  (0.4ms) CREATE INDEX "index_approval_cycle_setups_on_name" ON "approval_cycle_setups" ("name")
2354
+ ActiveRecord::SchemaMigration Create (1.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20250731123034') RETURNING "version"
2355
+ TRANSACTION (0.5ms) COMMIT
2356
+ Migrating to CreateApprovalCycleApprovers (20250731123035)
2357
+ TRANSACTION (0.2ms) BEGIN
2358
+  (3.5ms) CREATE TABLE "approval_cycle_approvers" ("id" bigserial primary key, "order" integer NOT NULL, "approval_cycle_setup_id" bigint NOT NULL, "user_type" character varying NOT NULL, "user_id" bigint NOT NULL, CONSTRAINT "fk_rails_29d5c295cb"
2359
+ FOREIGN KEY ("approval_cycle_setup_id")
2360
+ REFERENCES "approval_cycle_setups" ("id")
2361
+ )
2362
+  (0.9ms) CREATE INDEX "index_approval_cycle_approvers_on_approval_cycle_setup_id" ON "approval_cycle_approvers" ("approval_cycle_setup_id")
2363
+  (0.5ms) CREATE INDEX "index_approval_cycle_approvers_on_user" ON "approval_cycle_approvers" ("user_type", "user_id")
2364
+ ActiveRecord::SchemaMigration Create (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20250731123035') RETURNING "version"
2365
+ TRANSACTION (0.4ms) COMMIT
2366
+ Migrating to CreateApprovalCycleWatchers (20250731123036)
2367
+ TRANSACTION (0.4ms) BEGIN
2368
+  (3.3ms) CREATE TABLE "approval_cycle_watchers" ("id" bigserial primary key, "action" integer, "user_type" character varying NOT NULL, "user_id" bigint NOT NULL, "approval_cycle_setup_id" bigint NOT NULL, "created_at" timestamp(6) NOT NULL, "updated_at" timestamp(6) NOT NULL, CONSTRAINT "fk_rails_9cbca1575a"
2369
+ FOREIGN KEY ("approval_cycle_setup_id")
2370
+ REFERENCES "approval_cycle_setups" ("id")
2371
+ )
2372
+  (0.6ms) CREATE INDEX "index_approval_cycle_watchers_on_user" ON "approval_cycle_watchers" ("user_type", "user_id")
2373
+  (0.5ms) CREATE INDEX "index_approval_cycle_watchers_on_approval_cycle_setup_id" ON "approval_cycle_watchers" ("approval_cycle_setup_id")
2374
+  (0.8ms) CREATE UNIQUE INDEX "index_watchers_on_user_id_and_setup_id_and_action" ON "approval_cycle_watchers" ("user_id", "user_type", "approval_cycle_setup_id", "action")
2375
+ ActiveRecord::SchemaMigration Create (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20250731123036') RETURNING "version"
2376
+ TRANSACTION (1.8ms) COMMIT
2377
+ Migrating to CreateApprovalCycleActionTakers (20250731123037)
2378
+ TRANSACTION (0.6ms) BEGIN
2379
+  (6.7ms) CREATE TABLE "approval_cycle_action_takers" ("id" bigserial primary key, "user_type" character varying NOT NULL, "user_id" bigint NOT NULL, "approval_cycle_setup_id" bigint NOT NULL, "created_at" timestamp(6) NOT NULL, "updated_at" timestamp(6) NOT NULL, CONSTRAINT "fk_rails_e718b705bb"
2380
+ FOREIGN KEY ("approval_cycle_setup_id")
2381
+ REFERENCES "approval_cycle_setups" ("id")
2382
+ )
2383
+  (1.7ms) CREATE INDEX "index_approval_cycle_action_takers_on_user" ON "approval_cycle_action_takers" ("user_type", "user_id")
2384
+  (1.0ms) CREATE INDEX "index_approval_cycle_action_takers_on_approval_cycle_setup_id" ON "approval_cycle_action_takers" ("approval_cycle_setup_id")
2385
+  (1.2ms) CREATE UNIQUE INDEX "index_action_takers_on_user_id_and_setup_id" ON "approval_cycle_action_takers" ("user_id", "user_type", "approval_cycle_setup_id")
2386
+ ActiveRecord::SchemaMigration Create (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20250731123037') RETURNING "version"
2387
+ TRANSACTION (0.6ms) COMMIT
2388
+ Migrating to CreateApprovalCycleObjectActivities (20250731123038)
2389
+ TRANSACTION (0.5ms) BEGIN
2390
+  (4.8ms) CREATE TABLE "approval_cycle_object_activities" ("id" bigserial primary key, "object_type" character varying NOT NULL, "object_id" bigint NOT NULL, "created_by_type" character varying NOT NULL, "created_by_id" bigint NOT NULL, "updated_by_type" character varying, "updated_by_id" bigint, "updated_at" timestamp(6))
2391
+  (2.1ms) CREATE INDEX "index_approval_cycle_object_activities_on_object" ON "approval_cycle_object_activities" ("object_type", "object_id")
2392
+  (2.1ms) CREATE INDEX "index_approval_cycle_object_activities_on_created_by" ON "approval_cycle_object_activities" ("created_by_type", "created_by_id")
2393
+  (0.5ms) CREATE INDEX "index_approval_cycle_object_activities_on_updated_by" ON "approval_cycle_object_activities" ("updated_by_type", "updated_by_id")
2394
+ ActiveRecord::SchemaMigration Create (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20250731123038') RETURNING "version"
2395
+ TRANSACTION (0.2ms) COMMIT
2396
+ Migrating to CreateApprovalCycleApprovals (20250731123039)
2397
+ TRANSACTION (0.2ms) BEGIN
2398
+  (2.9ms) CREATE TABLE "approval_cycle_approvals" ("id" bigserial primary key, "status" character varying, "approvable_type" character varying, "approvable_id" bigint, "approval_cycle_approver_id" bigint, "rejection_reason" character varying, "received_at" timestamp(6), CONSTRAINT "fk_rails_63529350d0"
2399
+ FOREIGN KEY ("approval_cycle_approver_id")
2400
+ REFERENCES "approval_cycle_approvers" ("id")
2401
+ )
2402
+  (1.0ms) CREATE INDEX "index_approval_cycle_approvals_on_approvable" ON "approval_cycle_approvals" ("approvable_type", "approvable_id")
2403
+  (0.7ms) CREATE INDEX "index_approval_cycle_approvals_on_approval_cycle_approver_id" ON "approval_cycle_approvals" ("approval_cycle_approver_id")
2404
+ ActiveRecord::SchemaMigration Create (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20250731123039') RETURNING "version"
2405
+ TRANSACTION (0.4ms) COMMIT
2406
+  (0.2ms) SELECT pg_advisory_unlock(7679382742404183405)
2407
+ ActiveRecord::SchemaMigration Load (0.5ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2408
+  (0.2ms) SELECT pg_try_advisory_lock(7679382742404183405)
2409
+ ActiveRecord::SchemaMigration Load (2.4ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2410
+ ActiveRecord::InternalMetadata Load (5.9ms) SELECT * FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 ORDER BY "ar_internal_metadata"."key" ASC LIMIT 1 [[nil, "environment"]]
2411
+ Migrating to AddApprovalCycleToConfiguredTypes (20250731123227)
2412
+ TRANSACTION (0.5ms) BEGIN
2413
+  (6.2ms) ALTER TABLE "dummy_requests" ADD "approval_cycle_setup_id" bigint
2414
+  (3.4ms) CREATE INDEX "index_dummy_requests_on_approval_cycle_setup_id" ON "dummy_requests" ("approval_cycle_setup_id")
2415
+  (6.5ms) ALTER TABLE "dummy_requests" ADD CONSTRAINT "fk_rails_c4c69a6205"
2416
+ FOREIGN KEY ("approval_cycle_setup_id")
2417
+ REFERENCES "approval_cycle_setups" ("id")
2418
+ 
2419
+  (0.3ms) ALTER TABLE "dummy_requests" ADD "approval_cycle_status" integer
2420
+  (2.3ms) ALTER TABLE "dummy_requests" ADD "is_approval_cycle_reset" boolean DEFAULT FALSE
2421
+ ActiveRecord::SchemaMigration Create (4.1ms) INSERT INTO "schema_migrations" ("version") VALUES ('20250731123227') RETURNING "version"
2422
+ TRANSACTION (0.9ms) COMMIT
2423
+  (0.4ms) SELECT pg_advisory_unlock(7679382742404183405)
2424
+ ActiveRecord::SchemaMigration Load (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC