@spytecgps/nova-orm 1.4.298 → 1.4.299
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,21 +1,38 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* `purchased` is appended rather than slotted in next to `invited` where it belongs logically. MySQL
|
|
3
|
+
* stores an enum by its index, so inserting a value mid-list shifts every later value and forces a
|
|
4
|
+
* table rebuild; appending is an in-place change. Display ordering is the UI's job.
|
|
5
|
+
*/
|
|
6
|
+
declare const statusArray: readonly ["invited", "attributed", "active", "qualified", "credited", "canceled", "voided", "purchased"];
|
|
2
7
|
export type ReferralStatus = (typeof statusArray)[number];
|
|
3
8
|
declare const voidReasonArray: readonly ["refund", "cancelled_early", "self_referral", "fraud", "existing_active_customer", "referrer_ineligible", "attribution_expired", "annual_cap_reached"];
|
|
4
9
|
export type ReferralVoidReason = (typeof voidReasonArray)[number];
|
|
10
|
+
/**
|
|
11
|
+
* Which link the referral arrived on. `manual` is reserved for the deferred code-entry field — no
|
|
12
|
+
* code writes it yet.
|
|
13
|
+
*/
|
|
14
|
+
declare const sourceArray: readonly ["activation", "store", "manual"];
|
|
15
|
+
export type ReferralSource = (typeof sourceArray)[number];
|
|
5
16
|
/**
|
|
6
17
|
* One referral relationship — the state machine from invite through to credited.
|
|
7
18
|
*
|
|
8
19
|
* Status notes:
|
|
9
20
|
* - `invited` only ever applies to email invites, the one case where a row exists before the referred
|
|
10
21
|
* person has done anything. A link-only referral first becomes real at checkout, as `attributed`.
|
|
22
|
+
* - `purchased` is the store path only. A referee who buys on spytec.com has paid before any account
|
|
23
|
+
* of ours exists — the order and the account are days apart — so the row sits here with a
|
|
24
|
+
* `shopifyOrderId` but no `referredClientId`, and the 90-day clock has not started.
|
|
11
25
|
* - `qualified` is a resting state, not a transient one. The 90-day clock can complete while the
|
|
12
26
|
* referrer is past-due, paused, or at their annual cap; the row waits there until they can be paid.
|
|
13
27
|
* `qualifiedAt` records the clock completing, `creditedAt` records the money issuing.
|
|
14
28
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
29
|
+
* The payout deadline is `clockStartedAt + 90d + clockPausedSeconds`, so a referred customer's
|
|
30
|
+
* payment failure delays a payout rather than cancelling it.
|
|
31
|
+
*
|
|
32
|
+
* There is deliberately no revenue figure on this row. The reward is a flat amount, and revenue only
|
|
33
|
+
* ever lived in `billingInvoice`, which is Stripe-only — so a store-sourced referral would have read
|
|
34
|
+
* as zero and been voided as a refund. Qualification checks that the referred customer still has an
|
|
35
|
+
* active, reporting device instead, which works on both billing platforms.
|
|
19
36
|
*/
|
|
20
37
|
export declare class Referral {
|
|
21
38
|
id: number;
|
|
@@ -43,32 +60,50 @@ export declare class Referral {
|
|
|
43
60
|
signedUpAt: Date | null;
|
|
44
61
|
/** First device activation. */
|
|
45
62
|
activatedAt: Date | null;
|
|
46
|
-
/** Display only — the
|
|
63
|
+
/** Display only — the reward is a flat amount and does not scale with devices. */
|
|
47
64
|
deviceCount: number;
|
|
48
65
|
/** `= activatedAt`, or the resubscribe date when a cancel-and-resubscribe resets the clock. */
|
|
49
66
|
clockStartedAt: Date | null;
|
|
50
67
|
/** Set while the REFERRED customer's payment is failing. */
|
|
51
68
|
clockPausedAt: Date | null;
|
|
52
|
-
/** Accumulated pause. Shifts the payout deadline only
|
|
69
|
+
/** Accumulated pause. Shifts the payout deadline only. */
|
|
53
70
|
clockPausedSeconds: number;
|
|
54
71
|
/** `clockStartedAt + 90d + clockPausedSeconds` — the payout deadline. */
|
|
55
72
|
qualifiesAt: Date | null;
|
|
56
73
|
/** Clock completed. Not the same as credited — see the class comment. */
|
|
57
74
|
qualifiedAt: Date | null;
|
|
58
|
-
/** First plan price, frozen at activation — no mid-window repricing. */
|
|
59
|
-
baseMonthlyAmountCents: number | null;
|
|
60
75
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* received, since it measures revenue actually billed.
|
|
76
|
+
* Set at qualification. Always a flat 2500 ($25) — kept as a column rather than a constant so the
|
|
77
|
+
* ledger, exports and history stay readable if the amount ever changes.
|
|
64
78
|
*/
|
|
65
|
-
billedAmountCents: number;
|
|
66
|
-
/** 5% of `billedAmountCents`, set at qualification. */
|
|
67
79
|
earnedAmountCents: number | null;
|
|
68
80
|
creditedAt: Date | null;
|
|
69
81
|
status: ReferralStatus;
|
|
70
82
|
voidReason: ReferralVoidReason | null;
|
|
71
83
|
voidedAt: Date | null;
|
|
84
|
+
/** Which link this came in on. Drives the Source column in both dashboards. */
|
|
85
|
+
source: ReferralSource;
|
|
86
|
+
/**
|
|
87
|
+
* Store path — the order the `ref` was read off, and the idempotency key for it.
|
|
88
|
+
*
|
|
89
|
+
* The index is UNIQUE deliberately. `orders/create` is at-least-once and the backstop sweep reads
|
|
90
|
+
* the same orders, so a webhook and a sweep can race on one order; with a plain index both insert
|
|
91
|
+
* and the referrer is paid twice. One order is one buyer is one referral, so the database can
|
|
92
|
+
* enforce that the same way `ixuReferralReferredClient` does — MySQL tolerates repeated NULLs, so
|
|
93
|
+
* activation-path rows are unaffected. Callers must treat a duplicate-key error as success.
|
|
94
|
+
*/
|
|
95
|
+
shopifyOrderId: number | null;
|
|
96
|
+
/**
|
|
97
|
+
* Store path — the only route from a store order to one of our accounts, via
|
|
98
|
+
* `billing.platform = 'shopify' AND CAST(billing.subscriptionId AS UNSIGNED) = this`. That
|
|
99
|
+
* `billing` row is written days later, when the customer signs up and activates.
|
|
100
|
+
*/
|
|
101
|
+
shopifySubscriptionId: number | null;
|
|
102
|
+
/**
|
|
103
|
+
* When the store order was placed. Deliberately not `createdAt`: the backstop sweep can create the
|
|
104
|
+
* row days after the fact, and a referrer must not be shown the date we noticed.
|
|
105
|
+
*/
|
|
106
|
+
purchasedAt: Date | null;
|
|
72
107
|
/** Future phase — multi-tier referrals. Unused in MVP. */
|
|
73
108
|
parentReferralId: number | null;
|
|
74
109
|
/** Future phase — multi-tier depth. Unused in MVP. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("../node_modules/tslib/tslib.es6.js"),t=require("typeorm"),r=require("../utils/uuidTransformer.js");exports.Referral=class Referral{id;referrerId;referrerClientId;code;invitedEmail;invitedAt;firstClickAt;attributionExpiresAt;referredClientId;referredUserId;referredEmail;signedUpAt;activatedAt;deviceCount;clockStartedAt;clockPausedAt;clockPausedSeconds;qualifiesAt;qualifiedAt;
|
|
1
|
+
"use strict";var e=require("../node_modules/tslib/tslib.es6.js"),t=require("typeorm"),r=require("../utils/uuidTransformer.js");exports.Referral=class Referral{id;referrerId;referrerClientId;code;invitedEmail;invitedAt;firstClickAt;attributionExpiresAt;referredClientId;referredUserId;referredEmail;signedUpAt;activatedAt;deviceCount;clockStartedAt;clockPausedAt;clockPausedSeconds;qualifiesAt;qualifiedAt;earnedAmountCents;creditedAt;status;voidReason;voidedAt;source;shopifyOrderId;shopifySubscriptionId;purchasedAt;parentReferralId;tier;createdAt;updatedAt},e.__decorate([t.PrimaryGeneratedColumn({type:"int",name:"id"}),e.__metadata("design:type",Number)],exports.Referral.prototype,"id",void 0),e.__decorate([t.Column("int",{name:"referrerId"}),e.__metadata("design:type",Number)],exports.Referral.prototype,"referrerId",void 0),e.__decorate([t.Column("int",{name:"referrerClientId"}),e.__metadata("design:type",Number)],exports.Referral.prototype,"referrerClientId",void 0),e.__decorate([t.Column("varchar",{name:"code",length:36}),e.__metadata("design:type",String)],exports.Referral.prototype,"code",void 0),e.__decorate([t.Column("varchar",{name:"invitedEmail",nullable:!0,length:255}),e.__metadata("design:type",String)],exports.Referral.prototype,"invitedEmail",void 0),e.__decorate([t.Column("datetime",{name:"invitedAt",nullable:!0}),e.__metadata("design:type",Date)],exports.Referral.prototype,"invitedAt",void 0),e.__decorate([t.Column("datetime",{name:"firstClickAt",nullable:!0}),e.__metadata("design:type",Date)],exports.Referral.prototype,"firstClickAt",void 0),e.__decorate([t.Column("datetime",{name:"attributionExpiresAt",nullable:!0}),e.__metadata("design:type",Date)],exports.Referral.prototype,"attributionExpiresAt",void 0),e.__decorate([t.Column("int",{name:"referredClientId",nullable:!0}),e.__metadata("design:type",Number)],exports.Referral.prototype,"referredClientId",void 0),e.__decorate([t.Column("binary",{name:"referredUserId",length:16,nullable:!0,transformer:r.UUIDTransformer}),e.__metadata("design:type",String)],exports.Referral.prototype,"referredUserId",void 0),e.__decorate([t.Column("varchar",{name:"referredEmail",nullable:!0,length:255}),e.__metadata("design:type",String)],exports.Referral.prototype,"referredEmail",void 0),e.__decorate([t.Column("datetime",{name:"signedUpAt",nullable:!0}),e.__metadata("design:type",Date)],exports.Referral.prototype,"signedUpAt",void 0),e.__decorate([t.Column("datetime",{name:"activatedAt",nullable:!0}),e.__metadata("design:type",Date)],exports.Referral.prototype,"activatedAt",void 0),e.__decorate([t.Column("int",{name:"deviceCount",default:()=>"'0'"}),e.__metadata("design:type",Number)],exports.Referral.prototype,"deviceCount",void 0),e.__decorate([t.Column("datetime",{name:"clockStartedAt",nullable:!0}),e.__metadata("design:type",Date)],exports.Referral.prototype,"clockStartedAt",void 0),e.__decorate([t.Column("datetime",{name:"clockPausedAt",nullable:!0}),e.__metadata("design:type",Date)],exports.Referral.prototype,"clockPausedAt",void 0),e.__decorate([t.Column("int",{name:"clockPausedSeconds",default:()=>"'0'"}),e.__metadata("design:type",Number)],exports.Referral.prototype,"clockPausedSeconds",void 0),e.__decorate([t.Column("datetime",{name:"qualifiesAt",nullable:!0}),e.__metadata("design:type",Date)],exports.Referral.prototype,"qualifiesAt",void 0),e.__decorate([t.Column("datetime",{name:"qualifiedAt",nullable:!0}),e.__metadata("design:type",Date)],exports.Referral.prototype,"qualifiedAt",void 0),e.__decorate([t.Column("int",{name:"earnedAmountCents",nullable:!0}),e.__metadata("design:type",Number)],exports.Referral.prototype,"earnedAmountCents",void 0),e.__decorate([t.Column("datetime",{name:"creditedAt",nullable:!0}),e.__metadata("design:type",Date)],exports.Referral.prototype,"creditedAt",void 0),e.__decorate([t.Column("enum",{enum:["invited","attributed","active","qualified","credited","canceled","voided","purchased"],name:"status",default:"invited"}),e.__metadata("design:type",String)],exports.Referral.prototype,"status",void 0),e.__decorate([t.Column("enum",{enum:["refund","cancelled_early","self_referral","fraud","existing_active_customer","referrer_ineligible","attribution_expired","annual_cap_reached"],name:"voidReason",nullable:!0}),e.__metadata("design:type",String)],exports.Referral.prototype,"voidReason",void 0),e.__decorate([t.Column("datetime",{name:"voidedAt",nullable:!0}),e.__metadata("design:type",Date)],exports.Referral.prototype,"voidedAt",void 0),e.__decorate([t.Column("enum",{enum:["activation","store","manual"],name:"source",default:"activation"}),e.__metadata("design:type",String)],exports.Referral.prototype,"source",void 0),e.__decorate([t.Column("bigint",{name:"shopifyOrderId",nullable:!0}),e.__metadata("design:type",Number)],exports.Referral.prototype,"shopifyOrderId",void 0),e.__decorate([t.Column("bigint",{name:"shopifySubscriptionId",nullable:!0}),e.__metadata("design:type",Number)],exports.Referral.prototype,"shopifySubscriptionId",void 0),e.__decorate([t.Column("datetime",{name:"purchasedAt",nullable:!0}),e.__metadata("design:type",Date)],exports.Referral.prototype,"purchasedAt",void 0),e.__decorate([t.Column("int",{name:"parentReferralId",nullable:!0}),e.__metadata("design:type",Number)],exports.Referral.prototype,"parentReferralId",void 0),e.__decorate([t.Column("tinyint",{name:"tier",default:()=>"'1'"}),e.__metadata("design:type",Number)],exports.Referral.prototype,"tier",void 0),e.__decorate([t.Column("datetime",{name:"createdAt",nullable:!0}),e.__metadata("design:type",Date)],exports.Referral.prototype,"createdAt",void 0),e.__decorate([t.Column("datetime",{name:"updatedAt",nullable:!0}),e.__metadata("design:type",Date)],exports.Referral.prototype,"updatedAt",void 0),exports.Referral=e.__decorate([t.Index("ixuReferralReferredClient",["referredClientId"],{unique:!0}),t.Index("ixReferralReferrer",["referrerId"],{}),t.Index("ixReferralReferrerClientStatus",["referrerClientId","status"],{}),t.Index("ixReferralCode",["code"],{}),t.Index("ixReferralStatusQualifiesAt",["status","qualifiesAt"],{}),t.Index("ixReferralInvitedEmail",["invitedEmail"],{}),t.Index("ixReferralCreatedAt",["createdAt"],{}),t.Index("ixuReferralShopifyOrder",["shopifyOrderId"],{unique:!0}),t.Index("ixReferralShopifySubscription",["shopifySubscriptionId"],{}),t.Entity("referral",{schema:"nova"})],exports.Referral);
|
|
@@ -14,7 +14,7 @@ export type ReferralCreditType = (typeof typeArray)[number];
|
|
|
14
14
|
* total earned = SUM(amountCents) WHERE type = 'earned'
|
|
15
15
|
* credit applied = -SUM(amountCents) WHERE type = 'applied'
|
|
16
16
|
* A negative overall balance is meaningful — it is a clawback of credit that an invoice had already
|
|
17
|
-
* consumed, and is settled by pushing a positive (debit) transaction to
|
|
17
|
+
* consumed, and is settled by pushing a positive (debit) transaction back to the provider.
|
|
18
18
|
*/
|
|
19
19
|
export declare class ReferralCredit {
|
|
20
20
|
id: number;
|
|
@@ -30,10 +30,14 @@ export declare class ReferralCredit {
|
|
|
30
30
|
/** `issuedAt + 12 months`. Set on `earned` rows only. */
|
|
31
31
|
expiresAt: Date | null;
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
34
|
-
* —
|
|
33
|
+
* The provider's own reference for this movement, and the reason a retried drip cannot double-apply
|
|
34
|
+
* — it is uniquely indexed. A Stripe customer balance transaction id on the Stripe path (including
|
|
35
|
+
* the debit id when a clawback is settled), or the discount id Loop returns on the Loop path.
|
|
36
|
+
*
|
|
37
|
+
* Deliberately not named for Stripe: the referrer's platform decides which sink is used, and a
|
|
38
|
+
* Loop-billed referrer is paid with a subscription discount rather than a balance transaction.
|
|
35
39
|
*/
|
|
36
|
-
|
|
40
|
+
externalCreditRef: string | null;
|
|
37
41
|
appliedInvoiceId: string | null;
|
|
38
42
|
appliedAt: Date | null;
|
|
39
43
|
/** CS user behind a manual adjustment or clawback. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("../node_modules/tslib/tslib.es6.js"),t=require("typeorm");exports.ReferralCredit=class ReferralCredit{id;referralId;clientId;customerId;type;amountCents;issuedAt;expiresAt;
|
|
1
|
+
"use strict";var e=require("../node_modules/tslib/tslib.es6.js"),t=require("typeorm");exports.ReferralCredit=class ReferralCredit{id;referralId;clientId;customerId;type;amountCents;issuedAt;expiresAt;externalCreditRef;appliedInvoiceId;appliedAt;adjustedByUsername;note;createdAt;updatedAt},e.__decorate([t.PrimaryGeneratedColumn({type:"int",name:"id"}),e.__metadata("design:type",Number)],exports.ReferralCredit.prototype,"id",void 0),e.__decorate([t.Column("int",{name:"referralId",nullable:!0}),e.__metadata("design:type",Number)],exports.ReferralCredit.prototype,"referralId",void 0),e.__decorate([t.Column("int",{name:"clientId"}),e.__metadata("design:type",Number)],exports.ReferralCredit.prototype,"clientId",void 0),e.__decorate([t.Column("varchar",{name:"customerId",nullable:!0,length:50}),e.__metadata("design:type",String)],exports.ReferralCredit.prototype,"customerId",void 0),e.__decorate([t.Column("enum",{enum:["earned","applied","expired","clawback","manual_adjustment"],name:"type"}),e.__metadata("design:type",String)],exports.ReferralCredit.prototype,"type",void 0),e.__decorate([t.Column("int",{name:"amountCents"}),e.__metadata("design:type",Number)],exports.ReferralCredit.prototype,"amountCents",void 0),e.__decorate([t.Column("datetime",{name:"issuedAt"}),e.__metadata("design:type",Date)],exports.ReferralCredit.prototype,"issuedAt",void 0),e.__decorate([t.Column("datetime",{name:"expiresAt",nullable:!0}),e.__metadata("design:type",Date)],exports.ReferralCredit.prototype,"expiresAt",void 0),e.__decorate([t.Column("varchar",{name:"externalCreditRef",nullable:!0,length:100}),e.__metadata("design:type",String)],exports.ReferralCredit.prototype,"externalCreditRef",void 0),e.__decorate([t.Column("varchar",{name:"appliedInvoiceId",nullable:!0,length:100}),e.__metadata("design:type",String)],exports.ReferralCredit.prototype,"appliedInvoiceId",void 0),e.__decorate([t.Column("datetime",{name:"appliedAt",nullable:!0}),e.__metadata("design:type",Date)],exports.ReferralCredit.prototype,"appliedAt",void 0),e.__decorate([t.Column("varchar",{name:"adjustedByUsername",nullable:!0,length:255}),e.__metadata("design:type",String)],exports.ReferralCredit.prototype,"adjustedByUsername",void 0),e.__decorate([t.Column("varchar",{name:"note",nullable:!0,length:500}),e.__metadata("design:type",String)],exports.ReferralCredit.prototype,"note",void 0),e.__decorate([t.Column("datetime",{name:"createdAt",nullable:!0}),e.__metadata("design:type",Date)],exports.ReferralCredit.prototype,"createdAt",void 0),e.__decorate([t.Column("datetime",{name:"updatedAt",nullable:!0}),e.__metadata("design:type",Date)],exports.ReferralCredit.prototype,"updatedAt",void 0),exports.ReferralCredit=e.__decorate([t.Index("ixuReferralCreditExternalRef",["externalCreditRef"],{unique:!0}),t.Index("ixReferralCreditClientType",["clientId","type"],{}),t.Index("ixReferralCreditReferral",["referralId"],{}),t.Index("ixReferralCreditExpiresAt",["expiresAt"],{}),t.Index("ixReferralCreditClientIssuedAt",["clientId","issuedAt"],{}),t.Entity("referralCredit",{schema:"nova"})],exports.ReferralCredit);
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
var _1684483704434AddLowerCaseIndex = require('../1684483704434-addLowerCaseIndex.js');
|
|
4
4
|
var _1684483705002UpdateSecurityUserViewsV2 = require('../1684483705002-updateSecurityUserViewsV2.js');
|
|
5
|
-
var _1746434400000AddQuickSearchFulltextIndexes = require('../1746434400000-addQuickSearchFulltextIndexes.js');
|
|
6
5
|
var _1684483705001UpdateSecurityUserViewsV1 = require('../1684483705001-updateSecurityUserViewsV1.js');
|
|
6
|
+
var _1746434400000AddQuickSearchFulltextIndexes = require('../1746434400000-addQuickSearchFulltextIndexes.js');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
exports.addLowerCaseIndex1684483704434 = _1684483704434AddLowerCaseIndex.addLowerCaseIndex1684483704434;
|
|
11
11
|
exports.updateSecurityUserViewsV21684483705002 = _1684483705002UpdateSecurityUserViewsV2.updateSecurityUserViewsV21684483705002;
|
|
12
|
-
exports.addQuickSearchFulltextIndexes1746434400000 = _1746434400000AddQuickSearchFulltextIndexes.addQuickSearchFulltextIndexes1746434400000;
|
|
13
12
|
exports.updateSecurityUserViewsV11684483705001 = _1684483705001UpdateSecurityUserViewsV1.updateSecurityUserViewsV11684483705001;
|
|
13
|
+
exports.addQuickSearchFulltextIndexes1746434400000 = _1746434400000AddQuickSearchFulltextIndexes.addQuickSearchFulltextIndexes1746434400000;
|
package/package.json
CHANGED
package/schema.sql
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
-- nova-orm-schema-checksum:
|
|
1
|
+
-- nova-orm-schema-checksum: 48040cde7e40b0592f8ff8625e47b68c
|
|
2
2
|
-- Nova ORM Schema Dump
|
|
3
|
-
-- Generated at: 2026-
|
|
3
|
+
-- Generated at: 2026-09-02T22:47:03.965Z
|
|
4
4
|
|
|
5
5
|
SET FOREIGN_KEY_CHECKS = 0;
|
|
6
6
|
|
|
@@ -2906,19 +2906,23 @@ CREATE TABLE `referral` (
|
|
|
2906
2906
|
`clockPausedSeconds` int NOT NULL DEFAULT '0',
|
|
2907
2907
|
`qualifiesAt` datetime DEFAULT NULL,
|
|
2908
2908
|
`qualifiedAt` datetime DEFAULT NULL,
|
|
2909
|
-
`baseMonthlyAmountCents` int DEFAULT NULL,
|
|
2910
|
-
`billedAmountCents` int NOT NULL DEFAULT '0',
|
|
2911
2909
|
`earnedAmountCents` int DEFAULT NULL,
|
|
2912
2910
|
`creditedAt` datetime DEFAULT NULL,
|
|
2913
|
-
`status` enum('invited','attributed','active','qualified','credited','canceled','voided') NOT NULL DEFAULT 'invited',
|
|
2911
|
+
`status` enum('invited','attributed','active','qualified','credited','canceled','voided','purchased') NOT NULL DEFAULT 'invited',
|
|
2914
2912
|
`voidReason` enum('refund','cancelled_early','self_referral','fraud','existing_active_customer','referrer_ineligible','attribution_expired','annual_cap_reached') DEFAULT NULL,
|
|
2915
2913
|
`voidedAt` datetime DEFAULT NULL,
|
|
2914
|
+
`source` enum('activation','store','manual') NOT NULL DEFAULT 'activation',
|
|
2915
|
+
`shopifyOrderId` bigint DEFAULT NULL,
|
|
2916
|
+
`shopifySubscriptionId` bigint DEFAULT NULL,
|
|
2917
|
+
`purchasedAt` datetime DEFAULT NULL,
|
|
2916
2918
|
`parentReferralId` int DEFAULT NULL,
|
|
2917
2919
|
`tier` tinyint NOT NULL DEFAULT '1',
|
|
2918
2920
|
`createdAt` datetime DEFAULT NULL,
|
|
2919
2921
|
`updatedAt` datetime DEFAULT NULL,
|
|
2920
2922
|
PRIMARY KEY (`id`),
|
|
2923
|
+
UNIQUE KEY `ixuReferralShopifyOrder` (`shopifyOrderId`),
|
|
2921
2924
|
UNIQUE KEY `ixuReferralReferredClient` (`referredClientId`),
|
|
2925
|
+
KEY `ixReferralShopifySubscription` (`shopifySubscriptionId`),
|
|
2922
2926
|
KEY `ixReferralCreatedAt` (`createdAt`),
|
|
2923
2927
|
KEY `ixReferralInvitedEmail` (`invitedEmail`),
|
|
2924
2928
|
KEY `ixReferralStatusQualifiesAt` (`status`,`qualifiesAt`),
|
|
@@ -2937,7 +2941,7 @@ CREATE TABLE `referralCredit` (
|
|
|
2937
2941
|
`amountCents` int NOT NULL,
|
|
2938
2942
|
`issuedAt` datetime NOT NULL,
|
|
2939
2943
|
`expiresAt` datetime DEFAULT NULL,
|
|
2940
|
-
`
|
|
2944
|
+
`externalCreditRef` varchar(100) DEFAULT NULL,
|
|
2941
2945
|
`appliedInvoiceId` varchar(100) DEFAULT NULL,
|
|
2942
2946
|
`appliedAt` datetime DEFAULT NULL,
|
|
2943
2947
|
`adjustedByUsername` varchar(255) DEFAULT NULL,
|
|
@@ -2945,7 +2949,7 @@ CREATE TABLE `referralCredit` (
|
|
|
2945
2949
|
`createdAt` datetime DEFAULT NULL,
|
|
2946
2950
|
`updatedAt` datetime DEFAULT NULL,
|
|
2947
2951
|
PRIMARY KEY (`id`),
|
|
2948
|
-
UNIQUE KEY `
|
|
2952
|
+
UNIQUE KEY `ixuReferralCreditExternalRef` (`externalCreditRef`),
|
|
2949
2953
|
KEY `ixReferralCreditClientIssuedAt` (`clientId`,`issuedAt`),
|
|
2950
2954
|
KEY `ixReferralCreditExpiresAt` (`expiresAt`),
|
|
2951
2955
|
KEY `ixReferralCreditReferral` (`referralId`),
|