diff --git a/_migrations/2022-09-17-053418_stripe_webhook_event_logs/up.sql b/_migrations/2022-09-17-053418_stripe_webhook_event_logs/up.sql index ee271db9e4..d5314035a5 100644 --- a/_migrations/2022-09-17-053418_stripe_webhook_event_logs/up.sql +++ b/_migrations/2022-09-17-053418_stripe_webhook_event_logs/up.sql @@ -1,7 +1,6 @@ -- noinspection SqlDialectInspectionForFile -- noinspection SqlNoDataSourceInspectionForFile -- noinspection SqlResolveForFile --- Current credit balances CREATE TABLE stripe_webhook_event_logs ( -- Not used for anything except replication. @@ -52,6 +51,8 @@ CREATE TABLE stripe_webhook_event_logs ( PRIMARY KEY (id), UNIQUE KEY (stripe_event_id), KEY index_stripe_event_type (stripe_event_type), + KEY index_maybe_stripe_event_entity_id (maybe_stripe_event_entity_id), + KEY index_maybe_stripe_customer_id (maybe_stripe_customer_id), KEY fk_maybe_user_token (maybe_user_token) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; diff --git a/_migrations/2022-09-17-173657_user_subscriptions/down.sql b/_migrations/2022-09-17-173657_user_subscriptions/down.sql new file mode 100644 index 0000000000..fcd49ee911 --- /dev/null +++ b/_migrations/2022-09-17-173657_user_subscriptions/down.sql @@ -0,0 +1,5 @@ +-- noinspection SqlDialectInspectionForFile +-- noinspection SqlNoDataSourceInspectionForFile +-- noinspection SqlResolveForFile + +drop table user_subscriptions; \ No newline at end of file diff --git a/_migrations/2022-09-17-173657_user_subscriptions/up.sql b/_migrations/2022-09-17-173657_user_subscriptions/up.sql new file mode 100644 index 0000000000..91c106f3e7 --- /dev/null +++ b/_migrations/2022-09-17-173657_user_subscriptions/up.sql @@ -0,0 +1,76 @@ +-- noinspection SqlDialectInspectionForFile +-- noinspection SqlNoDataSourceInspectionForFile +-- noinspection SqlResolveForFile + +CREATE TABLE user_subscriptions ( + -- Not used for anything except replication. + id BIGINT(20) NOT NULL AUTO_INCREMENT, + + -- Effective "primary key" (PUBLIC) + token VARCHAR(32) NOT NULL, + + -- ========== INTERNAL SUBSCRIPTION DETAILS ========== + + -- The internal user associated with the subscription. + user_token VARCHAR(32) DEFAULT NULL, + + -- If we host multiple sites with distinct categories, this will enable us to segregate subscriptions. + subscription_category VARCHAR(32) NOT NULL, + + -- This is the identifier for the actual type of subscription. + -- These will not be defined in the database, but rather the source code. + subscription_product_key VARCHAR(32) NOT NULL, + + -- ========== STRIPE DATA ========== + + -- The stripe IDs (nullable in case we can't associate or if we use paypal) + + -- You can safely assume object IDs we generate will never exceed 255 characters, + -- but you should be able to handle IDs of up to that length. If for example you’re using MySQL, + -- you should store IDs in a VARCHAR(255) COLLATE utf8_bin column (the COLLATE configuration ensures + -- case-sensitivity in lookups). + -- https://stackoverflow.com/a/61809494 + + -- When we receive a webhook update, we'll look it up by this key. + -- This has a UNIQUE index. + maybe_stripe_subscription_id VARCHAR(255) DEFAULT NULL, + + maybe_stripe_product_id VARCHAR(255) DEFAULT NULL, + + maybe_stripe_customer_id VARCHAR(255) DEFAULT NULL, + + maybe_stripe_is_production BOOLEAN DEFAULT NULL, + + -- ========== VECTOR CLOCK ========== + + -- Incremented with every update. + version INT NOT NULL DEFAULT 0, + + -- ========== RECORD TIMESTAMPS ========== + + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + deleted_at TIMESTAMP DEFAULT NULL, + + -- ========== SUBSCRIPTION TIMESTAMPS ========== + + subscription_created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + + -- We'll use this to determine if the subscription is active. + -- + -- Always compare against MySQL's clock rather than the app's clock so that we + -- don't get weird clock skew behaviors across multiple requests. + -- + -- Technically the user can have multiple active subscriptions of the same type, but we'll + -- try to prevent creation of new subscriptions of the same type. + subscription_expires_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + + -- ========== INDICES ========== + PRIMARY KEY (id), + UNIQUE KEY (token), + UNIQUE KEY (maybe_stripe_subscription_id), + KEY index_subscription_category (subscription_category), + KEY index_subscription_product_key (subscription_product_key), + KEY fk_user_token (user_token) + +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;