Switch to mysql
- trilogy adapter - lots of small migration changes - notably we lose the search tables which case lots of tests to fail
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
class CreateSearchIndexes < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
create_virtual_table :bubbles_search_index, "fts5", [ "title" ]
|
||||
create_virtual_table :comments_search_index, "fts5", [ "body" ]
|
||||
# # TODO:PLANB: need to replace SQLite FTS
|
||||
# create_virtual_table :bubbles_search_index, "fts5", [ "title" ]
|
||||
# create_virtual_table :comments_search_index, "fts5", [ "body" ]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@ class CreateEvents < ActiveRecord::Migration[8.0]
|
||||
create_table :events do |t|
|
||||
t.references :bubble, null: false, index: false
|
||||
t.references :creator, null: false
|
||||
t.json :particulars, default: {}
|
||||
t.column :particulars, :json, default: -> { '(JSON_OBJECT())' }
|
||||
t.string :action, null: false
|
||||
|
||||
t.timestamps
|
||||
|
||||
@@ -3,7 +3,7 @@ class CreateViews < ActiveRecord::Migration[8.0]
|
||||
create_table :bucket_views do |t|
|
||||
t.references :creator, null: false
|
||||
t.references :bucket, null: false
|
||||
t.json :filters, default: {}, null: false
|
||||
t.column :filters, :json, default: -> { '(JSON_OBJECT())' }, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
class MakeBucketViewFiltersUnique < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
add_index :bucket_views, %i[ bucket_id creator_id filters ], unique: true
|
||||
# MySQL doesn't support direct indexing of JSON columns. To ensure uniqueness
|
||||
# of the filters JSON content, we create a generated column that stores a SHA2
|
||||
# hash of the JSON data. This allows us to enforce that each creator can only
|
||||
# have one view per bucket with the same filter configuration.
|
||||
add_column :bucket_views, :filters_hash, :string, limit: 64, as: "SHA2(filters, 256)", stored: true
|
||||
add_index :bucket_views, %i[ bucket_id creator_id filters_hash ], unique: true
|
||||
remove_index :bucket_views, :bucket_id
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,15 +2,19 @@ class RenameBucketViewsToFilters < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
rename_table :bucket_views, :filters
|
||||
|
||||
remove_index :filters, %i[ bucket_id creator_id filters ], unique: true
|
||||
remove_index :filters, %i[ bucket_id creator_id filters_hash ], unique: true
|
||||
remove_index :filters, :creator_id
|
||||
remove_column :filters, :filters_hash, :string
|
||||
|
||||
remove_reference :filters, :bucket
|
||||
|
||||
rename_column :filters, :filters, :params
|
||||
|
||||
add_column :filters, :fields, :jsonb, null: false, default: {}
|
||||
add_column :filters, :fields, :json, null: false, default: -> { '(JSON_OBJECT())' }
|
||||
|
||||
add_index :filters, %i[ creator_id params ], unique: true
|
||||
# MySQL doesn't support direct indexing of JSON columns. Create a generated
|
||||
# hash column for the params JSON data to enforce uniqueness.
|
||||
add_column :filters, :params_hash, :string, limit: 64, as: "SHA2(params, 256)", stored: true
|
||||
add_index :filters, %i[ creator_id params_hash ], unique: true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
class HashFilterParams < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
change_column_default :filters, :params, from: {}, to: nil
|
||||
change_column :filters, :params, :string, null: false
|
||||
rename_column :filters, :params, :params_digest
|
||||
remove_index :filters, %i[ creator_id params_hash ], unique: true
|
||||
remove_column :filters, :params_hash
|
||||
remove_column :filters, :params
|
||||
|
||||
add_column :filters, :params_digest, :string, null: false
|
||||
add_index :filters, %i[ creator_id params_digest ], unique: true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
class MakeTaggingsUniquePerBubble < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
remove_index :taggings, :bubble_id
|
||||
# Add the composite index first, then remove the old single-column index.
|
||||
# MySQL requires an index for foreign key constraints, so we need the new
|
||||
# composite index in place before removing the old one.
|
||||
add_index :taggings, %i[ bubble_id tag_id ], unique: true
|
||||
remove_index :taggings, :bubble_id
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
class CreateActionTextMarkdowns < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
create_table :action_text_markdowns do |t|
|
||||
t.references :record, polymorphic: true, null: false
|
||||
t.string :name, null: false
|
||||
t.text :content, null: false, default: ""
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_column :active_storage_attachments, :slug, :string
|
||||
add_index :active_storage_attachments, :slug, unique: true
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
class AddStatusToBubbles < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
add_column :bubbles, :status, :text, default: :drafted, null: false
|
||||
add_column :bubbles, :status, :string, default: "drafted", null: false
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,12 +4,12 @@ class AssociateEventsWithBubbles < ActiveRecord::Migration[8.1]
|
||||
t.references :bubble, foreign_key: true
|
||||
end
|
||||
|
||||
# MySQL uses JOIN syntax for multi-table updates, not FROM clause
|
||||
execute "
|
||||
update events
|
||||
set bubble_id = m.bubble_id
|
||||
from event_summaries es
|
||||
join messages m on m.messageable_type = 'EventSummary' and m.messageable_id = es.id
|
||||
where events.summary_id = es.id
|
||||
join event_summaries es on events.summary_id = es.id
|
||||
join messages m on m.messageable_type = 'EventSummary' and m.messageable_id = es.id
|
||||
set events.bubble_id = m.bubble_id
|
||||
"
|
||||
|
||||
change_column_null :events, :bubble_id, false
|
||||
|
||||
@@ -4,15 +4,16 @@ class AddAutoPopAtToBubbles < ActiveRecord::Migration[8.1]
|
||||
t.datetime :auto_pop_at, index: true
|
||||
end
|
||||
|
||||
# MySQL uses JOIN syntax for multi-table updates and DATE_ADD for date arithmetic
|
||||
execute "
|
||||
update bubbles
|
||||
set auto_pop_at = datetime(activity.last_active_at, '+30 days')
|
||||
from (
|
||||
select bubbles.id as bubble_id, coalesce(max(events.created_at), bubbles.created_at) as last_active_at
|
||||
from bubbles
|
||||
left join events on bubbles.id = events.bubble_id group by bubbles.id
|
||||
) as activity
|
||||
where bubbles.id = activity.bubble_id
|
||||
join (
|
||||
select bubbles.id as bubble_id, coalesce(max(events.created_at), bubbles.created_at) as last_active_at
|
||||
from bubbles
|
||||
left join events on bubbles.id = events.bubble_id
|
||||
group by bubbles.id
|
||||
) as activity on bubbles.id = activity.bubble_id
|
||||
set bubbles.auto_pop_at = DATE_ADD(activity.last_active_at, INTERVAL 30 DAY)
|
||||
"
|
||||
|
||||
change_column_null :bubbles, :auto_pop_at, false
|
||||
|
||||
@@ -3,10 +3,12 @@ class DropSubscriptions < ActiveRecord::Migration[8.1]
|
||||
execute "
|
||||
update accesses set involvement = 'access_only'
|
||||
"
|
||||
# MySQL uses JOIN syntax for multi-table updates
|
||||
execute "
|
||||
update accesses set involvement = 'watching'
|
||||
from (select user_id, subscribable_id as bucket_id from subscriptions) as subscriptions
|
||||
where subscriptions.user_id = accesses.user_id and subscriptions.bucket_id = accesses.bucket_id
|
||||
update accesses
|
||||
join (select user_id, subscribable_id as bucket_id from subscriptions) as subscriptions
|
||||
on subscriptions.user_id = accesses.user_id and subscriptions.bucket_id = accesses.bucket_id
|
||||
set accesses.involvement = 'watching'
|
||||
"
|
||||
|
||||
drop_table :subscriptions
|
||||
|
||||
@@ -3,15 +3,16 @@ class AddLastActiveAtToBubbles < ActiveRecord::Migration[8.1]
|
||||
add_column :bubbles, :last_active_at, :datetime
|
||||
add_index :bubbles, %i[ last_active_at status ]
|
||||
|
||||
# MySQL uses JOIN syntax for multi-table updates
|
||||
execute <<~SQL
|
||||
update bubbles
|
||||
set last_active_at = activity.last_active_at
|
||||
from (
|
||||
select bubbles.id as bubble_id, coalesce(max(events.created_at), bubbles.created_at) as last_active_at
|
||||
from bubbles
|
||||
left join events on bubbles.id = events.bubble_id group by bubbles.id
|
||||
) as activity
|
||||
where bubbles.id = activity.bubble_id
|
||||
join (
|
||||
select bubbles.id as bubble_id, coalesce(max(events.created_at), bubbles.created_at) as last_active_at
|
||||
from bubbles
|
||||
left join events on bubbles.id = events.bubble_id
|
||||
group by bubbles.id
|
||||
) as activity on bubbles.id = activity.bubble_id
|
||||
set bubbles.last_active_at = activity.last_active_at
|
||||
SQL
|
||||
|
||||
change_column_null :bubbles, :last_active_at, false
|
||||
|
||||
@@ -24,30 +24,32 @@ class RenameBubblesToCards < ActiveRecord::Migration[8.1]
|
||||
rename_column "collections_filters", "bucket_id", "collection_id"
|
||||
|
||||
# Indexes
|
||||
rename_index "assignments", "index_assignments_on_bubble_id", "index_assignments_on_card_id"
|
||||
rename_index "card_engagements", "index_bubble_engagements_on_bubble_id", "index_card_engagements_on_card_id"
|
||||
rename_index "events", "index_events_on_bubble_id", "index_events_on_card_id"
|
||||
rename_index "messages", "index_messages_on_bubble_id", "index_messages_on_card_id"
|
||||
rename_index "notifications", "index_notifications_on_bubble_id", "index_notifications_on_card_id"
|
||||
rename_index "pins", "index_pins_on_bubble_id", "index_pins_on_card_id"
|
||||
rename_index "pins", "index_pins_on_bubble_id_and_user_id", "index_pins_on_card_id_and_user_id"
|
||||
rename_index "closures", "index_pops_on_bubble_id", "index_closures_on_card_id"
|
||||
rename_index "closures", "index_pops_on_bubble_id_and_created_at", "index_closures_on_card_id_and_created_at"
|
||||
rename_index "watches", "index_watches_on_bubble_id", "index_watches_on_card_id"
|
||||
rename_index "taggings", "index_taggings_on_bubble_id_and_tag_id", "index_taggings_on_card_id_and_tag_id"
|
||||
# # No longer necessary in MySQL
|
||||
# rename_index "assignments", "index_assignments_on_bubble_id", "index_assignments_on_card_id"
|
||||
# rename_index "card_engagements", "index_bubble_engagements_on_bubble_id", "index_card_engagements_on_card_id"
|
||||
# rename_index "events", "index_events_on_bubble_id", "index_events_on_card_id"
|
||||
# rename_index "messages", "index_messages_on_bubble_id", "index_messages_on_card_id"
|
||||
# rename_index "notifications", "index_notifications_on_bubble_id", "index_notifications_on_card_id"
|
||||
# rename_index "pins", "index_pins_on_bubble_id", "index_pins_on_card_id"
|
||||
# rename_index "pins", "index_pins_on_bubble_id_and_user_id", "index_pins_on_card_id_and_user_id"
|
||||
# rename_index "closures", "index_pops_on_bubble_id", "index_closures_on_card_id"
|
||||
# rename_index "closures", "index_pops_on_bubble_id_and_created_at", "index_closures_on_card_id_and_created_at"
|
||||
# rename_index "watches", "index_watches_on_bubble_id", "index_watches_on_card_id"
|
||||
# rename_index "taggings", "index_taggings_on_bubble_id_and_tag_id", "index_taggings_on_card_id_and_tag_id"
|
||||
|
||||
rename_index "accesses", "index_accesses_on_bucket_id", "index_accesses_on_collection_id"
|
||||
rename_index "accesses", "index_accesses_on_bucket_id_and_user_id", "index_accesses_on_collection_id_and_user_id"
|
||||
rename_index "collections_filters", "index_buckets_filters_on_bucket_id", "index_collections_filters_on_collection_id"
|
||||
# rename_index "accesses", "index_accesses_on_bucket_id", "index_accesses_on_collection_id"
|
||||
# rename_index "accesses", "index_accesses_on_bucket_id_and_user_id", "index_accesses_on_collection_id_and_user_id"
|
||||
# rename_index "collections_filters", "index_buckets_filters_on_bucket_id", "index_collections_filters_on_collection_id"
|
||||
|
||||
# Search tables
|
||||
execute <<~SQL
|
||||
CREATE VIRTUAL TABLE cards_search_index USING fts5(title);
|
||||
INSERT INTO cards_search_index(title) SELECT title FROM bubbles_search_index;
|
||||
SQL
|
||||
# # TODO:PLANB: need to replace SQLite FTS
|
||||
# execute <<~SQL
|
||||
# CREATE VIRTUAL TABLE cards_search_index USING fts5(title);
|
||||
# INSERT INTO cards_search_index(title) SELECT title FROM bubbles_search_index;
|
||||
# SQL
|
||||
|
||||
execute <<~SQL
|
||||
DROP TABLE bubbles_search_index;
|
||||
SQL
|
||||
# execute <<~SQL
|
||||
# DROP TABLE bubbles_search_index;
|
||||
# SQL
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@ class CreateCommands < ActiveRecord::Migration[8.1]
|
||||
create_table :commands do |t|
|
||||
t.references :user, null: false, foreign_key: true, index: true
|
||||
t.string :type
|
||||
t.json :data, default: {}
|
||||
t.column :data, :json, default: -> { '(JSON_OBJECT())' }
|
||||
|
||||
t.timestamps
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
class DropActionTextMarkdowns < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
drop_table :action_text_markdowns
|
||||
end
|
||||
end
|
||||
@@ -1,8 +1,9 @@
|
||||
class AddDescriptionToCardsSearchIndex < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
execute <<~SQL
|
||||
DROP TABLE cards_search_index;
|
||||
SQL
|
||||
create_virtual_table :cards_search_index, "fts5", [ "title", "description" ]
|
||||
# # TODO:PLANB: need to replace SQLite FTS
|
||||
# execute <<~SQL
|
||||
# DROP TABLE cards_search_index;
|
||||
# SQL
|
||||
# create_virtual_table :cards_search_index, "fts5", [ "title", "description" ]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,7 +6,10 @@ class CreateSearchQueries < ActiveRecord::Migration[8.1]
|
||||
|
||||
t.timestamps
|
||||
|
||||
t.index %i[ user_id terms ]
|
||||
# MySQL has a max key length of 3072 bytes. With utf8mb4 (4 bytes/char),
|
||||
# we can only index 768 characters. Using a 255 character prefix is
|
||||
# sufficient for search query lookups while staying well under the limit.
|
||||
t.index "user_id, terms(255)", name: "index_search_queries_on_user_id_and_terms"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
class AddStemming < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
drop_table :cards_search_index
|
||||
drop_table :comments_search_index
|
||||
# # TODO:PLANB: need to replace SQLite FTS
|
||||
# drop_table :cards_search_index
|
||||
# drop_table :comments_search_index
|
||||
|
||||
create_virtual_table "cards_search_index", "fts5", [ "title", "description", "tokenize='porter'" ]
|
||||
create_virtual_table "comments_search_index", "fts5", [ "body", "tokenize='porter'" ]
|
||||
# create_virtual_table "cards_search_index", "fts5", [ "title", "description", "tokenize='porter'" ]
|
||||
# create_virtual_table "comments_search_index", "fts5", [ "body", "tokenize='porter'" ]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@ class CreateEventActivitySummaries < ActiveRecord::Migration[8.1]
|
||||
create_table :event_activity_summaries do |t|
|
||||
t.string :key, null: false
|
||||
t.text :contents, null: false
|
||||
t.json :data, default: {}
|
||||
t.column :data, :json, default: -> { '(JSON_OBJECT())' }
|
||||
|
||||
t.timestamps
|
||||
|
||||
|
||||
@@ -4,10 +4,13 @@ class CreateWebhooks < ActiveRecord::Migration[8.1]
|
||||
t.boolean :active, default: true, null: false
|
||||
t.string :name
|
||||
t.text :url, null: false
|
||||
t.text :subscribed_actions, index: true
|
||||
t.text :subscribed_actions
|
||||
t.string :signing_secret, null: false
|
||||
|
||||
t.timestamps
|
||||
|
||||
# MySQL requires a prefix length for TEXT column indexes
|
||||
t.index "subscribed_actions(255)", name: "index_webhooks_on_subscribed_actions"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,9 +10,10 @@ class CreateAccountJoinCodes < ActiveRecord::Migration[8.1]
|
||||
|
||||
reversible do |dir|
|
||||
dir.up do
|
||||
# MySQL uses NOW() instead of SQLite's datetime('now')
|
||||
execute <<-SQL
|
||||
INSERT INTO account_join_codes (code, usage_count, usage_limit, created_at, updated_at)
|
||||
SELECT join_code, 0, 10, datetime('now'), datetime('now')
|
||||
SELECT join_code, 0, 10, NOW(), NOW()
|
||||
FROM accounts
|
||||
WHERE join_code IS NOT NULL;
|
||||
SQL
|
||||
|
||||
@@ -3,9 +3,10 @@ class MoveEmailToIdentity < ActiveRecord::Migration[8.1]
|
||||
add_column :identities, :email_address, :string
|
||||
|
||||
# Create identities for each unique email
|
||||
# MySQL uses NOW() instead of SQLite's datetime('now')
|
||||
execute <<-SQL
|
||||
INSERT INTO identities (email_address, created_at, updated_at)
|
||||
SELECT DISTINCT email_address, datetime('now'), datetime('now')
|
||||
SELECT DISTINCT email_address, NOW(), NOW()
|
||||
FROM memberships
|
||||
WHERE email_address IS NOT NULL
|
||||
AND email_address NOT IN (SELECT email_address FROM identities WHERE email_address IS NOT NULL);
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
class CreateIdentitySessions < ActiveRecord::Migration[8.2]
|
||||
def change
|
||||
create_table "sessions", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.references "identity", null: false, foreign_key: true
|
||||
t.string "ip_address"
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "user_agent"
|
||||
t.integer "identity_id", null: false
|
||||
t.index [ "identity_id" ], name: "index_sessions_on_identity_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
add_foreign_key "sessions", "identities"
|
||||
end
|
||||
end
|
||||
|
||||
+6
-4
@@ -1,13 +1,15 @@
|
||||
class AddUniqueConstraintOnIdentityIdAndTenantToMemberships < ActiveRecord::Migration[8.2]
|
||||
def change
|
||||
# Remove duplicates, keeping the youngest membership for each identity_id + tenant combination
|
||||
# MySQL doesn't allow referencing the target table in a subquery, so we use a JOIN approach
|
||||
execute <<-SQL
|
||||
DELETE FROM memberships
|
||||
WHERE id NOT IN (
|
||||
SELECT MAX(id)
|
||||
DELETE m1 FROM memberships m1
|
||||
LEFT JOIN (
|
||||
SELECT MAX(id) as max_id
|
||||
FROM memberships
|
||||
GROUP BY identity_id, tenant
|
||||
)
|
||||
) m2 ON m1.id = m2.max_id
|
||||
WHERE m2.max_id IS NULL
|
||||
SQL
|
||||
|
||||
add_index :memberships, %i[ tenant identity_id ], unique: true
|
||||
|
||||
Generated
+108
-115
@@ -11,20 +11,20 @@
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
create_table "accesses", force: :cascade do |t|
|
||||
create_table "accesses", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.datetime "accessed_at"
|
||||
t.integer "board_id", null: false
|
||||
t.bigint "board_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "involvement", default: "access_only", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "user_id", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["accessed_at"], name: "index_accesses_on_accessed_at", order: :desc
|
||||
t.index ["board_id", "user_id"], name: "index_accesses_on_board_id_and_user_id", unique: true
|
||||
t.index ["board_id"], name: "index_accesses_on_board_id"
|
||||
t.index ["user_id"], name: "index_accesses_on_user_id"
|
||||
end
|
||||
|
||||
create_table "account_join_codes", force: :cascade do |t|
|
||||
create_table "account_join_codes", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.string "code", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
@@ -33,7 +33,7 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["code"], name: "index_account_join_codes_on_code", unique: true
|
||||
end
|
||||
|
||||
create_table "accounts", force: :cascade do |t|
|
||||
create_table "accounts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "external_account_id"
|
||||
t.string "name", null: false
|
||||
@@ -41,8 +41,8 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["external_account_id"], name: "index_accounts_on_external_account_id", unique: true
|
||||
end
|
||||
|
||||
create_table "action_text_rich_texts", force: :cascade do |t|
|
||||
t.text "body"
|
||||
create_table "action_text_rich_texts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.text "body", size: :long
|
||||
t.datetime "created_at", null: false
|
||||
t.string "name", null: false
|
||||
t.bigint "record_id", null: false
|
||||
@@ -51,19 +51,17 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true
|
||||
end
|
||||
|
||||
create_table "active_storage_attachments", force: :cascade do |t|
|
||||
create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "blob_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "name", null: false
|
||||
t.bigint "record_id", null: false
|
||||
t.string "record_type", null: false
|
||||
t.string "slug"
|
||||
t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
|
||||
t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
|
||||
t.index ["slug"], name: "index_active_storage_attachments_on_slug", unique: true
|
||||
end
|
||||
|
||||
create_table "active_storage_blobs", force: :cascade do |t|
|
||||
create_table "active_storage_blobs", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "byte_size", null: false
|
||||
t.string "checksum"
|
||||
t.string "content_type"
|
||||
@@ -75,38 +73,38 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
|
||||
end
|
||||
|
||||
create_table "active_storage_variant_records", force: :cascade do |t|
|
||||
create_table "active_storage_variant_records", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "blob_id", null: false
|
||||
t.string "variation_digest", null: false
|
||||
t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
|
||||
end
|
||||
|
||||
create_table "assignees_filters", id: false, force: :cascade do |t|
|
||||
t.integer "assignee_id", null: false
|
||||
t.integer "filter_id", null: false
|
||||
create_table "assignees_filters", id: false, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "assignee_id", null: false
|
||||
t.bigint "filter_id", null: false
|
||||
t.index ["assignee_id"], name: "index_assignees_filters_on_assignee_id"
|
||||
t.index ["filter_id"], name: "index_assignees_filters_on_filter_id"
|
||||
end
|
||||
|
||||
create_table "assigners_filters", id: false, force: :cascade do |t|
|
||||
t.integer "assigner_id", null: false
|
||||
t.integer "filter_id", null: false
|
||||
create_table "assigners_filters", id: false, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "assigner_id", null: false
|
||||
t.bigint "filter_id", null: false
|
||||
t.index ["assigner_id"], name: "index_assigners_filters_on_assigner_id"
|
||||
t.index ["filter_id"], name: "index_assigners_filters_on_filter_id"
|
||||
end
|
||||
|
||||
create_table "assignments", force: :cascade do |t|
|
||||
t.integer "assignee_id", null: false
|
||||
create_table "assignments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "assignee_id", null: false
|
||||
t.integer "assigner_id", null: false
|
||||
t.integer "card_id", null: false
|
||||
t.bigint "card_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["assignee_id", "card_id"], name: "index_assignments_on_assignee_id_and_card_id", unique: true
|
||||
t.index ["card_id"], name: "index_assignments_on_card_id"
|
||||
end
|
||||
|
||||
create_table "board_publications", force: :cascade do |t|
|
||||
t.integer "board_id", null: false
|
||||
create_table "board_publications", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "board_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "key"
|
||||
t.datetime "updated_at", null: false
|
||||
@@ -114,31 +112,31 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["key"], name: "index_board_publications_on_key", unique: true
|
||||
end
|
||||
|
||||
create_table "boards", force: :cascade do |t|
|
||||
create_table "boards", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.boolean "all_access", default: false, null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "creator_id", null: false
|
||||
t.bigint "creator_id", null: false
|
||||
t.string "name", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["creator_id"], name: "index_boards_on_creator_id"
|
||||
end
|
||||
|
||||
create_table "boards_filters", id: false, force: :cascade do |t|
|
||||
t.integer "board_id", null: false
|
||||
t.integer "filter_id", null: false
|
||||
create_table "boards_filters", id: false, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "board_id", null: false
|
||||
t.bigint "filter_id", null: false
|
||||
t.index ["board_id"], name: "index_boards_filters_on_board_id"
|
||||
t.index ["filter_id"], name: "index_boards_filters_on_filter_id"
|
||||
end
|
||||
|
||||
create_table "card_activity_spikes", force: :cascade do |t|
|
||||
t.integer "card_id", null: false
|
||||
create_table "card_activity_spikes", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "card_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["card_id"], name: "index_card_activity_spikes_on_card_id"
|
||||
end
|
||||
|
||||
create_table "card_engagements", force: :cascade do |t|
|
||||
t.integer "card_id"
|
||||
create_table "card_engagements", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "card_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.string "status", default: "doing", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
@@ -146,30 +144,30 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["status"], name: "index_card_engagements_on_status"
|
||||
end
|
||||
|
||||
create_table "card_goldnesses", force: :cascade do |t|
|
||||
t.integer "card_id", null: false
|
||||
create_table "card_goldnesses", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "card_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["card_id"], name: "index_card_goldnesses_on_card_id", unique: true
|
||||
end
|
||||
|
||||
create_table "card_not_nows", force: :cascade do |t|
|
||||
t.integer "card_id", null: false
|
||||
create_table "card_not_nows", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "card_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "user_id"
|
||||
t.bigint "user_id"
|
||||
t.index ["card_id"], name: "index_card_not_nows_on_card_id", unique: true
|
||||
t.index ["user_id"], name: "index_card_not_nows_on_user_id"
|
||||
end
|
||||
|
||||
create_table "cards", force: :cascade do |t|
|
||||
t.integer "board_id", null: false
|
||||
t.integer "column_id"
|
||||
create_table "cards", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "board_id", null: false
|
||||
t.bigint "column_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "creator_id", null: false
|
||||
t.date "due_on"
|
||||
t.datetime "last_active_at", null: false
|
||||
t.text "status", default: "drafted", null: false
|
||||
t.string "status", default: "drafted", null: false
|
||||
t.string "title"
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["board_id"], name: "index_cards_on_board_id"
|
||||
@@ -177,25 +175,25 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["last_active_at", "status"], name: "index_cards_on_last_active_at_and_status"
|
||||
end
|
||||
|
||||
create_table "closers_filters", id: false, force: :cascade do |t|
|
||||
create_table "closers_filters", id: false, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.integer "closer_id", null: false
|
||||
t.integer "filter_id", null: false
|
||||
t.index ["closer_id"], name: "index_closers_filters_on_closer_id"
|
||||
t.index ["filter_id"], name: "index_closers_filters_on_filter_id"
|
||||
end
|
||||
|
||||
create_table "closures", force: :cascade do |t|
|
||||
t.integer "card_id", null: false
|
||||
create_table "closures", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "card_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "user_id"
|
||||
t.bigint "user_id"
|
||||
t.index ["card_id", "created_at"], name: "index_closures_on_card_id_and_created_at"
|
||||
t.index ["card_id"], name: "index_closures_on_card_id", unique: true
|
||||
t.index ["user_id"], name: "index_closures_on_user_id"
|
||||
end
|
||||
|
||||
create_table "columns", force: :cascade do |t|
|
||||
t.integer "board_id", null: false
|
||||
create_table "columns", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "board_id", null: false
|
||||
t.string "color", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "name", null: false
|
||||
@@ -205,24 +203,24 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["board_id"], name: "index_columns_on_board_id"
|
||||
end
|
||||
|
||||
create_table "comments", force: :cascade do |t|
|
||||
t.integer "card_id", null: false
|
||||
create_table "comments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "card_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "creator_id", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["card_id"], name: "index_comments_on_card_id"
|
||||
end
|
||||
|
||||
create_table "creators_filters", id: false, force: :cascade do |t|
|
||||
create_table "creators_filters", id: false, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.integer "creator_id", null: false
|
||||
t.integer "filter_id", null: false
|
||||
t.index ["creator_id"], name: "index_creators_filters_on_creator_id"
|
||||
t.index ["filter_id"], name: "index_creators_filters_on_filter_id"
|
||||
end
|
||||
|
||||
create_table "entropies", force: :cascade do |t|
|
||||
create_table "entropies", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "auto_postpone_period", default: 2592000, null: false
|
||||
t.integer "container_id", null: false
|
||||
t.bigint "container_id", null: false
|
||||
t.string "container_type", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
@@ -230,14 +228,14 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["container_type", "container_id"], name: "index_entropy_configurations_on_container", unique: true
|
||||
end
|
||||
|
||||
create_table "events", force: :cascade do |t|
|
||||
create_table "events", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.string "action", null: false
|
||||
t.integer "board_id", null: false
|
||||
t.bigint "board_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "creator_id", null: false
|
||||
t.integer "eventable_id", null: false
|
||||
t.bigint "creator_id", null: false
|
||||
t.bigint "eventable_id", null: false
|
||||
t.string "eventable_type", null: false
|
||||
t.json "particulars", default: {}
|
||||
t.json "particulars", default: -> { "(json_object())" }
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["action"], name: "index_events_on_summary_id_and_action"
|
||||
t.index ["board_id", "action", "created_at"], name: "index_events_on_board_id_and_action_and_created_at"
|
||||
@@ -246,43 +244,43 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["eventable_type", "eventable_id"], name: "index_events_on_eventable"
|
||||
end
|
||||
|
||||
create_table "filters", force: :cascade do |t|
|
||||
create_table "filters", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "creator_id", null: false
|
||||
t.json "fields", default: {}, null: false
|
||||
t.bigint "creator_id", null: false
|
||||
t.json "fields", default: -> { "(json_object())" }, null: false
|
||||
t.string "params_digest", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["creator_id", "params_digest"], name: "index_filters_on_creator_id_and_params_digest", unique: true
|
||||
end
|
||||
|
||||
create_table "filters_tags", id: false, force: :cascade do |t|
|
||||
t.integer "filter_id", null: false
|
||||
t.integer "tag_id", null: false
|
||||
create_table "filters_tags", id: false, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "filter_id", null: false
|
||||
t.bigint "tag_id", null: false
|
||||
t.index ["filter_id"], name: "index_filters_tags_on_filter_id"
|
||||
t.index ["tag_id"], name: "index_filters_tags_on_tag_id"
|
||||
end
|
||||
|
||||
create_table "identities", force: :cascade do |t|
|
||||
create_table "identities", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.string "email_address", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["email_address"], name: "index_identities_on_email_address", unique: true
|
||||
end
|
||||
|
||||
create_table "magic_links", force: :cascade do |t|
|
||||
create_table "magic_links", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.string "code", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "expires_at", null: false
|
||||
t.integer "identity_id"
|
||||
t.bigint "identity_id"
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["code"], name: "index_magic_links_on_code", unique: true
|
||||
t.index ["expires_at"], name: "index_magic_links_on_expires_at"
|
||||
t.index ["identity_id"], name: "index_magic_links_on_identity_id"
|
||||
end
|
||||
|
||||
create_table "memberships", force: :cascade do |t|
|
||||
create_table "memberships", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "identity_id", null: false
|
||||
t.bigint "identity_id", null: false
|
||||
t.string "join_code"
|
||||
t.string "tenant", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
@@ -291,11 +289,11 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["tenant"], name: "index_memberships_on_user_tenant_and_user_id"
|
||||
end
|
||||
|
||||
create_table "mentions", force: :cascade do |t|
|
||||
create_table "mentions", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "mentionee_id", null: false
|
||||
t.integer "mentioner_id", null: false
|
||||
t.integer "source_id", null: false
|
||||
t.bigint "mentionee_id", null: false
|
||||
t.bigint "mentioner_id", null: false
|
||||
t.bigint "source_id", null: false
|
||||
t.string "source_type", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["mentionee_id"], name: "index_mentions_on_mentionee_id"
|
||||
@@ -303,50 +301,50 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["source_type", "source_id"], name: "index_mentions_on_source"
|
||||
end
|
||||
|
||||
create_table "notification_bundles", force: :cascade do |t|
|
||||
create_table "notification_bundles", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "ends_at", null: false
|
||||
t.datetime "starts_at", null: false
|
||||
t.integer "status", default: 0, null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "user_id", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["ends_at", "status"], name: "index_notification_bundles_on_ends_at_and_status"
|
||||
t.index ["user_id", "starts_at", "ends_at"], name: "idx_on_user_id_starts_at_ends_at_7eae5d3ac5"
|
||||
t.index ["user_id", "status"], name: "index_notification_bundles_on_user_id_and_status"
|
||||
end
|
||||
|
||||
create_table "notifications", force: :cascade do |t|
|
||||
create_table "notifications", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "creator_id"
|
||||
t.bigint "creator_id"
|
||||
t.datetime "read_at"
|
||||
t.integer "source_id", null: false
|
||||
t.bigint "source_id", null: false
|
||||
t.string "source_type", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "user_id", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["creator_id"], name: "index_notifications_on_creator_id"
|
||||
t.index ["source_type", "source_id"], name: "index_notifications_on_source"
|
||||
t.index ["user_id", "read_at", "created_at"], name: "index_notifications_on_user_id_and_read_at_and_created_at", order: { read_at: :desc, created_at: :desc }
|
||||
t.index ["user_id"], name: "index_notifications_on_user_id"
|
||||
end
|
||||
|
||||
create_table "pins", force: :cascade do |t|
|
||||
t.integer "card_id", null: false
|
||||
create_table "pins", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "card_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "user_id", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["card_id", "user_id"], name: "index_pins_on_card_id_and_user_id", unique: true
|
||||
t.index ["card_id"], name: "index_pins_on_card_id"
|
||||
t.index ["user_id"], name: "index_pins_on_user_id"
|
||||
end
|
||||
|
||||
create_table "push_subscriptions", force: :cascade do |t|
|
||||
create_table "push_subscriptions", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.string "auth_key"
|
||||
t.datetime "created_at", null: false
|
||||
t.string "endpoint"
|
||||
t.string "p256dh_key"
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "user_agent"
|
||||
t.integer "user_id", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["endpoint", "p256dh_key", "auth_key"], name: "idx_on_endpoint_p256dh_key_auth_key_7553014576"
|
||||
t.index ["endpoint"], name: "index_push_subscriptions_on_endpoint"
|
||||
t.index ["user_agent"], name: "index_push_subscriptions_on_user_agent"
|
||||
@@ -354,7 +352,7 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["user_id"], name: "index_push_subscriptions_on_user_id"
|
||||
end
|
||||
|
||||
create_table "reactions", force: :cascade do |t|
|
||||
create_table "reactions", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.integer "comment_id", null: false
|
||||
t.string "content", limit: 16, null: false
|
||||
t.datetime "created_at", null: false
|
||||
@@ -364,32 +362,32 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["reacter_id"], name: "index_reactions_on_reacter_id"
|
||||
end
|
||||
|
||||
create_table "search_queries", force: :cascade do |t|
|
||||
create_table "search_queries", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.string "terms", limit: 2000, null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "user_id", null: false
|
||||
t.index ["user_id", "terms"], name: "index_search_queries_on_user_id_and_terms"
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["user_id", "terms"], name: "index_search_queries_on_user_id_and_terms", length: { terms: 255 }
|
||||
t.index ["user_id", "updated_at"], name: "index_search_queries_on_user_id_and_updated_at", unique: true
|
||||
t.index ["user_id"], name: "index_search_queries_on_user_id"
|
||||
end
|
||||
|
||||
create_table "search_results", force: :cascade do |t|
|
||||
create_table "search_results", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
create_table "sessions", force: :cascade do |t|
|
||||
create_table "sessions", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "identity_id", null: false
|
||||
t.bigint "identity_id", null: false
|
||||
t.string "ip_address"
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "user_agent"
|
||||
t.index ["identity_id"], name: "index_sessions_on_identity_id"
|
||||
end
|
||||
|
||||
create_table "steps", force: :cascade do |t|
|
||||
t.integer "card_id", null: false
|
||||
create_table "steps", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "card_id", null: false
|
||||
t.boolean "completed", default: false, null: false
|
||||
t.text "content", null: false
|
||||
t.datetime "created_at", null: false
|
||||
@@ -398,33 +396,33 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["card_id"], name: "index_steps_on_card_id"
|
||||
end
|
||||
|
||||
create_table "taggings", force: :cascade do |t|
|
||||
t.integer "card_id", null: false
|
||||
create_table "taggings", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "card_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "tag_id", null: false
|
||||
t.bigint "tag_id", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["card_id", "tag_id"], name: "index_taggings_on_card_id_and_tag_id", unique: true
|
||||
t.index ["tag_id"], name: "index_taggings_on_tag_id"
|
||||
end
|
||||
|
||||
create_table "tags", force: :cascade do |t|
|
||||
create_table "tags", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.string "title"
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["title"], name: "index_tags_on_title", unique: true
|
||||
end
|
||||
|
||||
create_table "user_settings", force: :cascade do |t|
|
||||
create_table "user_settings", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.integer "bundle_email_frequency", default: 0, null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "timezone_name"
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "user_id", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["user_id", "bundle_email_frequency"], name: "index_user_settings_on_user_id_and_bundle_email_frequency"
|
||||
t.index ["user_id"], name: "index_user_settings_on_user_id"
|
||||
end
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
create_table "users", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.boolean "active", default: true, null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "membership_id"
|
||||
@@ -435,41 +433,41 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.index ["role"], name: "index_users_on_role"
|
||||
end
|
||||
|
||||
create_table "watches", force: :cascade do |t|
|
||||
t.integer "card_id", null: false
|
||||
create_table "watches", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "card_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "user_id", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.boolean "watching", default: true, null: false
|
||||
t.index ["card_id"], name: "index_watches_on_card_id"
|
||||
t.index ["user_id", "card_id"], name: "index_watches_on_user_id_and_card_id"
|
||||
t.index ["user_id"], name: "index_watches_on_user_id"
|
||||
end
|
||||
|
||||
create_table "webhook_delinquency_trackers", force: :cascade do |t|
|
||||
create_table "webhook_delinquency_trackers", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.integer "consecutive_failures_count", default: 0
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "first_failure_at"
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "webhook_id", null: false
|
||||
t.bigint "webhook_id", null: false
|
||||
t.index ["webhook_id"], name: "index_webhook_delinquency_trackers_on_webhook_id"
|
||||
end
|
||||
|
||||
create_table "webhook_deliveries", force: :cascade do |t|
|
||||
create_table "webhook_deliveries", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "event_id", null: false
|
||||
t.bigint "event_id", null: false
|
||||
t.text "request"
|
||||
t.text "response"
|
||||
t.string "state", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "webhook_id", null: false
|
||||
t.bigint "webhook_id", null: false
|
||||
t.index ["event_id"], name: "index_webhook_deliveries_on_event_id"
|
||||
t.index ["webhook_id"], name: "index_webhook_deliveries_on_webhook_id"
|
||||
end
|
||||
|
||||
create_table "webhooks", force: :cascade do |t|
|
||||
create_table "webhooks", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.boolean "active", default: true, null: false
|
||||
t.integer "board_id", null: false
|
||||
t.bigint "board_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "name"
|
||||
t.string "signing_secret", null: false
|
||||
@@ -477,7 +475,7 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
t.datetime "updated_at", null: false
|
||||
t.text "url", null: false
|
||||
t.index ["board_id"], name: "index_webhooks_on_board_id"
|
||||
t.index ["subscribed_actions"], name: "index_webhooks_on_subscribed_actions"
|
||||
t.index ["subscribed_actions"], name: "index_webhooks_on_subscribed_actions", length: 255
|
||||
end
|
||||
|
||||
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
||||
@@ -515,9 +513,4 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_06_154151) do
|
||||
add_foreign_key "webhook_deliveries", "events"
|
||||
add_foreign_key "webhook_deliveries", "webhooks"
|
||||
add_foreign_key "webhooks", "boards"
|
||||
|
||||
# Virtual tables defined in this database.
|
||||
# Note that virtual tables may not work with other database engines. Be careful if changing database.
|
||||
create_virtual_table "cards_search_index", "fts5", ["title", "description", "tokenize='porter'"]
|
||||
create_virtual_table "comments_search_index", "fts5", ["body", "tokenize='porter'"]
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user