customer-registration 0.0.123 → 0.0.124
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.
- package/.medusa/server/src/api/store/customers/route.js +83 -1
- package/.medusa/server/src/api/store/my-referrals/__tests__/route.test.js +120 -0
- package/.medusa/server/src/api/store/my-referrals/route.js +62 -0
- package/.medusa/server/src/modules/referral-link/index.js +14 -0
- package/.medusa/server/src/modules/referral-link/migrations/Migration20260502100000CreateReferralLinkTable.js +56 -0
- package/.medusa/server/src/modules/referral-link/models/referral-link.js +29 -0
- package/.medusa/server/src/modules/referral-link/service.js +13 -0
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ exports.POST = void 0;
|
|
|
4
4
|
const utils_1 = require("@medusajs/framework/utils");
|
|
5
5
|
const core_flows_1 = require("@medusajs/core-flows");
|
|
6
6
|
const config_1 = require("../../../config");
|
|
7
|
+
const referral_link_1 = require("../../../modules/referral-link");
|
|
7
8
|
const is_social_pending_customer_registration_1 = require("./shared/is-social-pending-customer-registration");
|
|
8
9
|
/** Medusa / Knex raw results may use `rows` (node-pg) or `result[0]` batch shape. */
|
|
9
10
|
function firstKnexRow(result) {
|
|
@@ -20,6 +21,83 @@ function firstKnexRow(result) {
|
|
|
20
21
|
}
|
|
21
22
|
return undefined;
|
|
22
23
|
}
|
|
24
|
+
function parseReferralCodeFromQuery(query) {
|
|
25
|
+
if (!query || typeof query !== "object") {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const raw = query.referral_code;
|
|
29
|
+
if (Array.isArray(raw)) {
|
|
30
|
+
const first = raw[0];
|
|
31
|
+
if (typeof first === "string" && first.trim().length > 0) {
|
|
32
|
+
return first.trim();
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
if (typeof raw === "string" && raw.trim().length > 0) {
|
|
37
|
+
return raw.trim();
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
function isRecord(value) {
|
|
42
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* `referral_code` is the referrer's Medusa customer id. If the query param is set,
|
|
46
|
+
* the customer must exist before we create the new account (avoids orphaned customers).
|
|
47
|
+
*/
|
|
48
|
+
async function assertReferralCodeReferrerExists(req) {
|
|
49
|
+
const referrerId = parseReferralCodeFromQuery(req.query);
|
|
50
|
+
if (!referrerId) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const customerService = req.scope.resolve(utils_1.Modules.CUSTOMER);
|
|
54
|
+
const referrerCustomers = await customerService.listCustomers({
|
|
55
|
+
id: [referrerId],
|
|
56
|
+
});
|
|
57
|
+
if (!referrerCustomers.length) {
|
|
58
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Invalid referral_code: no customer exists with this id");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* When `?referral_code=` is present (referrer customer id), inserts `referral_link`
|
|
63
|
+
* for the newly created customer. Omits DB write when the query param is absent.
|
|
64
|
+
* Call {@link assertReferralCodeReferrerExists} before creating the customer when
|
|
65
|
+
* `referral_code` is present.
|
|
66
|
+
*/
|
|
67
|
+
async function maybeCreateReferralLinkFromQuery(req, newCustomerId) {
|
|
68
|
+
const referrerId = parseReferralCodeFromQuery(req.query);
|
|
69
|
+
if (!referrerId) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (referrerId === newCustomerId) {
|
|
73
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "referral_code cannot match the new customer id");
|
|
74
|
+
}
|
|
75
|
+
const referralLinkService = req.scope.resolve(referral_link_1.REFERRAL_LINK_MODULE);
|
|
76
|
+
const parentByLevel = { "1": referrerId };
|
|
77
|
+
const referrerRows = await referralLinkService.listReferralLinks({
|
|
78
|
+
customer_id: referrerId,
|
|
79
|
+
});
|
|
80
|
+
const referrerOwnLink = referrerRows[0];
|
|
81
|
+
const referrerParents = referrerOwnLink?.parent_customers_by_level;
|
|
82
|
+
if (isRecord(referrerParents)) {
|
|
83
|
+
for (const [key, val] of Object.entries(referrerParents)) {
|
|
84
|
+
const n = Number(key);
|
|
85
|
+
if (!Number.isFinite(n) || n < 1) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const id = typeof val === "string" ? val.trim() : "";
|
|
89
|
+
if (!id) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
parentByLevel[String(n + 1)] = id;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
await referralLinkService.createReferralLinks({
|
|
96
|
+
customer_id: newCustomerId,
|
|
97
|
+
referrer_id: referrerId,
|
|
98
|
+
parent_customers_by_level: parentByLevel,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
23
101
|
/**
|
|
24
102
|
* Override of Medusa's built-in POST /store/customers.
|
|
25
103
|
*
|
|
@@ -49,6 +127,7 @@ const POST = async (req, res) => {
|
|
|
49
127
|
const phoneNormalized = customerData.phone != null && String(customerData.phone).trim() !== ""
|
|
50
128
|
? String(customerData.phone).trim()
|
|
51
129
|
: "";
|
|
130
|
+
await assertReferralCodeReferrerExists(req);
|
|
52
131
|
if (identifier === "email" || socialPending) {
|
|
53
132
|
const { result } = await (0, core_flows_1.createCustomerAccountWorkflow)(req.scope).run({
|
|
54
133
|
input: {
|
|
@@ -57,6 +136,7 @@ const POST = async (req, res) => {
|
|
|
57
136
|
authIdentityId: authIdentityId ?? "",
|
|
58
137
|
},
|
|
59
138
|
});
|
|
139
|
+
await maybeCreateReferralLinkFromQuery(req, result.id);
|
|
60
140
|
const customer = await refetchCustomer(result.id, req.scope);
|
|
61
141
|
return res.status(200).json({ customer });
|
|
62
142
|
}
|
|
@@ -77,6 +157,7 @@ const POST = async (req, res) => {
|
|
|
77
157
|
authIdentityId: authIdentityId ?? "",
|
|
78
158
|
},
|
|
79
159
|
});
|
|
160
|
+
await maybeCreateReferralLinkFromQuery(req, result.id);
|
|
80
161
|
const customer = await refetchCustomer(result.id, req.scope);
|
|
81
162
|
return res.status(200).json({ customer });
|
|
82
163
|
}
|
|
@@ -97,6 +178,7 @@ const POST = async (req, res) => {
|
|
|
97
178
|
app_metadata: { customer_id: customer.id },
|
|
98
179
|
});
|
|
99
180
|
}
|
|
181
|
+
await maybeCreateReferralLinkFromQuery(req, customer.id);
|
|
100
182
|
const fullCustomer = await refetchCustomer(customer.id, req.scope);
|
|
101
183
|
return res.status(200).json({ customer: fullCustomer });
|
|
102
184
|
};
|
|
@@ -121,4 +203,4 @@ async function refetchCustomer(customerId, scope) {
|
|
|
121
203
|
const customers = await remoteQuery(queryObject);
|
|
122
204
|
return customers[0];
|
|
123
205
|
}
|
|
124
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
206
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2N1c3RvbWVycy9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFLQSxxREFLa0M7QUFDbEMscURBQW9FO0FBQ3BFLDRDQUd3QjtBQUN4QixrRUFBcUU7QUFFckUsOEdBQXNHO0FBRXRHLHFGQUFxRjtBQUNyRixTQUFTLFlBQVksQ0FDbkIsTUFBbUM7SUFFbkMsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ2pDLElBQUksUUFBUSxJQUFJLE9BQU8sUUFBUSxLQUFLLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztRQUN6RSxPQUFPLFFBQVEsQ0FBQTtJQUNqQixDQUFDO0lBQ0QsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ3ZCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUN0QixJQUFJLEtBQUssSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDaEUsT0FBTyxLQUFVLENBQUE7UUFDbkIsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLFNBQVMsQ0FBQTtBQUNsQixDQUFDO0FBRUQsU0FBUywwQkFBMEIsQ0FBQyxLQUFjO0lBQ2hELElBQUksQ0FBQyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDeEMsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBQ0QsTUFBTSxHQUFHLEdBQUksS0FBaUMsQ0FBQyxhQUFhLENBQUE7SUFDNUQsSUFBSSxL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
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
const vitest_1 = require("vitest");
|
|
5
|
+
const referral_link_1 = require("../../../../modules/referral-link");
|
|
6
|
+
const route_1 = require("../route");
|
|
7
|
+
(0, vitest_1.describe)("GET /store/my-referrals table-driven tests", () => {
|
|
8
|
+
const cases = [
|
|
9
|
+
{
|
|
10
|
+
title: "returns empty children when no referral links",
|
|
11
|
+
auth_context: { actor_id: "cus_parent", actor_type: "customer" },
|
|
12
|
+
links: [],
|
|
13
|
+
customers: [],
|
|
14
|
+
expectListCustomersCalls: 0,
|
|
15
|
+
expectedStatus: 200,
|
|
16
|
+
expectedJson: { children: [] },
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
title: "returns children merged with customer rows",
|
|
20
|
+
auth_context: { actor_id: "cus_parent", actor_type: "customer" },
|
|
21
|
+
links: [
|
|
22
|
+
{
|
|
23
|
+
id: "rl_1",
|
|
24
|
+
customer_id: "cus_child",
|
|
25
|
+
referrer_id: "cus_parent",
|
|
26
|
+
parent_customers_by_level: { "1": "cus_parent" },
|
|
27
|
+
created_at: new Date("2025-06-01T12:00:00.000Z"),
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
customers: [
|
|
31
|
+
{
|
|
32
|
+
id: "cus_child",
|
|
33
|
+
email: "child@example.com",
|
|
34
|
+
first_name: "C",
|
|
35
|
+
last_name: "One",
|
|
36
|
+
phone: "+1000",
|
|
37
|
+
created_at: "2025-06-01T00:00:00.000Z",
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
expectListCustomersCalls: 1,
|
|
41
|
+
expectedStatus: 200,
|
|
42
|
+
expectedJson: {
|
|
43
|
+
children: [
|
|
44
|
+
{
|
|
45
|
+
referral_link_id: "rl_1",
|
|
46
|
+
referred_at: "2025-06-01T12:00:00.000Z",
|
|
47
|
+
parent_customers_by_level: { "1": "cus_parent" },
|
|
48
|
+
customer: {
|
|
49
|
+
id: "cus_child",
|
|
50
|
+
email: "child@example.com",
|
|
51
|
+
first_name: "C",
|
|
52
|
+
last_name: "One",
|
|
53
|
+
phone: "+1000",
|
|
54
|
+
created_at: "2025-06-01T00:00:00.000Z",
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
vitest_1.test.each(cases)("$title", async ({ auth_context, links, customers, expectListCustomersCalls, expectedStatus, expectedJson, }) => {
|
|
62
|
+
const listReferralLinks = vitest_1.vi.fn().mockResolvedValue(links);
|
|
63
|
+
const listCustomers = vitest_1.vi.fn().mockResolvedValue(customers);
|
|
64
|
+
const req = {
|
|
65
|
+
auth_context,
|
|
66
|
+
scope: {
|
|
67
|
+
resolve: (token) => {
|
|
68
|
+
if (token === referral_link_1.REFERRAL_LINK_MODULE) {
|
|
69
|
+
return { listReferralLinks };
|
|
70
|
+
}
|
|
71
|
+
if (token === utils_1.Modules.CUSTOMER) {
|
|
72
|
+
return { listCustomers };
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
const status = vitest_1.vi.fn().mockReturnThis();
|
|
79
|
+
const json = vitest_1.vi.fn();
|
|
80
|
+
const res = { status, json };
|
|
81
|
+
await (0, route_1.GET)(req, res);
|
|
82
|
+
(0, vitest_1.expect)(status).toHaveBeenCalledWith(expectedStatus);
|
|
83
|
+
(0, vitest_1.expect)(json).toHaveBeenCalledWith(expectedJson);
|
|
84
|
+
(0, vitest_1.expect)(listReferralLinks).toHaveBeenCalledWith({
|
|
85
|
+
referrer_id: auth_context?.actor_id,
|
|
86
|
+
});
|
|
87
|
+
(0, vitest_1.expect)(listCustomers).toHaveBeenCalledTimes(expectListCustomersCalls);
|
|
88
|
+
if (expectListCustomersCalls > 0) {
|
|
89
|
+
(0, vitest_1.expect)(listCustomers).toHaveBeenCalledWith({ id: ["cus_child"] });
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
const authErrorCases = [
|
|
93
|
+
{
|
|
94
|
+
title: "rejects when actor_type is not customer",
|
|
95
|
+
auth_context: { actor_id: "usr_admin", actor_type: "user" },
|
|
96
|
+
wantMessage: "Unauthorized",
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
title: "rejects when actor_id is missing",
|
|
100
|
+
auth_context: { actor_type: "customer" },
|
|
101
|
+
wantMessage: "Unauthorized",
|
|
102
|
+
},
|
|
103
|
+
];
|
|
104
|
+
vitest_1.test.each(authErrorCases)("$title", async ({ auth_context, wantMessage }) => {
|
|
105
|
+
const listReferralLinks = vitest_1.vi.fn();
|
|
106
|
+
const req = {
|
|
107
|
+
auth_context,
|
|
108
|
+
scope: {
|
|
109
|
+
resolve: () => ({ listReferralLinks }),
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
const res = {};
|
|
113
|
+
await (0, vitest_1.expect)((0, route_1.GET)(req, res)).rejects.toMatchObject({
|
|
114
|
+
type: utils_1.MedusaError.Types.UNAUTHORIZED,
|
|
115
|
+
message: wantMessage,
|
|
116
|
+
});
|
|
117
|
+
(0, vitest_1.expect)(listReferralLinks).not.toHaveBeenCalled();
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvc3RvcmUvbXktcmVmZXJyYWxzL19fdGVzdHNfXy9yb3V0ZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0EscURBQWdFO0FBQ2hFLG1DQUFtRDtBQUNuRCxxRUFBd0U7QUFDeEUsb0NBQThCO0FBMkI5QixJQUFBLGlCQUFRLEVBQUMsNENBQTRDLEVBQUUsR0FBRyxFQUFFO0lBQzFELE1BQU0sS0FBSyxHQUEwQjtRQUNuQztZQUNFLEtBQUssRUFBRSwrQ0FBK0M7WUFDdEQsWUFBWSxFQUFFLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFO1lBQ2hFLEtBQUssRUFBRSxFQUFFO1lBQ1QsU0FBUyxFQUFFLEVBQUU7WUFDYix3QkFBd0IsRUFBRSxDQUFDO1lBQzNCLGNBQWMsRUFBRSxHQUFHO1lBQ25CLFlBQVksRUFBRSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUU7U0FDL0I7UUFDRDtZQUNFLEtBQUssRUFBRSw0Q0FBNEM7WUFDbkQsWUFBWSxFQUFFLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFO1lBQ2hFLEtBQUssRUFBRTtnQkFDTDtvQkFDRSxFQUFFLEVBQUUsTUFBTTtvQkFDVixXQUFXLEVBQUUsV0FBVztvQkFDeEIsV0FBVyxFQUFFLFlBQVk7b0JBQ3pCLHlCQUF5QixFQUFFLEVBQUUsR0FBRyxFQUFFLFlBQVksRUFBRTtvQkFDaEQsVUFBVSxFQUFFLElBQUksSUFBSSxDQUFDLDBCQUEwQixDQUFDO2lCQUNqRDthQUNGO1lBQ0QsU0FBUyxFQUFFO2dCQUNUO29CQUNFLEVBQUUsRUFBRSxXQUFXO29CQUNmLEtBQUssRUFBRSxtQkFBbUI7b0JBQzFCLFVBQVUsRUFBRSxHQUFHO29CQUNmLFNBQVMsRUFBRSxLQUFLO29CQUNoQixLQUFLLEVBQUUs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
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const referral_link_1 = require("../../../modules/referral-link");
|
|
6
|
+
/**
|
|
7
|
+
* GET /store/my-referrals
|
|
8
|
+
*
|
|
9
|
+
* Returns every customer who signed up with this customer as `referrer_id`
|
|
10
|
+
* (`referral_link` rows for the authenticated customer).
|
|
11
|
+
*/
|
|
12
|
+
const GET = async (req, res) => {
|
|
13
|
+
const authContext = req.auth_context;
|
|
14
|
+
const actorId = authContext?.actor_id;
|
|
15
|
+
if (!actorId || authContext?.actor_type !== "customer") {
|
|
16
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Unauthorized");
|
|
17
|
+
}
|
|
18
|
+
const referralLinkService = req.scope.resolve(referral_link_1.REFERRAL_LINK_MODULE);
|
|
19
|
+
const links = await referralLinkService.listReferralLinks({
|
|
20
|
+
referrer_id: actorId,
|
|
21
|
+
});
|
|
22
|
+
const childIds = [
|
|
23
|
+
...new Set(links
|
|
24
|
+
.map((row) => row.customer_id)
|
|
25
|
+
.filter((id) => typeof id === "string" && id.length > 0)),
|
|
26
|
+
];
|
|
27
|
+
const customerService = req.scope.resolve(utils_1.Modules.CUSTOMER);
|
|
28
|
+
const customers = childIds.length > 0
|
|
29
|
+
? await customerService.listCustomers({ id: childIds })
|
|
30
|
+
: [];
|
|
31
|
+
const byId = new Map(customers.map((c) => [c.id, c]));
|
|
32
|
+
const children = links.map((link) => {
|
|
33
|
+
const c = byId.get(link.customer_id);
|
|
34
|
+
const parentLevel = link.parent_customers_by_level;
|
|
35
|
+
const parentParsed = parentLevel !== null &&
|
|
36
|
+
parentLevel !== undefined &&
|
|
37
|
+
typeof parentLevel === "object" &&
|
|
38
|
+
!Array.isArray(parentLevel)
|
|
39
|
+
? parentLevel
|
|
40
|
+
: null;
|
|
41
|
+
return {
|
|
42
|
+
referral_link_id: link.id,
|
|
43
|
+
referred_at: link.created_at != null
|
|
44
|
+
? typeof link.created_at === "string"
|
|
45
|
+
? link.created_at
|
|
46
|
+
: link.created_at.toISOString()
|
|
47
|
+
: null,
|
|
48
|
+
parent_customers_by_level: parentParsed,
|
|
49
|
+
customer: {
|
|
50
|
+
id: link.customer_id,
|
|
51
|
+
email: c?.email ?? null,
|
|
52
|
+
first_name: c?.first_name ?? null,
|
|
53
|
+
last_name: c?.last_name ?? null,
|
|
54
|
+
phone: c?.phone ?? null,
|
|
55
|
+
created_at: c?.created_at ?? null,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
res.status(200).json({ children });
|
|
60
|
+
};
|
|
61
|
+
exports.GET = GET;
|
|
62
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL215LXJlZmVycmFscy9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxxREFBZ0U7QUFDaEUsa0VBQXFFO0FBc0JyRTs7Ozs7R0FLRztBQUNJLE1BQU0sR0FBRyxHQUFHLEtBQUssRUFBRSxHQUErQixFQUFFLEdBQW1CLEVBQUUsRUFBRTtJQUNoRixNQUFNLFdBQVcsR0FBSSxHQUFzQyxDQUFDLFlBQVksQ0FBQTtJQUN4RSxNQUFNLE9BQU8sR0FBRyxXQUFXLEVBQUUsUUFBUSxDQUFBO0lBQ3JDLElBQUksQ0FBQyxPQUFPLElBQUksV0FBVyxFQUFFLFVBQVUsS0FBSyxVQUFVLEVBQUUsQ0FBQztRQUN2RCxNQUFNLElBQUksbUJBQVcsQ0FBQyxtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsY0FBYyxDQUFDLENBQUE7SUFDdkUsQ0FBQztJQUVELE1BQU0sbUJBQW1CLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQzNDLG9DQUFvQixDQUNyQixDQUFBO0lBQ0QsTUFBTSxLQUFLLEdBQUcsTUFBTSxtQkFBbUIsQ0FBQyxpQkFBaUIsQ0FBQztRQUN4RCxXQUFXLEVBQUUsT0FBTztLQUNyQixDQUFDLENBQUE7SUFFRixNQUFNLFFBQVEsR0FBRztRQUNmLEdBQUcsSUFBSSxHQUFHLENBQ1IsS0FBSzthQUNGLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQzthQUM3QixNQUFNLENBQUMsQ0FBQyxFQUFFLEVBQWdCLEVBQUUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxRQUFRLElBQUksRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FDekU7S0FDRixDQUFBO0lBRUQsTUFBTSxlQUFlLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQXlCLGVBQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUNuRixNQUFNLFNBQVMsR0FDYixRQUFRLENBQUMsTUFBTSxHQUFHLENBQUM7UUFDakIsQ0FBQyxDQUFDLE1BQU0sZUFBZSxDQUFDLGFBQWEsQ0FBQyxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsQ0FBQztRQUN2RCxDQUFDLENBQUMsRUFBRSxDQUFBO0lBRVIsTUFBTSxJQUFJLEdBQUcsSUFBSSxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUVyRCxNQUFNLFFBQVEsR0FBNEIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1FBQzNELE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFBO1FBQ3BDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQTtRQUNsRCxNQUFNLFlBQVksR0FDaEIsV0FBVyxLQUFLLElBQUk7WUFDcEIsV0FBVyxLQUFLLFNBQVM7WUFDekIsT0FBTyxXQUFXLEtBQUssUUFBUTtZQUMvQixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDO1lBQ3pCLENBQUMsQ0FBRSxXQUF1QztZQUMxQyxDQUFDLENBQUMsSUFBSSxDQUFBO1FBRVYsT0FBTztZQUNMLGdCQUFnQixFQUFFLElBQUksQ0FBQyxFQUFFO1lBQ3pCLFdBQVcsRUFDVCxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUk7Z0JBQ3JCLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxVQUFVLEtBQUssUUFBUTtvQkFDbkMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVO29CQUNqQixDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLEVBQUU7Z0JBQ2pDLENBQUMsQ0FBQyxJQUFJO1lBQ1YseUJBQXlCLEVBQUUsWUFBWTtZQUN2QyxRQUFRLEVBQUU7Z0JBQ1IsRUFBRSxFQUFFLElBQUksQ0FBQyxXQUFXO2dCQUNwQixLQUFLLEVBQUUsQ0FBQyxFQUFFLEtBQUssSUFBSSxJQUFJO2dCQUN2QixVQUFVLEVBQUUsQ0FBQyxFQUFFLFVBQVUsSUFBSSxJQUFJO2dCQUNqQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLFNBQVMsSUFBSSxJQUFJO2dCQUMvQixLQUFLLEVBQUUsQ0FBQyxFQUFFLEtBQUssSUFBSSxJQUFJO2dCQUN2QixVQUFVLEVBQUUsQ0FBQyxFQUFFLFVBQVUsSUFBSSxJQUFJO2FBQ2xDO1NBQ0YsQ0FBQTtJQUNILENBQUMsQ0FBQyxDQUFBO0lBRUYsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFBO0FBQ3BDLENBQUMsQ0FBQTtBQTlEWSxRQUFBLEdBQUcsT0E4RGYifQ==
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ReferralLinkModuleService = exports.REFERRAL_LINK_MODULE = void 0;
|
|
7
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
8
|
+
const service_1 = __importDefault(require("./service"));
|
|
9
|
+
exports.ReferralLinkModuleService = service_1.default;
|
|
10
|
+
exports.REFERRAL_LINK_MODULE = "referral_link";
|
|
11
|
+
exports.default = (0, utils_1.Module)(exports.REFERRAL_LINK_MODULE, {
|
|
12
|
+
service: service_1.default,
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9yZWZlcnJhbC1saW5rL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHFEQUFrRDtBQUNsRCx3REFBaUQ7QUFReEMsb0NBUkYsaUJBQXlCLENBUUU7QUFOckIsUUFBQSxvQkFBb0IsR0FBRyxlQUFlLENBQUE7QUFFbkQsa0JBQWUsSUFBQSxjQUFNLEVBQUMsNEJBQW9CLEVBQUU7SUFDMUMsT0FBTyxFQUFFLGlCQUF5QjtDQUNuQyxDQUFDLENBQUEifQ==
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Migration20260502100000CreateReferralLinkTable = void 0;
|
|
4
|
+
const migrations_1 = require("@mikro-orm/migrations");
|
|
5
|
+
/**
|
|
6
|
+
* Referral link for a referred customer (child) to their upline.
|
|
7
|
+
* Uses IF NOT EXISTS so the same table can be shared if both `customer-registration`
|
|
8
|
+
* and `medusa-referral-affiliate` register a `referral_link` module (whichever
|
|
9
|
+
* migration runs first creates the table; the other no-ops).
|
|
10
|
+
*/
|
|
11
|
+
class Migration20260502100000CreateReferralLinkTable extends migrations_1.Migration {
|
|
12
|
+
async up() {
|
|
13
|
+
this.addSql(`
|
|
14
|
+
CREATE TABLE IF NOT EXISTS "referral_link" (
|
|
15
|
+
"id" TEXT NOT NULL,
|
|
16
|
+
"customer_id" TEXT NOT NULL,
|
|
17
|
+
"referrer_id" TEXT NOT NULL,
|
|
18
|
+
"parent_customers_by_level" JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
19
|
+
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
|
20
|
+
"updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
|
21
|
+
"deleted_at" TIMESTAMP WITH TIME ZONE NULL,
|
|
22
|
+
CONSTRAINT "referral_link_pkey" PRIMARY KEY ("id"),
|
|
23
|
+
CONSTRAINT "referral_link_no_self" CHECK ("customer_id" <> "referrer_id"),
|
|
24
|
+
CONSTRAINT "referral_link_ids_nonempty" CHECK (
|
|
25
|
+
length(trim("customer_id")) > 0 AND length(trim("referrer_id")) > 0
|
|
26
|
+
),
|
|
27
|
+
CONSTRAINT "referral_link_parent_customers_by_level_is_object_chk" CHECK (
|
|
28
|
+
jsonb_typeof("parent_customers_by_level") = 'object'
|
|
29
|
+
)
|
|
30
|
+
);
|
|
31
|
+
`);
|
|
32
|
+
this.addSql(`
|
|
33
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "IDX_referral_link_customer_unique"
|
|
34
|
+
ON "referral_link" ("customer_id")
|
|
35
|
+
WHERE deleted_at IS NULL;
|
|
36
|
+
`);
|
|
37
|
+
this.addSql(`
|
|
38
|
+
CREATE INDEX IF NOT EXISTS "IDX_referral_link_referrer_id"
|
|
39
|
+
ON "referral_link" ("referrer_id")
|
|
40
|
+
WHERE deleted_at IS NULL;
|
|
41
|
+
`);
|
|
42
|
+
this.addSql(`
|
|
43
|
+
CREATE INDEX IF NOT EXISTS "IDX_referral_link_deleted_at"
|
|
44
|
+
ON "referral_link" ("deleted_at")
|
|
45
|
+
WHERE deleted_at IS NULL;
|
|
46
|
+
`);
|
|
47
|
+
}
|
|
48
|
+
async down() {
|
|
49
|
+
this.addSql(`DROP INDEX IF EXISTS "IDX_referral_link_deleted_at";`);
|
|
50
|
+
this.addSql(`DROP INDEX IF EXISTS "IDX_referral_link_referrer_id";`);
|
|
51
|
+
this.addSql(`DROP INDEX IF EXISTS "IDX_referral_link_customer_unique";`);
|
|
52
|
+
this.addSql(`DROP TABLE IF EXISTS "referral_link";`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.Migration20260502100000CreateReferralLinkTable = Migration20260502100000CreateReferralLinkTable;
|
|
56
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWlncmF0aW9uMjAyNjA1MDIxMDAwMDBDcmVhdGVSZWZlcnJhbExpbmtUYWJsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL3JlZmVycmFsLWxpbmsvbWlncmF0aW9ucy9NaWdyYXRpb24yMDI2MDUwMjEwMDAwMENyZWF0ZVJlZmVycmFsTGlua1RhYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHNEQUFpRDtBQUVqRDs7Ozs7R0FLRztBQUNILE1BQWEsOENBQStDLFNBQVEsc0JBQVM7SUFDM0UsS0FBSyxDQUFDLEVBQUU7UUFDTixJQUFJLENBQUMsTUFBTSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7S0FrQlgsQ0FBQyxDQUFBO1FBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQzs7OztLQUlYLENBQUMsQ0FBQTtRQUNGLElBQUksQ0FBQyxNQUFNLENBQUM7Ozs7S0FJWCxDQUFDLENBQUE7UUFDRixJQUFJLENBQUMsTUFBTSxDQUFDOzs7O0tBSVgsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFJO1FBQ1IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxzREFBc0QsQ0FBQyxDQUFBO1FBQ25FLElBQUksQ0FBQyxNQUFNLENBQUMsdURBQXVELENBQUMsQ0FBQTtRQUNwRSxJQUFJLENBQUMsTUFBTSxDQUFDLDJEQUEyRCxDQUFDLENBQUE7UUFDeEUsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFBO0lBQ3RELENBQUM7Q0FDRjtBQTVDRCx3R0E0Q0MifQ==
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReferralLink = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
exports.ReferralLink = utils_1.model
|
|
6
|
+
.define("referral_link", {
|
|
7
|
+
id: utils_1.model.id().primaryKey(),
|
|
8
|
+
customer_id: utils_1.model.text().searchable(),
|
|
9
|
+
referrer_id: utils_1.model.text().searchable(),
|
|
10
|
+
/**
|
|
11
|
+
* Upline keyed by referral distance: `"1"` = direct parent (same as `referrer_id`),
|
|
12
|
+
* `"2"` = next upline, etc. Example: `{ "1": "cus_123", "2": "cus_456", "3": "cus_789" }`.
|
|
13
|
+
*/
|
|
14
|
+
parent_customers_by_level: utils_1.model.json(),
|
|
15
|
+
})
|
|
16
|
+
.indexes([
|
|
17
|
+
{
|
|
18
|
+
name: "IDX_referral_link_customer_unique",
|
|
19
|
+
on: ["customer_id"],
|
|
20
|
+
unique: true,
|
|
21
|
+
where: "deleted_at IS NULL",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: "IDX_referral_link_referrer_id",
|
|
25
|
+
on: ["referrer_id"],
|
|
26
|
+
where: "deleted_at IS NULL",
|
|
27
|
+
},
|
|
28
|
+
]);
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmZXJyYWwtbGluay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL3JlZmVycmFsLWxpbmsvbW9kZWxzL3JlZmVycmFsLWxpbmsudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscURBQWlEO0FBRXBDLFFBQUEsWUFBWSxHQUFHLGFBQUs7S0FDOUIsTUFBTSxDQUFDLGVBQWUsRUFBRTtJQUN2QixFQUFFLEVBQUUsYUFBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLFVBQVUsRUFBRTtJQUMzQixXQUFXLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFVBQVUsRUFBRTtJQUN0QyxXQUFXLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFVBQVUsRUFBRTtJQUN0Qzs7O09BR0c7SUFDSCx5QkFBeUIsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFO0NBQ3hDLENBQUM7S0FDRCxPQUFPLENBQUM7SUFDUDtRQUNFLElBQUksRUFBRSxtQ0FBbUM7UUFDekMsRUFBRSxFQUFFLENBQUMsYUFBYSxDQUFDO1FBQ25CLE1BQU0sRUFBRSxJQUFJO1FBQ1osS0FBSyxFQUFFLG9CQUFvQjtLQUM1QjtJQUNEO1FBQ0UsSUFBSSxFQUFFLCtCQUErQjtRQUNyQyxFQUFFLEVBQUUsQ0FBQyxhQUFhLENBQUM7UUFDbkIsS0FBSyxFQUFFLG9CQUFvQjtLQUM1QjtDQUNGLENBQUMsQ0FBQSJ9
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
const referral_link_1 = require("./models/referral-link");
|
|
5
|
+
class ReferralLinkModuleService extends (0, utils_1.MedusaService)({
|
|
6
|
+
ReferralLink: referral_link_1.ReferralLink,
|
|
7
|
+
}) {
|
|
8
|
+
constructor(container, moduleOptions, moduleDeclaration) {
|
|
9
|
+
super(container, moduleOptions, moduleDeclaration);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.default = ReferralLinkModuleService;
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL3JlZmVycmFsLWxpbmsvc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFEQUF5RDtBQUV6RCwwREFBcUQ7QUFNckQsTUFBcUIseUJBQTBCLFNBQVEsSUFBQSxxQkFBYSxFQUFDO0lBQ25FLFlBQVksRUFBWiw0QkFBWTtDQUNiLENBQUM7SUFDQSxZQUNFLFNBQStCLEVBQy9CLGFBQXVDLEVBQ3ZDLGlCQUF5RDtRQUV6RCxLQUFLLENBQUMsU0FBUyxFQUFFLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxDQUFBO0lBQ3BELENBQUM7Q0FDRjtBQVZELDRDQVVDIn0=
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "customer-registration",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.124",
|
|
4
4
|
"description": "Medusa plugin that overrides store customer registration, enforces email/phone verification flags, and provides OTP management module.",
|
|
5
5
|
"author": "Medusa (https://medusajs.com)",
|
|
6
6
|
"license": "MIT",
|