Revamp entropy configuraiton

- Move both settings to its dedicated model entropy configuration
- A collection can have an entropy configuration, or will default to the account if not
This commit is contained in:
Jorge Manrubia
2025-06-04 10:41:08 +02:00
parent 56b32e6f52
commit 91787a3523
16 changed files with 199 additions and 46 deletions
+1 -1
View File
@@ -33,7 +33,7 @@ class CollectionsController < ApplicationController
end
def collection_params
params.expect(collection: [ :name, :all_access, :auto_close_period ])
params.expect(collection: [ :name, :all_access, :auto_close_period, :auto_reconsider_period ])
end
def grantees
+1 -1
View File
@@ -1,5 +1,5 @@
class Account < ApplicationRecord
include Joinable
include Entropy, Joinable
has_many_attached :uploads
end
+18
View File
@@ -0,0 +1,18 @@
module Account::Entropy
extend ActiveSupport::Concern
included do
has_one :default_entropy_configuration, class_name: "Entropy::Configuration", as: :container, dependent: :destroy
before_save :set_default_entropy_configuration
end
private
DEFAULT_ENTROPY_PERIOD = 30.days
def set_default_entropy_configuration
self.default_entropy_configuration ||= build_default_entropy_configuration \
auto_close_period: DEFAULT_ENTROPY_PERIOD,
auto_reconsider_period: DEFAULT_ENTROPY_PERIOD
end
end
+2 -2
View File
@@ -8,9 +8,9 @@ module Card::Entropy
scope :in_auto_closing_collection, -> { joins(:collection).merge(Collection.auto_closing) }
scope :stagnated, -> { doing.where(last_active_at: ..AUTO_RECONSIDER_PERIOD.ago) }
scope :due_to_be_closed, -> { considering.in_auto_closing_collection.where("last_active_at <= DATETIME('now', '-' || auto_close_period || ' seconds')") }
scope :due_to_be_closed, -> { considering.in_auto_closing_collection.where("last_active_at <= DATETIME('now', '-' || entropy_configurations.auto_close_period || ' seconds')") }
delegate :auto_close_period, to: :collection
delegate :auto_close_period, :auto_reconsider_period, to: :collection
end
class_methods do
+2 -1
View File
@@ -1,11 +1,12 @@
class Collection < ApplicationRecord
include AutoClosing, Accessible, Broadcastable, Filterable, Workflowing
include AutoClosing, Accessible, Broadcastable, Entropy, Filterable, Workflowing
belongs_to :creator, class_name: "User", default: -> { Current.user }
has_many :cards, dependent: :destroy
has_many :tags, -> { distinct }, through: :cards
has_many :events
has_one :entropy_configuration, class_name: "Entropy::Configuration", as: :container, dependent: :destroy
scope :alphabetically, -> { order("lower(name)") }
+2 -2
View File
@@ -2,12 +2,12 @@ module Collection::AutoClosing
extend ActiveSupport::Concern
included do
scope :auto_closing, -> { where.not(auto_close_period: nil) }
scope :auto_closing, -> { joins(:entropy_configuration).where.not("entropy_configurations.auto_close_period": nil) }
before_create :set_default_auto_close_period
end
def auto_closing?
auto_close_period.present?
entropy_configuration.present?
end
private
+21
View File
@@ -0,0 +1,21 @@
module Collection::Entropy
extend ActiveSupport::Concern
included do
delegate :auto_close_period, :auto_reconsider_period, to: :entropy_configuration
end
def entropy_configuration
super || Account.sole.default_entropy_configuration
end
def auto_close_period=(new_value)
entropy_configuration ||= association(:entropy_configuration).reader || self.build_entropy_configuration
entropy_configuration.update auto_close_period: new_value
end
def auto_reconsider_period=(new_value)
entropy_configuration ||= association(:entropy_configuration).reader || self.build_entropy_configuration
entropy_configuration.update auto_reconsider_period: new_value
end
end
+5
View File
@@ -0,0 +1,5 @@
module Entropy
def self.table_name_prefix
"entropy_"
end
end
+3
View File
@@ -0,0 +1,3 @@
class Entropy::Configuration < ApplicationRecord
belongs_to :container, polymorphic: true
end
@@ -5,12 +5,12 @@
<strong>Cards in Considering</strong>
<p class="txt-x-small margin-none">Auto-close after…</p>
<%= form_with model: collection, data: { controller: "form" } do |form| %>
<%= form.select :auto_close_period, collection_auto_close_options, {}, { class: "input input--select full-width margin-block-half txt-small fill-white txt-align-center", data: { action: "change->form#submit" } } %>
<%= form.select :auto_reconsider_period, collection_auto_close_options, {}, { class: "input input--select full-width margin-block-half txt-small fill-white txt-align-center", data: { action: "change->form#submit" } } %>
<% end %>
</div>
<div class="separator margin-block-half" style="--border-color: var(--color-ink-medium); min-block-size: 4lh;"></div>
<div class="flex flex-column full-width" style="flex-basis: 48%">
<strong>Cards inDoing</strong>
<strong>Cards in Doing</strong>
<p class="txt-x-small margin-none">Fall back to Considering after…</p>
<%= form_with model: collection, data: { controller: "form" } do |form| %>
<%= form.select :auto_close_period, collection_auto_close_options, {}, { class: "input input--select full-width margin-block-half txt-small fill-white txt-align-center", data: { action: "change->form#submit" } } %>
@@ -18,4 +18,3 @@
</div>
</div>
</div>
@@ -0,0 +1,15 @@
class CreateEntropyConfigurations < ActiveRecord::Migration[8.1]
def change
create_table :entropy_configurations do |t|
t.references :container, polymorphic: true, null: false, index: { unique: true }
t.bigint :auto_close_period, null: false, default: 30.days.to_i
t.bigint :auto_reconsider_period, null: false, default: 30.days.to_i
t.timestamps
t.index %i[ container_type container_id auto_close_period ]
t.index %i[ container_type container_id auto_reconsider_period ]
end
end
end
Generated
+13 -3
View File
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.1].define(version: 2025_06_01_161653) do
ActiveRecord::Schema[8.1].define(version: 2025_06_04_080022) do
create_table "accesses", force: :cascade do |t|
t.integer "collection_id", null: false
t.datetime "created_at", null: false
@@ -141,13 +141,11 @@ ActiveRecord::Schema[8.1].define(version: 2025_06_01_161653) do
create_table "collections", force: :cascade do |t|
t.boolean "all_access", default: false, null: false
t.bigint "auto_close_period"
t.datetime "created_at", null: false
t.integer "creator_id", null: false
t.string "name", null: false
t.datetime "updated_at", null: false
t.integer "workflow_id"
t.index ["auto_close_period"], name: "index_collections_on_auto_close_period"
t.index ["creator_id"], name: "index_collections_on_creator_id"
t.index ["workflow_id"], name: "index_collections_on_workflow_id"
end
@@ -188,6 +186,18 @@ ActiveRecord::Schema[8.1].define(version: 2025_06_01_161653) do
t.index ["filter_id"], name: "index_creators_filters_on_filter_id"
end
create_table "entropy_configurations", force: :cascade do |t|
t.bigint "auto_close_period", default: 2592000, null: false
t.bigint "auto_reconsider_period", default: 2592000, null: false
t.integer "container_id", null: false
t.string "container_type", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["container_type", "container_id", "auto_close_period"], name: "idx_on_container_type_container_id_auto_close_perio_74dc880875"
t.index ["container_type", "container_id", "auto_reconsider_period"], name: "idx_on_container_type_container_id_auto_reconsider__583aaddbea"
t.index ["container_type", "container_id"], name: "index_entropy_configurations_on_container", unique: true
end
create_table "events", force: :cascade do |t|
t.string "action", null: false
t.integer "collection_id", null: false
+101 -27
View File
@@ -495,16 +495,6 @@ columns:
default_function:
collation:
comment:
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
name: auto_close_period
cast_type: *11
sql_type_metadata: *12
'null': true
default:
default_function:
collation:
comment:
- *5
- *24
- *6
@@ -585,6 +575,50 @@ columns:
creators_filters:
- *24
- *19
entropy_configurations:
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
name: auto_close_period
cast_type: *11
sql_type_metadata: *12
'null': false
default: 2592000
default_function:
collation:
comment:
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
name: auto_reconsider_period
cast_type: *11
sql_type_metadata: *12
'null': false
default: 2592000
default_function:
collation:
comment:
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
name: container_id
cast_type: *1
sql_type_metadata: *2
'null': false
default:
default_function:
collation:
comment:
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
name: container_type
cast_type: *7
sql_type_metadata: *8
'null': false
default:
default_function:
collation:
comment:
- *5
- *6
- *9
events:
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
@@ -997,6 +1031,7 @@ primary_keys:
commands: id
comments: id
creators_filters:
entropy_configurations: id
events: id
filters: id
filters_stages:
@@ -1035,6 +1070,7 @@ data_sources:
commands: true
comments: true
creators_filters: true
entropy_configurations: true
events: true
filters: true
filters_stages: true
@@ -1447,22 +1483,6 @@ indexes:
comment:
valid: true
collections:
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
table: collections
name: index_collections_on_auto_close_period
unique: false
columns:
- auto_close_period
lengths: {}
orders: {}
opclasses: {}
where:
type:
using:
include:
nulls_not_distinct:
comment:
valid: true
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
table: collections
name: index_collections_on_creator_id
@@ -1646,6 +1666,60 @@ indexes:
nulls_not_distinct:
comment:
valid: true
entropy_configurations:
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
table: entropy_configurations
name: idx_on_container_type_container_id_auto_close_perio_74dc880875
unique: false
columns:
- container_type
- container_id
- auto_close_period
lengths: {}
orders: {}
opclasses: {}
where:
type:
using:
include:
nulls_not_distinct:
comment:
valid: true
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
table: entropy_configurations
name: idx_on_container_type_container_id_auto_reconsider__583aaddbea
unique: false
columns:
- container_type
- container_id
- auto_reconsider_period
lengths: {}
orders: {}
opclasses: {}
where:
type:
using:
include:
nulls_not_distinct:
comment:
valid: true
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
table: entropy_configurations
name: index_entropy_configurations_on_container
unique: true
columns:
- container_type
- container_id
lengths: {}
orders: {}
opclasses: {}
where:
type:
using:
include:
nulls_not_distinct:
comment:
valid: true
events:
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
table: events
@@ -2137,4 +2211,4 @@ indexes:
comment:
valid: true
workflows: []
version: 20250601161653
version: 20250604080022
-2
View File
@@ -2,11 +2,9 @@ writebook:
name: Writebook
creator: david
all_access: true
auto_close_period: <%= 30.days.to_i %>
workflow: qa
private:
name: Private collection
creator: kevin
all_access: false
auto_close_period: <%= 30.days.to_i %>
+9
View File
@@ -0,0 +1,9 @@
writebook_collection:
container: writebook (Collection)
auto_reconsider_period: <%= 30.days.to_i %>
auto_close_period: <%= 30.days.to_i %>
private_collection:
container: private (Collection)
auto_reconsider_period: <%= 30.days.to_i %>
auto_close_period: <%= 30.days.to_i %>
+4 -4
View File
@@ -8,7 +8,7 @@ class Card::EntropyTest < ActiveSupport::TestCase
test "auto_close_at infers the period from the collection" do
freeze_time
collections(:writebook).update! auto_close_period: 123.days
entropy_configurations(:writebook_collection).update! auto_close_period: 123.days
cards(:layout).update! last_active_at: 2.day.ago
assert_equal (123-2).days.from_now, cards(:layout).auto_close_at
end
@@ -16,8 +16,8 @@ class Card::EntropyTest < ActiveSupport::TestCase
test "auto close all due" do
cards(:logo, :shipping).each(&:reconsider)
cards(:logo).update!(last_active_at: 1.day.ago - collections(:writebook).auto_close_period)
cards(:shipping).update!(last_active_at: 1.day.from_now - collections(:writebook).auto_close_period)
cards(:logo).update!(last_active_at: 1.day.ago - entropy_configurations(:writebook_collection).auto_close_period)
cards(:shipping).update!(last_active_at: 1.day.from_now - entropy_configurations(:writebook_collection).auto_close_period)
assert_difference -> { Card.closed.count }, +1 do
Card.auto_close_all_due
@@ -30,7 +30,7 @@ class Card::EntropyTest < ActiveSupport::TestCase
test "don't auto close those cards where the collection has no auto close period" do
cards(:logo, :shipping).each(&:reconsider)
collections(:writebook).update auto_close_period: nil
collections(:writebook).entropy_configuration.destroy
assert_no_difference -> { Card.closed.count } do
Card.auto_close_all_due