Skip to content

Commit 10ad303

Browse files
committed
subscription migrations
1 parent 001a957 commit 10ad303

7 files changed

Lines changed: 462 additions & 4 deletions

engine/db/migrate/019_create_inner_performance_events.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
# frozen_string_literal: true
22

3+
# Creates the legacy inner_performance_events table. Guarded with
4+
# `unless table_exists?` so it runs cleanly whether or not the table is already
5+
# present (the engine and its migrations are shared by multiple apps, and these
6+
# transient telemetry tables are later dropped by migrations 023/024 and so are
7+
# absent from the final schema).
38
class CreateInnerPerformanceEvents < ActiveRecord::Migration[8.1]
4-
def change
9+
def up
10+
return if table_exists?(:inner_performance_events)
11+
512
create_table :inner_performance_events, force: :cascade do |t|
613
t.string :event
714
t.string :name
@@ -13,4 +20,8 @@ def change
1320
t.string :type
1421
end
1522
end
23+
24+
def down
25+
drop_table :inner_performance_events, if_exists: true
26+
end
1627
end

engine/db/migrate/020_create_inner_performance_traces.rb

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
# frozen_string_literal: true
22

3+
# Creates the legacy inner_performance_traces table (foreign key to
4+
# inner_performance_events). Guarded so it runs cleanly on databases where the
5+
# traces table already exists or the events table is absent — these transient
6+
# telemetry tables are dropped by migrations 023/024 and so never appear in the
7+
# final schema. Mirrors the defensive style of those drop migrations.
38
class CreateInnerPerformanceTraces < ActiveRecord::Migration[8.1]
4-
def change
9+
def up
10+
return if table_exists?(:inner_performance_traces)
11+
# Can't add the foreign key if the referenced table was never created (e.g.
12+
# a database that skipped or never ran migration 019). The table is dropped
13+
# downstream anyway, so safely no-op.
14+
return unless table_exists?(:inner_performance_events)
15+
516
create_table :inner_performance_traces do |t|
617
t.references :event, type: :bigint, null: false, foreign_key: {to_table: :inner_performance_events}
718
t.string :name
@@ -12,4 +23,8 @@ def change
1223
t.timestamps
1324
end
1425
end
26+
27+
def down
28+
drop_table :inner_performance_traces, if_exists: true
29+
end
1530
end
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# frozen_string_literal: true
2+
3+
class AddBillingToAccounts < ActiveRecord::Migration[8.1]
4+
def up
5+
add_column :accounts, :trial_ends_on, :date
6+
add_column :accounts, :stripe_customer_id, :string
7+
add_column :accounts, :stripe_subscription_id, :string
8+
add_column :accounts, :subscription_status, :string
9+
add_column :accounts, :subscription_current_period_end, :datetime
10+
add_column :accounts, :stripe_base_item_id, :string
11+
add_column :accounts, :stripe_additional_item_id, :string
12+
13+
add_index :accounts, :stripe_customer_id, unique: true
14+
add_index :accounts, :stripe_subscription_id, unique: true
15+
16+
# Backfill trial_ends_on from each account's owner user's trial_started_on + 60 days.
17+
execute(<<~SQL.squish)
18+
UPDATE accounts
19+
SET trial_ends_on = users.trial_started_on + INTERVAL '60 days'
20+
FROM account_users
21+
JOIN users ON users.id = account_users.user_id
22+
WHERE account_users.account_id = accounts.id
23+
AND account_users.role = 'owner'
24+
AND users.trial_started_on IS NOT NULL
25+
SQL
26+
27+
# Any account still without an end date gets a 60-day trial from today.
28+
execute(<<~SQL.squish)
29+
UPDATE accounts
30+
SET trial_ends_on = CURRENT_DATE + INTERVAL '60 days'
31+
WHERE trial_ends_on IS NULL
32+
SQL
33+
34+
remove_column :users, :trial_started_on
35+
end
36+
37+
def down
38+
add_column :users, :trial_started_on, :date
39+
40+
remove_index :accounts, :stripe_subscription_id
41+
remove_index :accounts, :stripe_customer_id
42+
43+
remove_column :accounts, :stripe_additional_item_id
44+
remove_column :accounts, :stripe_base_item_id
45+
remove_column :accounts, :subscription_current_period_end
46+
remove_column :accounts, :subscription_status
47+
remove_column :accounts, :stripe_subscription_id
48+
remove_column :accounts, :stripe_customer_id
49+
remove_column :accounts, :trial_ends_on
50+
end
51+
end
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# frozen_string_literal: true
2+
3+
class AddSubscriptionGraceToAccounts < ActiveRecord::Migration[8.1]
4+
def change
5+
add_column :accounts, :subscription_grace_until, :datetime
6+
end
7+
end
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# frozen_string_literal: true
2+
3+
# Switches billing from two separate prices (base + additional line items) to a
4+
# single tiered price with one subscription line item whose quantity is the
5+
# account's device count. Collapses the two item-id columns into one.
6+
class CollapseSubscriptionItemColumns < ActiveRecord::Migration[8.1]
7+
def up
8+
rename_column :accounts, :stripe_base_item_id, :stripe_subscription_item_id
9+
remove_column :accounts, :stripe_additional_item_id
10+
end
11+
12+
def down
13+
add_column :accounts, :stripe_additional_item_id, :string
14+
rename_column :accounts, :stripe_subscription_item_id, :stripe_base_item_id
15+
end
16+
end

engine/db/schema.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[8.1].define(version: 25) do
13+
ActiveRecord::Schema[8.1].define(version: 28) do
1414
# These are extensions that must be enabled in order to support this database
1515
enable_extension "pg_catalog.plpgsql"
1616
enable_extension "pgcrypto"
@@ -32,9 +32,18 @@
3232
t.text "name", null: false
3333
t.string "precipitation_unit", default: "in", null: false
3434
t.string "speed_unit", default: "mph", null: false
35+
t.string "stripe_customer_id"
36+
t.string "stripe_subscription_id"
37+
t.string "stripe_subscription_item_id"
38+
t.datetime "subscription_current_period_end"
39+
t.datetime "subscription_grace_until"
40+
t.string "subscription_status"
3541
t.datetime "support_access_at"
3642
t.string "temperature_unit", default: "F", null: false
43+
t.date "trial_ends_on"
3744
t.datetime "updated_at", null: false
45+
t.index ["stripe_customer_id"], name: "index_accounts_on_stripe_customer_id", unique: true
46+
t.index ["stripe_subscription_id"], name: "index_accounts_on_stripe_subscription_id", unique: true
3847
end
3948

4049
create_table "apple_accounts", force: :cascade do |t|
@@ -308,7 +317,6 @@
308317
t.datetime "login_code_sent_at"
309318
t.datetime "remember_created_at"
310319
t.text "remember_token"
311-
t.date "trial_started_on"
312320
t.datetime "updated_at", null: false
313321
t.index ["email"], name: "index_users_on_email", unique: true
314322
end

0 commit comments

Comments
 (0)