Skip to content

Commit f1750d6

Browse files
committed
scope queries, extract shared helpers, fix group cleanup safety
1 parent b367b7a commit f1750d6

File tree

5 files changed

+142
-111
lines changed

5 files changed

+142
-111
lines changed

apps/web/scripts/dev/data.json

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"workspace": {
3-
"id": "ws_clrei1gld0002vs9mzn93p8ik",
3+
"id": "ws_1KETZ919F83ZJH6A80HWEHW6E",
44
"name": "Acme, Inc.",
55
"slug": "acme",
66
"logo": "https://assets.dub.co/logo.png",
@@ -15,7 +15,7 @@
1515
"usersLimit": 100,
1616
"aiLimit": 100,
1717
"groupsLimit": 100,
18-
"defaultProgramId": "prog_CYCu7IMAapjkRpTnr8F1azjN",
18+
"defaultProgramId": "prog_1K2J9DRWPPJ2F1RX53N92TSGA",
1919
"invoicePrefix": "ACME",
2020
"conversionEnabled": true,
2121
"webhookEnabled": true,
@@ -24,7 +24,7 @@
2424
},
2525
"users": [
2626
{
27-
"id": "clxz1q7c7000hbqx5ckv4r82h",
27+
"id": "user_cludszk1h0000wmd2e0ea2b0p",
2828
"name": "Owner",
2929
"email": "owner@dub-internal-test.com",
3030
"emailVerified": "2026-01-21T00:00:00.000Z",
@@ -89,7 +89,7 @@
8989
],
9090
"groups": [
9191
{
92-
"id": "grp_1K2E25381GVMG7HHM057TB92F",
92+
"id": "grp_1K2J9DRWPPJ2F1RX53N92TSGC",
9393
"name": "Default Group",
9494
"slug": "default",
9595
"color": null,
@@ -103,64 +103,95 @@
103103
],
104104
"defaultLinks": [
105105
{
106-
"url": "https://github.com/dubinc"
106+
"url": "https://acme.com"
107+
},
108+
{
109+
"url": "https://example.com"
107110
}
108111
]
109112
}
110113
],
111114
"program": {
112-
"id": "prog_CYCu7IMAapjkRpTnr8F1azjN",
115+
"id": "prog_1K2J9DRWPPJ2F1RX53N92TSGA",
113116
"name": "Acme",
114117
"slug": "acme",
115118
"defaultFolderId": "fold_1K2J9DRWPPJ2F1RX53N92TSGB",
116-
"defaultGroupId": "grp_1K2E25381GVMG7HHM057TB92F",
119+
"defaultGroupId": "grp_1K2J9DRWPPJ2F1RX53N92TSGC",
117120
"domain": "dub.sh",
118-
"url": "https://acme.dub.sh/",
121+
"url": "https://acme.com",
119122
"termsUrl": "https://acme.com/terms",
120123
"helpUrl": "https://acme.com/help",
121124
"supportEmail": "support@acme.com",
122125
"logo": "https://assets.dub.co/logo.png"
123126
},
124127
"partners": [
125128
{
126-
"id": "pn_H4TB2V5hDIjpqB7PwrxESoY3",
127-
"name": "Steven",
128-
"email": "steven@dub.co",
129-
"description": "E2E Test Partner",
129+
"id": "pn_1K2J9DRWPPJ2F1RX53N92TSGD",
130+
"name": "Partner 1",
131+
"email": "partner1@dub-internal-test.com",
132+
"description": "Partner 1 description",
130133
"country": "US",
131134
"createdAt": "2026-01-21T00:00:00.000Z",
132135
"user": {
133136
"id": "user_cl8dea8g1073109m7wkwlldqj",
134-
"name": "Steven",
135-
"email": "steven@dub.co",
137+
"name": "Partner 1",
138+
"email": "partner1@dub-internal-test.com",
136139
"emailVerified": "2026-01-21T00:00:00.000Z"
137140
}
138141
},
139142
{
140-
"id": "pn_NNG3YjwhLhA7nCZSaXeLIsWu",
141-
"name": "Marvin",
142-
"email": "marvin@dub-internal-test.com",
143-
"description": "E2E Test Partner - US",
143+
"id": "pn_1K2J9DRWPPJ2F1RX53N92TSGE",
144+
"name": "Partner 2",
145+
"email": "partner2@dub-internal-test.com",
146+
"description": "Partner 2 description",
144147
"country": "US",
145148
"createdAt": "2026-01-21T00:00:00.000Z",
146149
"user": {
147150
"id": "user_cludszk1h0000wmd2e0ea2b0t",
148-
"name": "Marvin",
149-
"email": "marvin@dub-internal-test.com",
151+
"name": "Partner 2",
152+
"email": "partner2@dub-internal-test.com",
150153
"emailVerified": "2026-01-21T00:00:00.000Z"
151154
}
152155
},
153156
{
154-
"id": "pn_1K8ND11BZ4XPEX39QX3YMBGY0",
155-
"name": "Kiran E2E",
156-
"email": "kiran+e2e+1@dub.co",
157-
"description": "E2E Test Partner - SG",
158-
"country": "SG",
157+
"id": "pn_1K2J9DRWPPJ2F1RX53N92TSGF",
158+
"name": "Partner 3",
159+
"email": "partner3@dub-internal-test.com",
160+
"description": "Partner 3 description",
161+
"country": "US",
159162
"createdAt": "2026-01-21T00:00:00.000Z",
160163
"user": {
161164
"id": "user_cludszk1h0000wmd2e0ea2b0u",
162-
"name": "Kiran E2E",
163-
"email": "kiran+e2e+1@dub.co",
165+
"name": "Partner 3",
166+
"email": "partner3@dub-internal-test.com",
167+
"emailVerified": "2026-01-21T00:00:00.000Z"
168+
}
169+
},
170+
{
171+
"id": "pn_1K2J9DRWPPJ2F1RX53N92TSGG",
172+
"name": "Partner 4",
173+
"email": "partner4@dub-internal-test.com",
174+
"description": "Partner 4 description",
175+
"country": "US",
176+
"createdAt": "2026-01-21T00:00:00.000Z",
177+
"user": {
178+
"id": "user_cludszk1h0000wmd2e0ea2b0v",
179+
"name": "Partner 4",
180+
"email": "partner4@dub-internal-test.com",
181+
"emailVerified": "2026-01-21T00:00:00.000Z"
182+
}
183+
},
184+
{
185+
"id": "pn_1K2J9DRWPPJ2F1RX53N92TSGH",
186+
"name": "Partner 5",
187+
"email": "partner5@dub-internal-test.com",
188+
"description": "Partner 5 description",
189+
"country": "US",
190+
"createdAt": "2026-01-21T00:00:00.000Z",
191+
"user": {
192+
"id": "user_cludszk1h0000wmd2e0ea2b0w",
193+
"name": "Partner 5",
194+
"email": "partner5@dub-internal-test.com",
164195
"emailVerified": "2026-01-21T00:00:00.000Z"
165196
}
166197
}

apps/web/tests/utils/verify-commission.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { expect } from "vitest";
22
import { prisma } from "./prisma";
3+
import { E2E_PROGRAM, E2E_WORKSPACE_ID } from "./resource";
34

45
interface VerifyCommissionProps {
56
customerExternalId?: string;
@@ -19,10 +20,15 @@ export const verifyCommission = async ({
1920
}: VerifyCommissionProps) => {
2021
let customerId: string | undefined;
2122

22-
// Resolve customer ID first if customerExternalId is given
23+
// Resolve customer ID (scoped by projectId — externalId is unique per project)
2324
if (customerExternalId) {
24-
const customer = await prisma.customer.findFirst({
25-
where: { externalId: customerExternalId },
25+
const customer = await prisma.customer.findUnique({
26+
where: {
27+
projectId_externalId: {
28+
projectId: E2E_WORKSPACE_ID,
29+
externalId: customerExternalId,
30+
},
31+
},
2632
select: { id: true },
2733
});
2834

@@ -36,6 +42,7 @@ export const verifyCommission = async ({
3642
while (Date.now() - startTime < TIMEOUT_MS) {
3743
const commission = await prisma.commission.findFirst({
3844
where: {
45+
programId: E2E_PROGRAM.id,
3946
...(customerId && { customerId }),
4047
...(invoiceId && { invoiceId }),
4148
},
@@ -66,6 +73,6 @@ export const verifyCommission = async ({
6673
// Timeout reached - fail the test
6774
throw new Error(
6875
`Commission not found within ${TIMEOUT_MS / 1000} seconds. ` +
69-
`customerId: ${customerId}, invoiceId: ${invoiceId}`,
76+
`programId: ${E2E_PROGRAM.id}, customerId: ${customerId}, invoiceId: ${invoiceId}`,
7077
);
7178
};

apps/web/tests/workflows/award-bounty-workflow.test.ts

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,9 @@ import { prisma } from "../utils/prisma";
44
import { describe, expect, test, onTestFinished } from "vitest";
55
import { randomEmail } from "../utils/helpers";
66
import { IntegrationHarness } from "../utils/integration";
7-
import { E2E_TRACK_CLICK_HEADERS } from "../utils/resource";
7+
import { trackLeads } from "./utils/track-leads";
88
import { verifyBountySubmission } from "./utils/verify-bounty-submission";
99

10-
async function trackLeads(
11-
http: any,
12-
partnerLink: { domain: string; key: string },
13-
count: number,
14-
) {
15-
for (let i = 0; i < count; i++) {
16-
const { status: clickStatus, data: clickData } = await http.post({
17-
path: "/track/click",
18-
headers: E2E_TRACK_CLICK_HEADERS,
19-
body: {
20-
domain: partnerLink.domain,
21-
key: partnerLink.key,
22-
},
23-
});
24-
25-
expect(clickStatus).toEqual(200);
26-
expect(clickData.clickId).toBeDefined();
27-
28-
const { status: leadStatus } = await http.post({
29-
path: "/track/lead",
30-
body: {
31-
clickId: clickData.clickId,
32-
eventName: `Signup-${i}-${Date.now()}`,
33-
customerExternalId: `e2e-customer-${i}-${Date.now()}`,
34-
customerEmail: `customer${i}@example.com`,
35-
},
36-
});
37-
38-
expect(leadStatus).toEqual(200);
39-
40-
await new Promise((resolve) => setTimeout(resolve, 200));
41-
}
42-
}
43-
4410
describe.sequential("Workflow - AwardBounty", async () => {
4511
const h = new IntegrationHarness();
4612
const { http } = await h.init();

0 commit comments

Comments
 (0)