Skip to content

Increase quantity for Gitlab.com DuoPro trials

Hold off on the merge until we get a confirm per comment

What does this MR do and why?

Part of issue https://gitlab.com/gitlab-org/customers-gitlab-com/-/issues/9493+

Increase quantity for Gitlab.com Duo Pro trials

Prior to this change, Gitlab.com Duo Pro trials were provisioned with 50 seats. There's been an increasing number of requests from customer-facing team members for a higher quantity of users since the launch of the Duo Pro trials.

This is the 3nd MR for the whole issue:

  1. increase default quantity of seats for Gitlab.com Duo Pro trials : MR https://gitlab.com/gitlab-org/customers-gitlab-com/-/merge_requests/9973+
  2. migrate active Gitlab.com DuoPro trials order's quantity to 100 in CustomersDot database: MR https://gitlab.com/gitlab-org/customers-gitlab-com/-/merge_requests/9985+
  3. migrate active Gitlab.com DuoPro trials subscription_add_on_purchases.quantity to 100 in Gitlab database: Increase quantity for Gitlab.com DuoPro trials (!152629 - merged) -- THIS MR
Migrate up output
qingyuzhao@bcd0740929d1 gitlab % rails db:migrate:main
main: == [advisory_lock_connection] object_id: 124900, pg_backend_pid: 53357
main: == 20240510125400 IncreaseQuantityForGitlabcomDuoProTrials: migrating =========
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- exec_query("SELECT COUNT(*) AS count FROM \"subscription_add_on_purchases\" WHERE \"subscription_add_on_purchases\".\"subscription_add_on_id\" = 1 AND \"subscription_add_on_purchases\".\"trial\" = TRUE AND \"subscription_add_on_purchases\".\"expires_on\" >= '2024-05-10'")
main:    -> 0.0007s
main: -- exec_query("SELECT \"subscription_add_on_purchases\".\"id\" FROM \"subscription_add_on_purchases\" WHERE \"subscription_add_on_purchases\".\"subscription_add_on_id\" = 1 AND \"subscription_add_on_purchases\".\"trial\" = TRUE AND \"subscription_add_on_purchases\".\"expires_on\" >= '2024-05-10' ORDER BY \"subscription_add_on_purchases\".\"id\" ASC LIMIT 1")
main:    -> 0.0003s
main: -- exec_query("SELECT \"subscription_add_on_purchases\".\"id\" FROM \"subscription_add_on_purchases\" WHERE \"subscription_add_on_purchases\".\"id\" >= 35 AND \"subscription_add_on_purchases\".\"subscription_add_on_id\" = 1 AND \"subscription_add_on_purchases\".\"trial\" = TRUE AND \"subscription_add_on_purchases\".\"expires_on\" >= '2024-05-10' ORDER BY \"subscription_add_on_purchases\".\"id\" ASC LIMIT 1 OFFSET 1")
main:    -> 0.0003s
main: -- transaction(nil)
main: -- execute("UPDATE \"subscription_add_on_purchases\" SET \"quantity\" = 100 WHERE \"subscription_add_on_purchases\".\"id\" >= 35 AND \"subscription_add_on_purchases\".\"id\" < 37 AND \"subscription_add_on_purchases\".\"subscription_add_on_id\" = 1 AND \"subscription_add_on_purchases\".\"trial\" = TRUE AND \"subscription_add_on_purchases\".\"expires_on\" >= '2024-05-10'")
main:    -> 0.0011s
main:    -> 0.0026s
main: -- exec_query("SELECT \"subscription_add_on_purchases\".\"id\" FROM \"subscription_add_on_purchases\" WHERE \"subscription_add_on_purchases\".\"id\" >= 37 AND \"subscription_add_on_purchases\".\"subscription_add_on_id\" = 1 AND \"subscription_add_on_purchases\".\"trial\" = TRUE AND \"subscription_add_on_purchases\".\"expires_on\" >= '2024-05-10' ORDER BY \"subscription_add_on_purchases\".\"id\" ASC LIMIT 1 OFFSET 1")
main:    -> 0.0003s
main: -- transaction(nil)
main: -- execute("UPDATE \"subscription_add_on_purchases\" SET \"quantity\" = 100 WHERE \"subscription_add_on_purchases\".\"id\" >= 37 AND \"subscription_add_on_purchases\".\"id\" < 38 AND \"subscription_add_on_purchases\".\"subscription_add_on_id\" = 1 AND \"subscription_add_on_purchases\".\"trial\" = TRUE AND \"subscription_add_on_purchases\".\"expires_on\" >= '2024-05-10'")
main:    -> 0.0004s
main:    -> 0.0006s
main: -- exec_query("SELECT \"subscription_add_on_purchases\".\"id\" FROM \"subscription_add_on_purchases\" WHERE \"subscription_add_on_purchases\".\"id\" >= 38 AND \"subscription_add_on_purchases\".\"subscription_add_on_id\" = 1 AND \"subscription_add_on_purchases\".\"trial\" = TRUE AND \"subscription_add_on_purchases\".\"expires_on\" >= '2024-05-10' ORDER BY \"subscription_add_on_purchases\".\"id\" ASC LIMIT 1 OFFSET 1")
main:    -> 0.0003s
main: -- transaction(nil)
main: -- execute("UPDATE \"subscription_add_on_purchases\" SET \"quantity\" = 100 WHERE \"subscription_add_on_purchases\".\"id\" >= 38 AND \"subscription_add_on_purchases\".\"subscription_add_on_id\" = 1 AND \"subscription_add_on_purchases\".\"trial\" = TRUE AND \"subscription_add_on_purchases\".\"expires_on\" >= '2024-05-10'")
main:    -> 0.0004s
main:    -> 0.0005s
main: == 20240510125400 IncreaseQuantityForGitlabcomDuoProTrials: migrated (0.0282s)

main: == [advisory_lock_connection] object_id: 124900, pg_backend_pid: 53357
qingyuzhao@bcd0740929d1 gitlab %
Rollback output
qingyuzhao@bcd0740929d1 gitlab % rails db:rollback:main
main: == [advisory_lock_connection] object_id: 124600, pg_backend_pid: 64498
main: == 20240510125400 IncreaseQuantityForGitlabcomDuoProTrials: reverting =========
main: == 20240510125400 IncreaseQuantityForGitlabcomDuoProTrials: reverted (0.0031s)

main: == [advisory_lock_connection] object_id: 124600, pg_backend_pid: 64498

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Screenshots or screen recordings

Screenshots are required for UI changes, and strongly recommended for all other merge requests.

Before After

How to set up and validate locally

I've done testing on my local development environment, with the following steps:

  1. Start Gitlab and CustomersDot application
  2. Create several groups in Gitlab. Apply either paid base plan(premium, ultimate, etc) or ultimate_trial plan on those groups. And then apply DuoPro trial on these groups. That will give us some records in GitlabSubscriptions::AddOnPurchase table.
  3. Before run migration script, in Gitlab rails console, find the active DuoPro trial records
My local test result

Non-duopro addons records:

[41] pry(main)> GitlabSubscriptions::AddOnPurchase.where.not(subscription_add_on_id: duo_pro_addon_id)
  GitlabSubscriptions::AddOnPurchase Load (0.3ms)  SELECT "subscription_add_on_purchases".* FROM "subscription_add_on_purchases" WHERE "subscription_add_on_purchases"."subscription_add_on_id" != 1 /*application:console,db_config_name:main,console_hostname:bcd0740929d1,console_username:qingyuzhao,line:bin/rails:4:in `<main>'*/
=> [#<GitlabSubscriptions::AddOnPurchase:0x0000000118d81f58 id: 1, created_at: Mon, 22 Jan 2024 09:29:07.020683000 UTC +00:00, updated_at: Wed, 01 May 2024 11:52:28.693043000 UTC +00:00, subscription_add_on_id: 2, namespace_id: 51, quantity: 3, expires_on: Wed, 05 Feb 2025, purchase_xid: "A-S00475218", last_assigned_users_refreshed_at: nil, trial: false>,
 #<GitlabSubscriptions::AddOnPurchase:0x0000000118d81e18 id: 2, created_at: Mon, 12 Feb 2024 01:54:36.390004000 UTC +00:00, updated_at: Fri, 10 May 2024 13:07:57.371128000 UTC +00:00, subscription_add_on_id: 2, namespace_id: 76, quantity: 20, expires_on: Wed, 13 Mar 2024, purchase_xid: "trial-order-74", last_assigned_users_refreshed_at: nil, trial: false>]
[42] pry(main)>

Expired DuoPro addon records:

[43] pry(main)> GitlabSubscriptions::AddOnPurchase.where(subscription_add_on_id: duo_pro_addon_id).where(trial: true).where('expires_on < ?', Date.current).order(:id)
  GitlabSubscriptions::AddOnPurchase Load (0.5ms)  SELECT "subscription_add_on_purchases".* FROM "subscription_add_on_purchases" WHERE "subscription_add_on_purchases"."subscription_add_on_id" = 1 AND "subscription_add_on_purchases"."trial" = TRUE AND (expires_on < '2024-05-10') ORDER BY "subscription_add_on_purchases"."id" ASC /*application:console,db_config_name:main,console_hostname:bcd0740929d1,console_username:qingyuzhao,line:bin/rails:4:in `<main>'*/
=> [#<GitlabSubscriptions::AddOnPurchase:0x0000000118d6c810 id: 22, created_at: Thu, 21 Mar 2024 07:12:24.873140000 UTC +00:00, updated_at: Fri, 10 May 2024 13:06:18.614547000 UTC +00:00, subscription_add_on_id: 1, namespace_id: 78, quantity: 50, expires_on: Sat, 20 Apr 2024, purchase_xid: "trial-order-115", last_assigned_users_refreshed_at: nil, trial: true>]
[44] pry(main)>

Active DuoPro addon trial records:

[46] pry(main)> GitlabSubscriptions::AddOnPurchase.where(subscription_add_on_id: duo_pro_addon_id).where(trial: true).where('expires_on >= ?', Date.current).order(:id)
  GitlabSubscriptions::AddOnPurchase Load (0.5ms)  SELECT "subscription_add_on_purchases".* FROM "subscription_add_on_purchases" WHERE "subscription_add_on_purchases"."subscription_add_on_id" = 1 AND "subscription_add_on_purchases"."trial" = TRUE AND (expires_on >= '2024-05-10') ORDER BY "subscription_add_on_purchases"."id" ASC /*application:console,db_config_name:main,console_hostname:bcd0740929d1,console_username:qingyuzhao,line:bin/rails:4:in `<main>'*/
=> [#<GitlabSubscriptions::AddOnPurchase:0x0000000118d676d0 id: 35, created_at: Thu, 18 Apr 2024 03:17:27.236085000 UTC +00:00, updated_at: Thu, 02 May 2024 11:02:21.659822000 UTC +00:00, subscription_add_on_id: 1, namespace_id: 107, quantity: 50, expires_on: Mon, 17 Jun 2024, purchase_xid: "trial-order-132", last_assigned_users_refreshed_at: nil, trial: true>,
 #<GitlabSubscriptions::AddOnPurchase:0x0000000118d67590 id: 37, created_at: Wed, 01 May 2024 10:34:43.551242000 UTC +00:00, updated_at: Wed, 01 May 2024 10:34:43.551242000 UTC +00:00, subscription_add_on_id: 1, namespace_id: 111, quantity: 50, expires_on: Sun, 30 Jun 2024, purchase_xid: "trial-order-136", last_assigned_users_refreshed_at: nil, trial: true>,
 #<GitlabSubscriptions::AddOnPurchase:0x0000000118d67450 id: 38, created_at: Fri, 10 May 2024 07:57:26.728029000 UTC +00:00, updated_at: Fri, 10 May 2024 07:57:26.728029000 UTC +00:00, subscription_add_on_id: 1, namespace_id: 113, quantity: 100, expires_on: Tue, 09 Jul 2024, purchase_xid: "trial-order-139", last_assigned_users_refreshed_at: nil, trial: true>]
[47] pry(main)>
  1. Run the migration script rails db:migrate. It succeed.
  2. In Gitlab rails console, check the active DuoPro trial records again. The 30 days duration record is extended to 60 days.
My local test result

Non-duopro addons records, they are NOT changed:

[52] pry(main)> GitlabSubscriptions::AddOnPurchase.where.not(subscription_add_on_id: duo_pro_addon_id)
  GitlabSubscriptions::AddOnPurchase Load (0.3ms)  SELECT "subscription_add_on_purchases".* FROM "subscription_add_on_purchases" WHERE "subscription_add_on_purchases"."subscription_add_on_id" != 1 /*application:console,db_config_name:main,console_hostname:bcd0740929d1,console_username:qingyuzhao,line:bin/rails:4:in `<main>'*/
=> [#<GitlabSubscriptions::AddOnPurchase:0x0000000118d4b548 id: 1, created_at: Mon, 22 Jan 2024 09:29:07.020683000 UTC +00:00, updated_at: Wed, 01 May 2024 11:52:28.693043000 UTC +00:00, subscription_add_on_id: 2, namespace_id: 51, quantity: 3, expires_on: Wed, 05 Feb 2025, purchase_xid: "A-S00475218", last_assigned_users_refreshed_at: nil, trial: false>,
 #<GitlabSubscriptions::AddOnPurchase:0x0000000118d4b408 id: 2, created_at: Mon, 12 Feb 2024 01:54:36.390004000 UTC +00:00, updated_at: Fri, 10 May 2024 13:07:57.371128000 UTC +00:00, subscription_add_on_id: 2, namespace_id: 76, quantity: 20, expires_on: Wed, 13 Mar 2024, purchase_xid: "trial-order-74", last_assigned_users_refreshed_at: nil, trial: false>]
[53] pry(main)>

Expired duopro trials, the quantity is NOT changed either:

[54] pry(main)> GitlabSubscriptions::AddOnPurchase.where(subscription_add_on_id: duo_pro_addon_id).where(trial: true).where('expires_on < ?', Date.current).order(:id)
  GitlabSubscriptions::AddOnPurchase Load (0.3ms)  SELECT "subscription_add_on_purchases".* FROM "subscription_add_on_purchases" WHERE "subscription_add_on_purchases"."subscription_add_on_id" = 1 AND "subscription_add_on_purchases"."trial" = TRUE AND (expires_on < '2024-05-10') ORDER BY "subscription_add_on_purchases"."id" ASC /*application:console,db_config_name:main,console_hostname:bcd0740929d1,console_username:qingyuzhao,line:bin/rails:4:in `<main>'*/
=> [#<GitlabSubscriptions::AddOnPurchase:0x0000000118d45f08 id: 22, created_at: Thu, 21 Mar 2024 07:12:24.873140000 UTC +00:00, updated_at: Fri, 10 May 2024 13:06:18.614547000 UTC +00:00, subscription_add_on_id: 1, namespace_id: 78, quantity: 50, expires_on: Sat, 20 Apr 2024, purchase_xid: "trial-order-115", last_assigned_users_refreshed_at: nil, trial: true>]
[55] pry(main)>

Active DuoPro trials, the quantity are all 100 now:

[56] pry(main)> GitlabSubscriptions::AddOnPurchase.where(subscription_add_on_id: duo_pro_addon_id).where(trial: true).where('expires_on >= ?', Date.current).order(:id)
  GitlabSubscriptions::AddOnPurchase Load (0.3ms)  SELECT "subscription_add_on_purchases".* FROM "subscription_add_on_purchases" WHERE "subscription_add_on_purchases"."subscription_add_on_id" = 1 AND "subscription_add_on_purchases"."trial" = TRUE AND (expires_on >= '2024-05-10') ORDER BY "subscription_add_on_purchases"."id" ASC /*application:console,db_config_name:main,console_hostname:bcd0740929d1,console_username:qingyuzhao,line:bin/rails:4:in `<main>'*/
=> [#<GitlabSubscriptions::AddOnPurchase:0x0000000118d40dc8 id: 35, created_at: Thu, 18 Apr 2024 03:17:27.236085000 UTC +00:00, updated_at: Thu, 02 May 2024 11:02:21.659822000 UTC +00:00, subscription_add_on_id: 1, namespace_id: 107, quantity: 100, expires_on: Mon, 17 Jun 2024, purchase_xid: "trial-order-132", last_assigned_users_refreshed_at: nil, trial: true>,
 #<GitlabSubscriptions::AddOnPurchase:0x0000000118d40c88 id: 37, created_at: Wed, 01 May 2024 10:34:43.551242000 UTC +00:00, updated_at: Wed, 01 May 2024 10:34:43.551242000 UTC +00:00, subscription_add_on_id: 1, namespace_id: 111, quantity: 100, expires_on: Sun, 30 Jun 2024, purchase_xid: "trial-order-136", last_assigned_users_refreshed_at: nil, trial: true>,
 #<GitlabSubscriptions::AddOnPurchase:0x0000000118d40b48 id: 38, created_at: Fri, 10 May 2024 07:57:26.728029000 UTC +00:00, updated_at: Fri, 10 May 2024 07:57:26.728029000 UTC +00:00, subscription_add_on_id: 1, namespace_id: 113, quantity: 100, expires_on: Tue, 09 Jul 2024, purchase_xid: "trial-order-139", last_assigned_users_refreshed_at: nil, trial: true>]
[57] pry(main)>
Edited by Qingyu Zhao

Merge request reports