@mohasinac/appkit 4.1.0 → 4.1.1
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/dist/features/tester/seed-data/bids-tester-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/bids-tester-seed-data.js +37 -0
- package/dist/features/tester/seed-data/coupons-tester-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/coupons-tester-seed-data.js +76 -0
- package/dist/features/tester/seed-data/events-tester-seed-data.js +50 -2
- package/dist/features/tester/seed-data/index.d.ts +3 -0
- package/dist/features/tester/seed-data/index.js +3 -0
- package/dist/features/tester/seed-data/orders-tester-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/orders-tester-seed-data.js +265 -0
- package/dist/features/tester/seed-data/products-tester-seed-data.js +213 -8
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +276 -6
- package/dist/next/api/routeHandler.js +6 -10
- package/dist/seed/index.d.ts +1 -1
- package/dist/seed/index.js +1 -1
- package/dist/seed/manifest.js +4 -4
- package/dist/seed/orders-seed-data.js +4 -0
- package/dist/seed/products-classifieds-seed-data.js +48 -5
- package/dist/seed/products-digital-codes-seed-data.js +48 -5
- package/dist/seed/products-live-items-seed-data.js +6 -1
- package/dist/seed/products-prize-draws-seed-data.js +58 -5
- package/package.json +1 -1
- package/scripts/seed-cli.mjs +10 -4
|
@@ -21,6 +21,10 @@ import { seedExtMedia } from "../../../seed/_helpers/media";
|
|
|
21
21
|
import { testDataExpiresAt } from "./tester-ttl";
|
|
22
22
|
const TESTER_STORE_ID = "store-tester-sandbox";
|
|
23
23
|
const TESTER_STORE_NAME = "Tester Sandbox Store";
|
|
24
|
+
const GADGETS_CATEGORY_SLUGS = ["category-tester-gadgets", "category-tester-sandbox"];
|
|
25
|
+
const GADGETS_CATEGORY_NAMES = ["Test Gadgets", "Tester Sandbox"];
|
|
26
|
+
const COLLECTIBLES_CATEGORY_SLUGS = ["category-tester-collectibles", "category-tester-sandbox"];
|
|
27
|
+
const COLLECTIBLES_CATEGORY_NAMES = ["Test Collectibles", "Tester Sandbox"];
|
|
24
28
|
function withTokens(p) {
|
|
25
29
|
return {
|
|
26
30
|
tags: [],
|
|
@@ -39,8 +43,8 @@ export const productsTesterSeedData = [
|
|
|
39
43
|
slug: "product-tester-standard-1",
|
|
40
44
|
title: "Test Gadget — Standard Listing #1",
|
|
41
45
|
description: "Disposable test product for the tester QA program. Buy it, review it, wishlist it — it auto-expires in 7 days.",
|
|
42
|
-
categorySlugs:
|
|
43
|
-
categoryNames:
|
|
46
|
+
categorySlugs: GADGETS_CATEGORY_SLUGS,
|
|
47
|
+
categoryNames: GADGETS_CATEGORY_NAMES,
|
|
44
48
|
brandSlug: "brand-tester-sandbox",
|
|
45
49
|
brand: "TestBrand",
|
|
46
50
|
price: 199,
|
|
@@ -65,8 +69,8 @@ export const productsTesterSeedData = [
|
|
|
65
69
|
slug: "product-tester-standard-2",
|
|
66
70
|
title: "Test Collectible — Standard Listing #2",
|
|
67
71
|
description: "Second disposable test product, referenced by the test bundle. Auto-expires in 7 days.",
|
|
68
|
-
categorySlugs:
|
|
69
|
-
categoryNames:
|
|
72
|
+
categorySlugs: COLLECTIBLES_CATEGORY_SLUGS,
|
|
73
|
+
categoryNames: COLLECTIBLES_CATEGORY_NAMES,
|
|
70
74
|
brandSlug: "brand-tester-sandbox",
|
|
71
75
|
brand: "TestBrand",
|
|
72
76
|
price: 149,
|
|
@@ -91,8 +95,8 @@ export const productsTesterSeedData = [
|
|
|
91
95
|
slug: "auction-tester-sandbox-1",
|
|
92
96
|
title: "Test Auction — Bid Me!",
|
|
93
97
|
description: "Disposable test auction for the tester QA program. Place a bid — it auto-expires in 7 days, cascading to any bids.",
|
|
94
|
-
categorySlugs:
|
|
95
|
-
categoryNames:
|
|
98
|
+
categorySlugs: COLLECTIBLES_CATEGORY_SLUGS,
|
|
99
|
+
categoryNames: COLLECTIBLES_CATEGORY_NAMES,
|
|
96
100
|
brandSlug: "brand-tester-sandbox",
|
|
97
101
|
brand: "TestBrand",
|
|
98
102
|
startingBid: 15000,
|
|
@@ -117,13 +121,45 @@ export const productsTesterSeedData = [
|
|
|
117
121
|
createdAt: new Date(),
|
|
118
122
|
updatedAt: new Date(),
|
|
119
123
|
}),
|
|
124
|
+
withTokens({
|
|
125
|
+
id: "auction-tester-sandbox-won",
|
|
126
|
+
slug: "auction-tester-sandbox-won",
|
|
127
|
+
title: "Test Auction — Already Won",
|
|
128
|
+
description: "Disposable test auction, already ended and won, paired with a \"won auction\" test order. Auto-expires in 7 days, cascading to its bid.",
|
|
129
|
+
categorySlugs: COLLECTIBLES_CATEGORY_SLUGS,
|
|
130
|
+
categoryNames: COLLECTIBLES_CATEGORY_NAMES,
|
|
131
|
+
brandSlug: "brand-tester-sandbox",
|
|
132
|
+
brand: "TestBrand",
|
|
133
|
+
startingBid: 8000,
|
|
134
|
+
currentBid: 15000,
|
|
135
|
+
currency: "INR",
|
|
136
|
+
price: 150,
|
|
137
|
+
stockQuantity: 1,
|
|
138
|
+
availableQuantity: 0,
|
|
139
|
+
auctionEndDate: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000),
|
|
140
|
+
bidCount: 1,
|
|
141
|
+
bidsHaveStarted: true,
|
|
142
|
+
leadingBidderId: "user-tester-qa",
|
|
143
|
+
isSold: true,
|
|
144
|
+
mainImage: seedExtMedia("https://picsum.photos/seed/auction-image-tester-sandbox-won-20260101/900/900"),
|
|
145
|
+
images: [seedExtMedia("https://picsum.photos/seed/auction-image-tester-sandbox-won-20260101/900/900")],
|
|
146
|
+
status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
|
|
147
|
+
condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
|
|
148
|
+
listingType: "auction",
|
|
149
|
+
customFields: [],
|
|
150
|
+
customSections: [],
|
|
151
|
+
isPromoted: false,
|
|
152
|
+
isOnSale: false,
|
|
153
|
+
createdAt: new Date(),
|
|
154
|
+
updatedAt: new Date(),
|
|
155
|
+
}),
|
|
120
156
|
withTokens({
|
|
121
157
|
id: "preorder-tester-sandbox-1",
|
|
122
158
|
slug: "preorder-tester-sandbox-1",
|
|
123
159
|
title: "Test Pre-order — Reserve Me!",
|
|
124
160
|
description: "Disposable test pre-order for the tester QA program. Auto-expires in 7 days.",
|
|
125
|
-
categorySlugs:
|
|
126
|
-
categoryNames:
|
|
161
|
+
categorySlugs: GADGETS_CATEGORY_SLUGS,
|
|
162
|
+
categoryNames: GADGETS_CATEGORY_NAMES,
|
|
127
163
|
brandSlug: "brand-tester-sandbox",
|
|
128
164
|
brand: "TestBrand",
|
|
129
165
|
price: 299,
|
|
@@ -148,4 +184,173 @@ export const productsTesterSeedData = [
|
|
|
148
184
|
createdAt: new Date(),
|
|
149
185
|
updatedAt: new Date(),
|
|
150
186
|
}),
|
|
187
|
+
withTokens({
|
|
188
|
+
id: "prizedraw-tester-sandbox-1",
|
|
189
|
+
slug: "prizedraw-tester-sandbox-1",
|
|
190
|
+
title: "Test Prize Draw — Reveal Me!",
|
|
191
|
+
description: "Disposable test prize-draw for the tester QA program. Buy an entry, then reveal — auto-expires in 7 days.",
|
|
192
|
+
categorySlugs: COLLECTIBLES_CATEGORY_SLUGS,
|
|
193
|
+
categoryNames: COLLECTIBLES_CATEGORY_NAMES,
|
|
194
|
+
brandSlug: "brand-tester-sandbox",
|
|
195
|
+
brand: "TestBrand",
|
|
196
|
+
price: 50,
|
|
197
|
+
currency: "INR",
|
|
198
|
+
condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
|
|
199
|
+
status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
|
|
200
|
+
listingType: "prize-draw",
|
|
201
|
+
images: [seedExtMedia("https://picsum.photos/seed/prizedraw-image-tester-sandbox-1-20260101/900/900")],
|
|
202
|
+
mainImage: seedExtMedia("https://picsum.photos/seed/prizedraw-image-tester-sandbox-1-20260101/900/900"),
|
|
203
|
+
isSold: false,
|
|
204
|
+
stockQuantity: 3,
|
|
205
|
+
availableQuantity: 3,
|
|
206
|
+
customFields: [],
|
|
207
|
+
customSections: [],
|
|
208
|
+
isPromoted: false,
|
|
209
|
+
isOnSale: false,
|
|
210
|
+
prizeDrawMode: "reveal",
|
|
211
|
+
pricePerEntry: 50,
|
|
212
|
+
prizeMaxEntries: 3,
|
|
213
|
+
prizeCurrentEntries: 0,
|
|
214
|
+
prizeRevealWindowStart: new Date(),
|
|
215
|
+
prizeRevealWindowEnd: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
|
216
|
+
prizeRevealStatus: "open",
|
|
217
|
+
prizeRevealDeadlineDays: 7,
|
|
218
|
+
prizeDrawItems: [
|
|
219
|
+
{ itemNumber: 1, title: "Test Prize — Grand", description: "Disposable test grand prize.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-1-20260101/600/600")], condition: "new", estimatedValue: 500, isWon: false },
|
|
220
|
+
{ itemNumber: 2, title: "Test Prize — Runner-up", description: "Disposable test runner-up prize.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-2-20260101/600/600")], condition: "new", estimatedValue: 150, isWon: false },
|
|
221
|
+
{ itemNumber: 3, title: "Test Prize — Consolation", description: "Disposable test consolation prize.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-3-20260101/600/600")], condition: "new", estimatedValue: 20, isWon: false },
|
|
222
|
+
],
|
|
223
|
+
createdAt: new Date(),
|
|
224
|
+
updatedAt: new Date(),
|
|
225
|
+
}),
|
|
226
|
+
withTokens({
|
|
227
|
+
id: "classified-tester-sandbox-1",
|
|
228
|
+
slug: "classified-tester-sandbox-1",
|
|
229
|
+
title: "Test Classified — Contact Me!",
|
|
230
|
+
description: "Disposable test classified listing for the tester QA program. No checkout — contact the seller. Auto-expires in 7 days.",
|
|
231
|
+
categorySlugs: COLLECTIBLES_CATEGORY_SLUGS,
|
|
232
|
+
categoryNames: COLLECTIBLES_CATEGORY_NAMES,
|
|
233
|
+
brandSlug: "brand-tester-sandbox",
|
|
234
|
+
brand: "TestBrand",
|
|
235
|
+
price: 250,
|
|
236
|
+
currency: "INR",
|
|
237
|
+
condition: PRODUCT_FIELDS.CONDITION_VALUES.GOOD,
|
|
238
|
+
status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
|
|
239
|
+
listingType: "classified",
|
|
240
|
+
images: [seedExtMedia("https://picsum.photos/seed/classified-image-tester-sandbox-1-20260101/900/900")],
|
|
241
|
+
mainImage: seedExtMedia("https://picsum.photos/seed/classified-image-tester-sandbox-1-20260101/900/900"),
|
|
242
|
+
isSold: false,
|
|
243
|
+
stockQuantity: 1,
|
|
244
|
+
availableQuantity: 1,
|
|
245
|
+
customFields: [],
|
|
246
|
+
customSections: [],
|
|
247
|
+
isPromoted: false,
|
|
248
|
+
isOnSale: false,
|
|
249
|
+
classified: {
|
|
250
|
+
meetupArea: { city: "Bengaluru", locality: "Test Locality", pincode: "560001" },
|
|
251
|
+
contactMethod: "both",
|
|
252
|
+
acceptsShipping: false,
|
|
253
|
+
negotiable: true,
|
|
254
|
+
},
|
|
255
|
+
createdAt: new Date(),
|
|
256
|
+
updatedAt: new Date(),
|
|
257
|
+
}),
|
|
258
|
+
withTokens({
|
|
259
|
+
id: "digitalcode-tester-sandbox-1",
|
|
260
|
+
slug: "digitalcode-tester-sandbox-1",
|
|
261
|
+
title: "Test Digital Code — Auto-Claim!",
|
|
262
|
+
description: "Disposable test digital-code listing for the tester QA program. Auto-expires in 7 days.",
|
|
263
|
+
categorySlugs: GADGETS_CATEGORY_SLUGS,
|
|
264
|
+
categoryNames: GADGETS_CATEGORY_NAMES,
|
|
265
|
+
brandSlug: "brand-tester-sandbox",
|
|
266
|
+
brand: "TestBrand",
|
|
267
|
+
price: 99,
|
|
268
|
+
currency: "INR",
|
|
269
|
+
condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
|
|
270
|
+
status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
|
|
271
|
+
listingType: "digital-code",
|
|
272
|
+
images: [seedExtMedia("https://picsum.photos/seed/digitalcode-image-tester-sandbox-1-20260101/900/900")],
|
|
273
|
+
mainImage: seedExtMedia("https://picsum.photos/seed/digitalcode-image-tester-sandbox-1-20260101/900/900"),
|
|
274
|
+
isSold: false,
|
|
275
|
+
stockQuantity: 10,
|
|
276
|
+
availableQuantity: 10,
|
|
277
|
+
customFields: [],
|
|
278
|
+
customSections: [],
|
|
279
|
+
isPromoted: false,
|
|
280
|
+
isOnSale: false,
|
|
281
|
+
digitalCode: {
|
|
282
|
+
codeDeliveryMethod: "auto-claim",
|
|
283
|
+
codePoolSize: 10,
|
|
284
|
+
codesAvailable: 10,
|
|
285
|
+
redemptionInstructions: "Disposable test code — redeem at test-redeem.example for tester QA purposes only.",
|
|
286
|
+
},
|
|
287
|
+
createdAt: new Date(),
|
|
288
|
+
updatedAt: new Date(),
|
|
289
|
+
}),
|
|
290
|
+
withTokens({
|
|
291
|
+
id: "live-tester-sandbox-1",
|
|
292
|
+
slug: "live-tester-sandbox-1",
|
|
293
|
+
title: "Test Live Item — Watch Me!",
|
|
294
|
+
description: "Disposable test live-item listing for the tester QA program. Auto-expires in 7 days.",
|
|
295
|
+
categorySlugs: COLLECTIBLES_CATEGORY_SLUGS,
|
|
296
|
+
categoryNames: COLLECTIBLES_CATEGORY_NAMES,
|
|
297
|
+
brandSlug: "brand-tester-sandbox",
|
|
298
|
+
brand: "TestBrand",
|
|
299
|
+
price: 1500,
|
|
300
|
+
currency: "INR",
|
|
301
|
+
condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
|
|
302
|
+
status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
|
|
303
|
+
listingType: "live",
|
|
304
|
+
images: [seedExtMedia("https://picsum.photos/seed/live-image-tester-sandbox-1-20260101/900/900")],
|
|
305
|
+
mainImage: seedExtMedia("https://picsum.photos/seed/live-image-tester-sandbox-1-20260101/900/900"),
|
|
306
|
+
video: { url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ" },
|
|
307
|
+
isSold: false,
|
|
308
|
+
stockQuantity: 1,
|
|
309
|
+
availableQuantity: 1,
|
|
310
|
+
customFields: [],
|
|
311
|
+
customSections: [],
|
|
312
|
+
isPromoted: false,
|
|
313
|
+
isOnSale: false,
|
|
314
|
+
liveItem: {
|
|
315
|
+
species: "Test Species",
|
|
316
|
+
ageMonths: 6,
|
|
317
|
+
sex: "n/a",
|
|
318
|
+
careInfo: "Disposable test care info for the tester QA program.",
|
|
319
|
+
transport: { method: "courier", handlingFee: 100, insuranceIncluded: true },
|
|
320
|
+
jurisdictionAllowed: ["IN-KA", "IN-MH"],
|
|
321
|
+
vendorVerified: true,
|
|
322
|
+
},
|
|
323
|
+
createdAt: new Date(),
|
|
324
|
+
updatedAt: new Date(),
|
|
325
|
+
}),
|
|
326
|
+
withTokens({
|
|
327
|
+
id: "group-tester-sandbox-bundle",
|
|
328
|
+
slug: "group-tester-sandbox-bundle",
|
|
329
|
+
title: "Test Bundle — Standard #1 + Standard #2",
|
|
330
|
+
description: "Disposable test bundle bundling the two tester-sandbox standard products. Auto-expires in 7 days.",
|
|
331
|
+
categorySlugs: GADGETS_CATEGORY_SLUGS,
|
|
332
|
+
categoryNames: GADGETS_CATEGORY_NAMES,
|
|
333
|
+
brandSlug: "brand-tester-sandbox",
|
|
334
|
+
brand: "TestBrand",
|
|
335
|
+
price: 329,
|
|
336
|
+
currency: "INR",
|
|
337
|
+
condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
|
|
338
|
+
status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
|
|
339
|
+
listingType: "standard",
|
|
340
|
+
images: [seedExtMedia("https://picsum.photos/seed/product-image-tester-standard-1-20260101/900/900")],
|
|
341
|
+
mainImage: seedExtMedia("https://picsum.photos/seed/product-image-tester-standard-1-20260101/900/900"),
|
|
342
|
+
isSold: false,
|
|
343
|
+
stockQuantity: 5,
|
|
344
|
+
availableQuantity: 5,
|
|
345
|
+
customFields: [],
|
|
346
|
+
customSections: [],
|
|
347
|
+
isPromoted: false,
|
|
348
|
+
isOnSale: false,
|
|
349
|
+
isGroupParent: true,
|
|
350
|
+
groupId: "group-tester-sandbox-bundle",
|
|
351
|
+
groupTitle: "Tester Sandbox Bundle",
|
|
352
|
+
groupChildSlugs: ["product-tester-standard-1", "product-tester-standard-2"],
|
|
353
|
+
createdAt: new Date(),
|
|
354
|
+
updatedAt: new Date(),
|
|
355
|
+
}),
|
|
151
356
|
];
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* WHY: Seeds the initial tester QA checklist catalog — DB-backed, admin-manageable (mirrors faq-seed-data.ts).
|
|
3
|
-
* WHAT:
|
|
4
|
-
* Community & Support, Design & UX). Admins add/edit
|
|
5
|
-
* this array is a starting point, not the source of
|
|
6
|
-
* route in the Tester Hub (/user/tester), which any
|
|
3
|
+
* WHAT: Default test cases across 8 groups (Account & Auth, Buying, Selling, Content & Discovery,
|
|
4
|
+
* Community & Support, Design & UX, Public & Marketing Pages, Admin (Testing)). Admins add/edit
|
|
5
|
+
* further cases via /admin/tester-checklist — this array is a starting point, not the source of
|
|
6
|
+
* truth. Every case is searchable by title or route in the Tester Hub (/user/tester), which any
|
|
7
|
+
* isTester account OR admin can open. Items in the "admin" group carry adminOnly:true — only
|
|
8
|
+
* visible to a tester with canTestAdmin (or a real admin); see `group()`'s `opts.adminOnly`.
|
|
7
9
|
*
|
|
8
10
|
* EXPORTS:
|
|
9
11
|
* testerChecklistSeedData — Array of Partial<TesterChecklistItemDocument> for seed runner
|
|
@@ -106,14 +108,29 @@ export const testerChecklistSeedData = [
|
|
|
106
108
|
pageLabel: "Buying & Checkout",
|
|
107
109
|
cases: [
|
|
108
110
|
{ key: "add-to-cart", label: "Add to cart works from the product page" },
|
|
111
|
+
{ key: "add-to-cart-out-of-stock", label: "Add to cart is disabled/blocked once a listing's stock reaches zero" },
|
|
112
|
+
{ key: "add-to-cart-max-quantity", label: "Increasing quantity in the cart is capped at the listing's available stock, with a clear message" },
|
|
109
113
|
{ key: "checkout-flow", label: "Checkout flow completes without errors", href: "/cart" },
|
|
114
|
+
{ key: "checkout-order-review", label: "The order-review step before payment shows correct items, quantities, addresses, and totals" },
|
|
115
|
+
{ key: "checkout-multi-seller-split", label: "A cart with items from multiple sellers correctly splits into separate orders at checkout" },
|
|
110
116
|
{ key: "shipping-address", label: "Selecting/adding a shipping address works" },
|
|
117
|
+
{ key: "shipping-address-inline-add", label: "Adding a new address inline during checkout (without leaving the flow) works and the new address is selectable immediately" },
|
|
118
|
+
{ key: "shipping-address-edit", label: "Editing an existing shipping address from checkout works" },
|
|
119
|
+
{ key: "shipping-method-selection", label: "Selecting a shipping method/provider at checkout recalculates the shipping fee correctly" },
|
|
120
|
+
{ key: "gst-breakdown-display", label: "When GST is enabled in Site Settings, checkout shows the correct CGST/SGST or IGST breakdown based on buyer vs seller state" },
|
|
111
121
|
{ key: "checkout-otp-highvalue", label: "Carts ≥ the OTP threshold prompt for email verification before placing the order (except COD)" },
|
|
122
|
+
{ key: "payment-method-selection", label: "Choosing between COD, UPI/manual, and Razorpay (when enabled) at checkout works" },
|
|
112
123
|
{ key: "payment-window-countdown", label: "Manual-payment orders show a 15-minute countdown timer on the payment page" },
|
|
113
124
|
{ key: "payment-proof-upload", label: "Uploading manual payment proof (screenshot, UTR, mark-as-paid + agreement checkboxes) works" },
|
|
125
|
+
{ key: "payment-proof-reupload", label: "Requesting a proof re-upload extends the buyer's payment window and the buyer can successfully re-submit" },
|
|
114
126
|
{ key: "payment-window-expiry", label: "An order whose 15-minute payment window expires with no proof auto-cancels and the item returns to stock" },
|
|
127
|
+
{ key: "emi-checkout-flow", label: "Choosing EMI at checkout (when enabled) shows the correct tenure options, token amount, and surcharge, and creates the installment schedule" },
|
|
128
|
+
{ key: "out-of-stock-policy-cancel", label: "With the \"cancel whole order\" out-of-stock policy, checkout correctly rejects the entire batch if any item goes out of stock mid-checkout" },
|
|
129
|
+
{ key: "out-of-stock-policy-skip", label: "With the \"skip unavailable items\" policy, checkout proceeds with only the still-available items" },
|
|
115
130
|
{ key: "order-confirmation", label: "Order confirmation page/email shows correct order details" },
|
|
116
131
|
{ key: "payment-auto-approve-dispute", label: "An auto-approved order (2h, no admin review) shows the badge, and \"Raise a dispute\" submits successfully" },
|
|
132
|
+
{ key: "checkout-mobile-responsive", label: "The full checkout flow (cart → address → payment → confirmation) is usable and correctly laid out on a mobile viewport" },
|
|
133
|
+
{ key: "checkout-back-navigation", label: "Using the browser back button mid-checkout does not lose cart state or double-submit the order" },
|
|
117
134
|
],
|
|
118
135
|
},
|
|
119
136
|
{
|
|
@@ -130,9 +147,21 @@ export const testerChecklistSeedData = [
|
|
|
130
147
|
pageKey: "wishlist-history",
|
|
131
148
|
pageLabel: "Wishlist & History",
|
|
132
149
|
cases: [
|
|
133
|
-
{ key: "add-wishlist", label: "Adding a product to the wishlist works", href: "/user/wishlist" },
|
|
150
|
+
{ key: "add-wishlist-pdp", label: "Adding a product to the wishlist from the product detail page works", href: "/user/wishlist" },
|
|
151
|
+
{ key: "add-wishlist-card", label: "Adding a product to the wishlist from a listing card (checkbox/long-press) works on both listing and search pages" },
|
|
134
152
|
{ key: "remove-wishlist", label: "Removing a product from the wishlist works" },
|
|
135
|
-
{ key: "
|
|
153
|
+
{ key: "wishlist-persists-guest-to-login", label: "Wishlist items added as a guest are preserved after logging in" },
|
|
154
|
+
{ key: "wishlist-idempotent-readd", label: "Re-adding a product already on the wishlist is a no-op and doesn't create a duplicate entry" },
|
|
155
|
+
{ key: "wishlist-cap-enforced", label: "Adding a 21st item to the wishlist is blocked with a clear \"wishlist full\" message (20-item cap)" },
|
|
156
|
+
{ key: "wishlist-across-listing-types", label: "Auctions and pre-orders (not just standard products) can be added to and viewed correctly in the wishlist" },
|
|
157
|
+
{ key: "wishlist-price-drop-accuracy", label: "A wishlist item's displayed price matches the product's current price, not a stale snapshot" },
|
|
158
|
+
{ key: "wishlist-sold-out-item", label: "A wishlist item whose product later sells out or is removed still displays gracefully (no crash) with an appropriate indicator" },
|
|
159
|
+
{ key: "wishlist-empty-state", label: "The empty-wishlist state renders correctly with no items", href: "/user/wishlist" },
|
|
160
|
+
{ key: "wishlist-add-to-cart-from-list", label: "Adding a wishlist item directly to the cart from the wishlist page works" },
|
|
161
|
+
{ key: "view-history", label: "Recently viewed history shows accurate items in most-recent-first order", href: "/user/history" },
|
|
162
|
+
{ key: "history-revisit-reorders", label: "Re-visiting a product already in history removes the old entry and moves it to the front, rather than duplicating it" },
|
|
163
|
+
{ key: "history-fifo-cap", label: "History silently evicts the oldest entry once more than 50 items have been viewed (no error shown to the user)" },
|
|
164
|
+
{ key: "history-guest-merge-on-login", label: "Guest browsing history (localStorage) merges correctly with the account's history after login, deduplicated by product" },
|
|
136
165
|
],
|
|
137
166
|
},
|
|
138
167
|
{
|
|
@@ -141,7 +170,12 @@ export const testerChecklistSeedData = [
|
|
|
141
170
|
cases: [
|
|
142
171
|
{ key: "update-qty", label: "Updating item quantity in cart recalculates the total" },
|
|
143
172
|
{ key: "apply-coupon", label: "Applying a coupon code at checkout works" },
|
|
173
|
+
{ key: "remove-coupon", label: "Removing an already-applied coupon from the cart recalculates the total back down" },
|
|
144
174
|
{ key: "remove-item", label: "Removing an item from the cart works" },
|
|
175
|
+
{ key: "cart-empty-state", label: "The empty-cart state renders correctly with a clear call to action" },
|
|
176
|
+
{ key: "cart-persists-across-session", label: "Cart contents persist across a page reload and across login/logout for the same account" },
|
|
177
|
+
{ key: "cart-guest-to-login-merge", label: "A guest cart's items merge correctly into the account's cart after logging in" },
|
|
178
|
+
{ key: "cart-price-revalidated", label: "If a product's price changes after it was added to the cart, checkout uses the current price and shows the buyer the updated total" },
|
|
145
179
|
],
|
|
146
180
|
},
|
|
147
181
|
{
|
|
@@ -177,6 +211,20 @@ export const testerChecklistSeedData = [
|
|
|
177
211
|
{ key: "my-reviews", label: "\"My Reviews\" shows reviews the user has left", href: "/user/reviews" },
|
|
178
212
|
],
|
|
179
213
|
},
|
|
214
|
+
{
|
|
215
|
+
pageKey: "user-dashboard-navigation",
|
|
216
|
+
pageLabel: "User Dashboard Navigation",
|
|
217
|
+
cases: [
|
|
218
|
+
{ key: "sidebar-all-links-work", label: "Every item in the user dashboard sidebar navigates to its page without a 404 or broken layout", href: "/user" },
|
|
219
|
+
{ key: "sidebar-active-highlight", label: "The sidebar correctly highlights the currently active section as you navigate between pages" },
|
|
220
|
+
{ key: "sidebar-mobile-collapse", label: "The user dashboard sidebar collapses into a mobile-friendly menu/bottom bar on small screens" },
|
|
221
|
+
{ key: "deep-link-direct-load", label: "Directly loading a deep user dashboard URL (e.g. /user/orders/view/[id]) works without first visiting the dashboard home" },
|
|
222
|
+
{ key: "become-seller-crossnav", label: "\"Become a Seller\" (buyer) vs \"Go to my Store\" (seller) shows the correct one based on account state and navigates correctly" },
|
|
223
|
+
{ key: "browser-back-forward", label: "Browser back/forward buttons move correctly between dashboard sub-pages without breaking the layout" },
|
|
224
|
+
{ key: "logged-out-redirect", label: "Opening a user dashboard URL while logged out redirects to login, then returns to the originally requested page after signing in" },
|
|
225
|
+
{ key: "breadcrumbs-accurate", label: "Breadcrumbs (where present) on nested user dashboard pages accurately reflect the current location" },
|
|
226
|
+
],
|
|
227
|
+
},
|
|
180
228
|
]),
|
|
181
229
|
...group("selling", "Selling", [
|
|
182
230
|
{
|
|
@@ -284,6 +332,20 @@ export const testerChecklistSeedData = [
|
|
|
284
332
|
{ key: "seller-guide-pages", label: "The 5 seller guide pages (overview, capabilities, finance, listings, orders, settings) all load correctly", href: "/store/guide" },
|
|
285
333
|
],
|
|
286
334
|
},
|
|
335
|
+
{
|
|
336
|
+
pageKey: "store-dashboard-navigation",
|
|
337
|
+
pageLabel: "Store Dashboard Navigation",
|
|
338
|
+
cases: [
|
|
339
|
+
{ key: "store-sidebar-all-links-work", label: "Every item in the store/seller dashboard sidebar navigates to its page without a 404 or broken layout", href: "/store" },
|
|
340
|
+
{ key: "store-sidebar-active-highlight", label: "The store sidebar correctly highlights the currently active section as you navigate between pages" },
|
|
341
|
+
{ key: "store-sidebar-mobile-collapse", label: "The store dashboard sidebar collapses into a mobile-friendly menu/bottom bar on small screens" },
|
|
342
|
+
{ key: "store-deep-link-direct-load", label: "Directly loading a deep store dashboard URL (e.g. /store/products/[id]/edit) works without first visiting the dashboard home" },
|
|
343
|
+
{ key: "store-user-crossnav", label: "The store dashboard's cross-nav link back to the buyer dashboard works and lands on the correct page" },
|
|
344
|
+
{ key: "store-browser-back-forward", label: "Browser back/forward buttons move correctly between store dashboard sub-pages without breaking the layout" },
|
|
345
|
+
{ key: "store-logged-out-redirect", label: "Opening a store dashboard URL while logged out (or as a non-seller) redirects appropriately instead of erroring" },
|
|
346
|
+
{ key: "store-nav-listing-type-groups", label: "The seller nav correctly groups/labels each listing-type management area (standard, auctions, pre-orders, prize draws, bundles, classifieds, digital codes, live, art, stickers)" },
|
|
347
|
+
],
|
|
348
|
+
},
|
|
287
349
|
]),
|
|
288
350
|
...group("content-discovery", "Content & Discovery", [
|
|
289
351
|
{
|
|
@@ -405,4 +467,212 @@ export const testerChecklistSeedData = [
|
|
|
405
467
|
],
|
|
406
468
|
},
|
|
407
469
|
]),
|
|
470
|
+
...group("public-pages", "Public & Marketing Pages", [
|
|
471
|
+
{
|
|
472
|
+
pageKey: "core-listing-pages",
|
|
473
|
+
pageLabel: "Homepage & Core Listing Pages",
|
|
474
|
+
cases: [
|
|
475
|
+
{ key: "homepage-loads", label: "The homepage loads without errors on both desktop and mobile", href: "/" },
|
|
476
|
+
{ key: "products-listing-page", label: "The products listing page loads and paginates correctly", href: "/products" },
|
|
477
|
+
{ key: "auctions-listing-page", label: "The auctions listing page loads correctly", href: "/auctions" },
|
|
478
|
+
{ key: "preorders-listing-page", label: "The pre-orders listing page loads correctly", href: "/pre-orders" },
|
|
479
|
+
{ key: "bundles-listing-page", label: "The bundles listing page loads correctly", href: "/bundles" },
|
|
480
|
+
{ key: "categories-index", label: "The categories index page loads correctly", href: "/categories" },
|
|
481
|
+
{ key: "brands-index-detail", label: "The brands index and an individual brand detail page load correctly" },
|
|
482
|
+
],
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
pageKey: "stores-sellers-directories",
|
|
486
|
+
pageLabel: "Store & Seller Directories",
|
|
487
|
+
cases: [
|
|
488
|
+
{ key: "store-directory", label: "The store directory page loads correctly", href: "/stores" },
|
|
489
|
+
{ key: "store-detail-tabs", label: "A store detail page's auctions/bundles/coupons/pre-orders/prize-draws/reviews tabs all load correctly" },
|
|
490
|
+
{ key: "sellers-directory", label: "The sellers directory page loads correctly", href: "/sellers" },
|
|
491
|
+
{ key: "seller-detail-page", label: "An individual seller's public detail page loads correctly" },
|
|
492
|
+
{ key: "scams-registry", label: "The scams registry page and an individual scam detail page load correctly", href: "/scams" },
|
|
493
|
+
],
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
pageKey: "help-how-it-works",
|
|
497
|
+
pageLabel: "Help & How-It-Works Pages",
|
|
498
|
+
cases: [
|
|
499
|
+
{ key: "contact-page", label: "The contact page loads and the form submits correctly", href: "/contact" },
|
|
500
|
+
{ key: "help-page", label: "The help page loads correctly", href: "/help" },
|
|
501
|
+
{ key: "how-it-works-pages", label: "All 7 how-it-works pages (auctions, checkout, offers, orders, payouts, pre-orders, reviews) load correctly" },
|
|
502
|
+
{ key: "fees-page", label: "The fees page loads correctly", href: "/fees" },
|
|
503
|
+
],
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
pageKey: "legal-policy-pages",
|
|
507
|
+
pageLabel: "Legal & Policy Pages",
|
|
508
|
+
cases: [
|
|
509
|
+
{ key: "shipping-refund-policy", label: "Shipping-policy and refund-policy pages load correctly" },
|
|
510
|
+
{ key: "privacy-cookies-security", label: "Privacy, cookies, and security pages load correctly" },
|
|
511
|
+
],
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
pageKey: "auth-error-pages",
|
|
515
|
+
pageLabel: "Remaining Auth & Error Pages",
|
|
516
|
+
cases: [
|
|
517
|
+
{ key: "register-page", label: "The register page loads and account creation works", href: "/register" },
|
|
518
|
+
{ key: "forgot-reset-password-pages", label: "Forgot-password and reset-password pages both work" },
|
|
519
|
+
{ key: "verify-email-page", label: "The verify-email page correctly confirms a pending verification" },
|
|
520
|
+
{ key: "oauth-loading-redirect", label: "The OAuth-loading redirect page transitions correctly after a Google sign-in" },
|
|
521
|
+
{ key: "checkout-success-page", label: "The checkout-success page shows correct order details after payment", href: "/checkout/success" },
|
|
522
|
+
{ key: "unauthorized-404-pages", label: "Unauthorized and 404 error pages render correctly instead of crashing" },
|
|
523
|
+
],
|
|
524
|
+
},
|
|
525
|
+
]),
|
|
526
|
+
...group("admin", "Admin (Testing)", [
|
|
527
|
+
{
|
|
528
|
+
pageKey: "catalog-listings",
|
|
529
|
+
pageLabel: "Catalog & Listings",
|
|
530
|
+
cases: [
|
|
531
|
+
{ key: "brands-crud", label: "Admin can create, edit, and list brands", href: "/admin/brands" },
|
|
532
|
+
{ key: "categories-crud", label: "Admin can create, edit, and list categories", href: "/admin/categories" },
|
|
533
|
+
{ key: "products-crud", label: "Admin can create, edit, and list products", href: "/admin/products" },
|
|
534
|
+
{ key: "sublisting-categories-crud", label: "Admin can create, edit, and list sublisting categories", href: "/admin/sublisting-categories" },
|
|
535
|
+
{ key: "carousel-crud", label: "Admin can create, edit, and reorder carousel slides", href: "/admin/carousel" },
|
|
536
|
+
{ key: "sections-crud", label: "Admin can create, edit, and reorder homepage sections", href: "/admin/sections" },
|
|
537
|
+
{ key: "art-stickers-crud", label: "Admin can create, edit, and list art and sticker listings" },
|
|
538
|
+
{ key: "deals-featured-crud", label: "Admin can create, edit, and list deals and featured listings" },
|
|
539
|
+
],
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
pageKey: "coupons",
|
|
543
|
+
pageLabel: "Coupons",
|
|
544
|
+
cases: [
|
|
545
|
+
{ key: "coupon-create-percentage", label: "Admin can create a percentage-type coupon", href: "/admin/coupons/new" },
|
|
546
|
+
{ key: "coupon-create-fixed-freeship-bxgy", label: "Admin can create fixed, free_shipping, and buy_x_get_y coupon types" },
|
|
547
|
+
{ key: "coupon-per-user-limit-enforced", label: "A coupon's perUserLimit is correctly enforced at checkout after being set by admin" },
|
|
548
|
+
{ key: "coupon-min-max-discount", label: "Admin-set minPurchase and maxDiscount are correctly enforced at checkout" },
|
|
549
|
+
{ key: "coupon-scope-admin-vs-seller", label: "Admin-scope and seller-scope coupons both apply correctly, respecting scope rules" },
|
|
550
|
+
{ key: "coupon-expire-reject", label: "Expiring a coupon from the admin editor causes checkout to reject it immediately" },
|
|
551
|
+
],
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
pageKey: "events-raffles-spin",
|
|
555
|
+
pageLabel: "Events, Raffles & Spin Wheel",
|
|
556
|
+
cases: [
|
|
557
|
+
{ key: "raffle-create-open", label: "Admin can create an open_raffle event", href: "/admin/events/new" },
|
|
558
|
+
{ key: "raffle-create-top-n-scorers", label: "Admin can create a top_n_scorers raffle event" },
|
|
559
|
+
{ key: "raffle-create-top-n-participants", label: "Admin can create a top_n_participants raffle event" },
|
|
560
|
+
{ key: "raffle-draw-winner", label: "Drawing a raffle winner correctly populates raffleWinnerUserId and raffleTriggeredAt" },
|
|
561
|
+
{ key: "spin-wheel-create", label: "Admin can create a spin_wheel event with weighted prizes" },
|
|
562
|
+
{ key: "spin-wheel-limits-enforced", label: "spinMaxPerUser and spinWindowStart/End are correctly enforced once configured by admin" },
|
|
563
|
+
{ key: "event-entries-admin-view", label: "Admin event-entries list shows accurate entries", href: "/admin/event-entries" },
|
|
564
|
+
],
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
pageKey: "prize-draws-lotteries",
|
|
568
|
+
pageLabel: "Prize Draws / Lotteries",
|
|
569
|
+
cases: [
|
|
570
|
+
{ key: "prizedraw-create", label: "Admin can create a prize-draw listing", href: "/admin/prize-draws" },
|
|
571
|
+
{ key: "prizedraw-reveal-winner", label: "Admin can reveal a prize-draw winner via the crypto.randomInt reveal flow" },
|
|
572
|
+
{ key: "prizedraw-auto-refund", label: "Non-winning entries are auto-refunded correctly after a reveal" },
|
|
573
|
+
{ key: "prizedraw-lock-on-reveal", label: "Lock-on-reveal correctly blocks further entries after the draw" },
|
|
574
|
+
{ key: "prizedraw-entries-view", label: "Admin can view prize-draw / lottery entries", href: "/admin/lotteries" },
|
|
575
|
+
],
|
|
576
|
+
},
|
|
577
|
+
{
|
|
578
|
+
pageKey: "bundles",
|
|
579
|
+
pageLabel: "Bundles / Grouped Listings",
|
|
580
|
+
cases: [
|
|
581
|
+
{ key: "bundle-create", label: "Admin can create a bundle from existing products", href: "/admin/bundles" },
|
|
582
|
+
{ key: "bundle-stock-sync", label: "Bundle stock correctly syncs when a component product's stock changes" },
|
|
583
|
+
{ key: "bundle-edit-delete", label: "Admin can edit and delete a bundle" },
|
|
584
|
+
],
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
pageKey: "classifieds-digitalcodes-live",
|
|
588
|
+
pageLabel: "Classifieds, Digital Codes & Live Listings",
|
|
589
|
+
cases: [
|
|
590
|
+
{ key: "classified-create-moderate", label: "Admin can create and moderate classified listings", href: "/admin/classified" },
|
|
591
|
+
{ key: "digitalcode-create-moderate", label: "Admin can create and moderate digital-code listings", href: "/admin/digital-codes" },
|
|
592
|
+
{ key: "live-create-moderate", label: "Admin can create and moderate live-item listings", href: "/admin/live" },
|
|
593
|
+
],
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
pageKey: "blog-faqs",
|
|
597
|
+
pageLabel: "Blog & FAQs",
|
|
598
|
+
cases: [
|
|
599
|
+
{ key: "blog-create-edit-publish", label: "Admin can create, edit, and publish a blog post", href: "/admin/blog" },
|
|
600
|
+
{ key: "faq-create-edit-category", label: "Admin can create and edit an FAQ, including category assignment", href: "/admin/faqs" },
|
|
601
|
+
],
|
|
602
|
+
},
|
|
603
|
+
{
|
|
604
|
+
pageKey: "orders-fulfillment",
|
|
605
|
+
pageLabel: "Orders & Fulfillment",
|
|
606
|
+
cases: [
|
|
607
|
+
{ key: "orders-status-change", label: "Admin orders list shows accurate orders and status changes save correctly", href: "/admin/orders" },
|
|
608
|
+
{ key: "bids-admin-view", label: "Admin bids view shows accurate bid data", href: "/admin/bids" },
|
|
609
|
+
{ key: "return-requests-triage", label: "Admin can triage return requests", href: "/admin/return-requests" },
|
|
610
|
+
{ key: "fulfillment-queue-admin", label: "Admin fulfillment queue shows accurate pending items", href: "/admin/fulfillment" },
|
|
611
|
+
{ key: "shipments-crud", label: "Admin can create/edit shipments, including lots/items and projections", href: "/admin/shipments" },
|
|
612
|
+
{ key: "print-center-admin", label: "Admin print-center generates labels/invoices correctly", href: "/admin/print-center" },
|
|
613
|
+
{ key: "payouts-export-admin", label: "Admin can export payouts", href: "/admin/payouts" },
|
|
614
|
+
{ key: "bulk-action-realtime-progress", label: "A bulk admin action (e.g. bulk order status update) shows live progress via the bulk_events realtime channel and resolves without polling" },
|
|
615
|
+
],
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
pageKey: "users-trust",
|
|
619
|
+
pageLabel: "Users & Trust",
|
|
620
|
+
cases: [
|
|
621
|
+
{ key: "users-role-change", label: "Admin can change a user's role and toggle isTester/canTestAdmin", href: "/admin/users" },
|
|
622
|
+
{ key: "roles-crud", label: "Admin can create and edit custom roles", href: "/admin/roles" },
|
|
623
|
+
{ key: "sessions-revoke", label: "Admin can revoke a user's active sessions", href: "/admin/sessions" },
|
|
624
|
+
{ key: "scammers-registry-admin", label: "Admin can manage the scammer registry", href: "/admin/scammers" },
|
|
625
|
+
{ key: "banned-addresses-admin", label: "Admin can manage banned addresses", href: "/admin/banned-addresses" },
|
|
626
|
+
{ key: "address-clusters-admin", label: "Admin can view address clusters", href: "/admin/address-clusters" },
|
|
627
|
+
{ key: "moderation-queue-admin", label: "Admin moderation queue works correctly", href: "/admin/moderation" },
|
|
628
|
+
{ key: "support-tickets-triage-admin", label: "Admin can triage support tickets", href: "/admin/support-tickets" },
|
|
629
|
+
{ key: "item-requests-admin", label: "Admin can manage item requests", href: "/admin/item-requests" },
|
|
630
|
+
{ key: "reports-admin", label: "Admin reports queue works correctly", href: "/admin/reports" },
|
|
631
|
+
{ key: "payment-methods-clusters-admin", label: "Admin can manage payment methods and payment-method clusters", href: "/admin/payment-methods" },
|
|
632
|
+
{ key: "catalogue-approvals-admin", label: "Admin can approve/reject personal catalogue submissions", href: "/admin/catalogue-approvals" },
|
|
633
|
+
],
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
pageKey: "content-marketing",
|
|
637
|
+
pageLabel: "Content & Marketing",
|
|
638
|
+
cases: [
|
|
639
|
+
{ key: "ads-crud-preview", label: "Admin can create, edit, and preview ads", href: "/admin/ads" },
|
|
640
|
+
{ key: "newsletter-export-admin", label: "Admin can export the newsletter subscriber list", href: "/admin/newsletter" },
|
|
641
|
+
{ key: "contact-submissions-admin", label: "Admin can view contact form submissions", href: "/admin/contact" },
|
|
642
|
+
{ key: "media-library-admin", label: "Admin media library works correctly", href: "/admin/media" },
|
|
643
|
+
{ key: "navigation-editor-admin", label: "Admin can edit site navigation", href: "/admin/navigation" },
|
|
644
|
+
{ key: "settings-navigation-actions", label: "Admin settings/navigation and settings/actions pages save correctly" },
|
|
645
|
+
{ key: "features-feature-flags-admin", label: "Admin can manage product features and feature flags" },
|
|
646
|
+
],
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
pageKey: "site-system",
|
|
650
|
+
pageLabel: "Site & System",
|
|
651
|
+
cases: [
|
|
652
|
+
{ key: "site-settings-admin", label: "Admin site settings page saves correctly", href: "/admin/site" },
|
|
653
|
+
{ key: "admin-dashboard-widgets", label: "Admin dashboard widgets show accurate data", href: "/admin/dashboard" },
|
|
654
|
+
{ key: "analytics-admin", label: "Admin analytics dashboard shows accurate data", href: "/admin/analytics" },
|
|
655
|
+
{ key: "maintenance-pages-admin", label: "The maintenance pages (analysis, client-errors, cloud-logs, function-errors, payment-rollbacks, server-errors + detail) all load correctly", href: "/admin/maintenance" },
|
|
656
|
+
{ key: "copilot-admin", label: "Admin copilot page works correctly", href: "/admin/copilot" },
|
|
657
|
+
{ key: "team-admin", label: "Admin team page works correctly", href: "/admin/team" },
|
|
658
|
+
{ key: "guide-pages-admin", label: "The 8 admin guide pages all load correctly", href: "/admin/guide" },
|
|
659
|
+
{ key: "tester-checklist-crud-admin", label: "Admin can create, edit, and toggle adminOnly on tester checklist items", href: "/admin/tester-checklist" },
|
|
660
|
+
{ key: "tester-feedback-report-export", label: "Admin tester-feedback report shows Yes/No analytics grouped correctly and the Download Report export works", href: "/admin/tester-feedback" },
|
|
661
|
+
],
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
pageKey: "buyer-data-admin",
|
|
665
|
+
pageLabel: "Buyer-Data Admin Views",
|
|
666
|
+
cases: [
|
|
667
|
+
{ key: "carts-admin-view", label: "Admin carts view shows accurate data", href: "/admin/carts" },
|
|
668
|
+
{ key: "wishlists-admin-view", label: "Admin wishlists view shows accurate data", href: "/admin/wishlists" },
|
|
669
|
+
{ key: "history-admin-view", label: "Admin history view shows accurate data", href: "/admin/history" },
|
|
670
|
+
{ key: "notifications-admin-view", label: "Admin notifications and admin-notifications views show accurate data" },
|
|
671
|
+
{ key: "reviews-admin-view", label: "Admin reviews view shows accurate data", href: "/admin/reviews" },
|
|
672
|
+
{ key: "store-addresses-admin", label: "Admin store-addresses view shows accurate data", href: "/admin/store-addresses" },
|
|
673
|
+
{ key: "addresses-crud-admin", label: "Admin can create and edit addresses", href: "/admin/addresses" },
|
|
674
|
+
{ key: "stores-admin-view", label: "Admin stores view shows accurate data", href: "/admin/stores" },
|
|
675
|
+
],
|
|
676
|
+
},
|
|
677
|
+
], { adminOnly: true }),
|
|
408
678
|
];
|
|
@@ -188,17 +188,13 @@ export function createRouteHandler(options) {
|
|
|
188
188
|
: options.permission
|
|
189
189
|
? ["admin", "employee"]
|
|
190
190
|
: [];
|
|
191
|
-
if (effectiveRoles.length > 0) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
user.isTester = true;
|
|
196
|
-
user.canTestAdmin = true;
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
return errorJson(403, HTTP_ERROR_CODES.FORBIDDEN, "Insufficient permissions", requestId);
|
|
200
|
-
}
|
|
191
|
+
if (effectiveRoles.length > 0 && (!user || !effectiveRoles.includes(user.role ?? ""))) {
|
|
192
|
+
const testerEligible = await isTesterEligibleForAdminRoute(user, effectiveRoles);
|
|
193
|
+
if (!testerEligible || !user) {
|
|
194
|
+
return errorJson(403, HTTP_ERROR_CODES.FORBIDDEN, "Insufficient permissions", requestId);
|
|
201
195
|
}
|
|
196
|
+
user.isTester = true;
|
|
197
|
+
user.canTestAdmin = true;
|
|
202
198
|
}
|
|
203
199
|
// -- Permission check (employee fine-grained) --------------------------
|
|
204
200
|
if (options.permission && user && !isEffectiveAdminUser(user)) {
|