@mohasinac/appkit 3.1.7 → 3.2.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.
Files changed (54) hide show
  1. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +39 -9
  2. package/dist/_internal/client/features/tour/TourProvider.d.ts +12 -0
  3. package/dist/_internal/client/features/tour/TourProvider.js +19 -0
  4. package/dist/_internal/server/features/checkout/actions.js +8 -2
  5. package/dist/_internal/server/features/media/contextGuards.js +2 -2
  6. package/dist/_internal/server/features/orders/actions.d.ts +6 -0
  7. package/dist/_internal/server/features/orders/actions.js +43 -1
  8. package/dist/_internal/server/features/products/data.js +5 -1
  9. package/dist/_internal/server/jobs/core/assignSpinPrize.js +4 -0
  10. package/dist/_internal/server/jobs/core/auctionSettlement.js +4 -0
  11. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +4 -0
  12. package/dist/_internal/server/jobs/core/bundleStockSync.js +4 -0
  13. package/dist/_internal/server/jobs/core/payoutBatch.js +4 -0
  14. package/dist/_internal/server/jobs/core/prizeRevealClose.js +4 -0
  15. package/dist/_internal/server/jobs/core/prizeRevealExpiry.js +4 -0
  16. package/dist/_internal/server/jobs/core/prizeRevealOpen.js +4 -0
  17. package/dist/_internal/server/jobs/core/prizeRevealReminder.js +4 -0
  18. package/dist/_internal/server/jobs/core/promotions.js +4 -0
  19. package/dist/_internal/server/jobs/core/triggerEventRaffle.js +4 -0
  20. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +4 -0
  21. package/dist/_internal/shared/actions/action-registry.js +13 -0
  22. package/dist/_internal/shared/features/checkout/config.d.ts +1 -1
  23. package/dist/_internal/shared/features/checkout/config.js +1 -1
  24. package/dist/features/admin/components/AdminOrderEditorView.d.ts +5 -1
  25. package/dist/features/admin/components/AdminOrderEditorView.js +30 -4
  26. package/dist/features/admin/components/AdminOrdersView.js +5 -1
  27. package/dist/features/layout/AppLayoutShell.d.ts +3 -1
  28. package/dist/features/layout/AppLayoutShell.js +2 -2
  29. package/dist/features/layout/TitleBarLayout.d.ts +3 -1
  30. package/dist/features/layout/TitleBarLayout.js +3 -2
  31. package/dist/features/orders/schemas/firestore.d.ts +9 -0
  32. package/dist/features/orders/schemas/firestore.js +1 -0
  33. package/dist/features/products/components/ProductForm.js +5 -3
  34. package/dist/features/products/components/ProductGrid.js +2 -2
  35. package/dist/index.d.ts +1 -1
  36. package/dist/index.js +1 -1
  37. package/dist/next/routing/route-map.d.ts +2 -0
  38. package/dist/next/routing/route-map.js +1 -0
  39. package/dist/seed/categories-seed-data.d.ts +1 -0
  40. package/dist/seed/categories-seed-data.js +6 -0
  41. package/dist/seed/index.d.ts +1 -1
  42. package/dist/seed/index.js +1 -1
  43. package/dist/seed/orders-seed-data.js +63 -9
  44. package/dist/seed/products-standard-seed-data.js +15 -15
  45. package/dist/seed/site-settings-seed-data.js +15 -5
  46. package/dist/server.d.ts +1 -0
  47. package/dist/server.js +2 -0
  48. package/dist/styles.css +9 -1
  49. package/dist/tailwind-utilities.css +1 -1
  50. package/dist/ui/components/PaginatedSelect.js +10 -1
  51. package/dist/ui/components/PaginatedSelect.style.css +8 -0
  52. package/dist/utils/id-generators.d.ts +6 -0
  53. package/dist/utils/id-generators.js +9 -0
  54. package/package.json +1 -1
@@ -14,10 +14,11 @@ const countBadge = "absolute -top-0.5 -right-0.5 flex items-center justify-cente
14
14
  *
15
15
  * Receives all domain data as props — zero domain imports.
16
16
  */
17
- export function TitleBarLayout({ onToggleSidebar, sidebarOpen, onSearchToggle, searchOpen: _searchOpen, brandName, brandShortName: _brandShortName, siteLogoUrl, logoHref, promotionsHref, compareHref, wishlistHref, wishlistCount = 0, cartHref, cartCount = 0, profileHref, unreadNotificationCount = 0, notificationsHref, loginHref, registerHref, user, notificationSlot, devSlot, navSlot, promoStripText, isDark = false, onToggleTheme, hasDashboardNav, onToggleDashboardNav, hideSidebarToggle = false, id = "titlebar", className = "", }) {
17
+ export function TitleBarLayout({ onToggleSidebar, sidebarOpen, onSearchToggle, searchOpen: _searchOpen, brandName, brandShortName: _brandShortName, siteLogoUrl, logoHref, promotionsHref, compareHref, wishlistHref, wishlistCount = 0, cartHref, cartCount = 0, profileHref, unreadNotificationCount = 0, notificationsHref, loginHref, registerHref, user, notificationSlot, devSlot, navSlot, promoStripText, isDark = false, onToggleTheme, onTourStart, hasDashboardNav, onToggleDashboardNav, hideSidebarToggle = false, id = "titlebar", className = "", }) {
18
18
  // ── Element builders ────────────────────────────────────────────────────────
19
19
  const promotionsEl = promotionsHref ? (_jsxs(Link, { href: promotionsHref, "aria-label": "Today's deals", className: "flex items-center gap-1 px-3 py-1 rounded-full text-xs font-bold bg-primary-100 text-primary-700 dark:bg-secondary-900/40 dark:text-secondary-400 hover:bg-primary-200 dark:hover:bg-secondary-900/60 transition-colors border border-primary-200/60 dark:border-secondary-700/40", children: [_jsx("svg", { className: "w-3 h-3", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", children: _jsx("path", { d: "M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.37.86.58 1.41.58.55 0 1.05-.21 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z" }) }), _jsx(Span, { className: "hidden sm:inline", children: "Today's Deals" })] })) : null;
20
20
  const themeBtn = onToggleTheme ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": isDark ? "Switch to light mode" : "Switch to dark mode", onClick: onToggleTheme, className: iconBtn, children: isDark ? (_jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m8.66-9h-1M4.34 12h-1m15.07-6.07-.71.71M6.34 17.66l-.71.71m12.73 0-.71-.71M6.34 6.34l-.71-.71M12 5a7 7 0 1 0 0 14A7 7 0 0 0 12 5z" }) })) : (_jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 12.79A9 9 0 1 1 11.21 3a7 7 0 1 0 9.79 9.79z" }) })) })) : null;
21
+ const tourBtn = onTourStart ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": "Start product tour", onClick: onTourStart, className: iconBtn, children: _jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }) })) : null;
21
22
  const hamburgerBtn = !hideSidebarToggle ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": sidebarOpen ? "Close menu" : hasDashboardNav ? "Open dashboard navigation" : "Open menu", "aria-expanded": sidebarOpen, "aria-controls": "secondary-sidebar", onClick: hasDashboardNav && onToggleDashboardNav ? onToggleDashboardNav : onToggleSidebar, className: iconBtn, children: _jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: sidebarOpen ? (_jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" })) : (_jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 12h16M4 18h16" })) }) })) : null;
22
23
  // Compare is always lg+ (desktop-only feature, less critical on mobile)
23
24
  const compareEl = compareHref ? (_jsx(Link, { href: compareHref, "aria-label": "Compare items", className: `${iconBtn} hidden lg:flex`, children: _jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" }) }) })) : null;
@@ -34,5 +35,5 @@ export function TitleBarLayout({ onToggleSidebar, sidebarOpen, onSearchToggle, s
34
35
  // ── Render ───────────────────────────────────────────────────────────────────
35
36
  return (_jsxs(BlockHeader, { id: id, className: `sticky top-0 z-50 bg-white/95 dark:bg-slate-950/95 backdrop-blur-md border-b border-zinc-100 dark:border-slate-800 shadow-sm ${className}`, children: [promoStripText && (_jsx(Section, { color: "inverse", tone: "accent-banner", className: "text-xs text-center font-medium", padding: "y-2xs", children: promoStripText })), _jsxs(Div, { paddingX: "x-page", className: "container mx-auto max-w-[1920px]", children: [_jsxs(Row, { justify: "between", gap: "none", className: "relative h-14", children: [_jsx(Row, { gap: "3", children: _jsx(Link, { href: logoHref, "aria-label": brandName, className: "flex items-center transition-opacity hover:opacity-80", children: _jsx(SiteLogo, { title: brandName, size: "md" }) }) }), siteLogoUrl ? (_jsx(Row, { className: "absolute inset-y-0 left-1/2 -translate-x-1/2", align: "center", children: _jsx(Link, { href: logoHref, "aria-label": brandName, className: "flex items-center transition-opacity hover:opacity-80", children: _jsx(SiteLogo, { src: siteLogoUrl, title: brandName, size: "md" }) }) })) : (navSlot && _jsx(Div, { className: "hidden md:flex", children: navSlot })), _jsxs(Row, { gap: "xs", children: [devSlot, compareEl, notificationSlot, notificationsEl && _jsx(Div, { className: "hidden lg:flex", children: notificationsEl }), wishlistEl && _jsx(Div, { className: "hidden lg:flex", children: wishlistEl }), cartEl && _jsx(Div, { className: "hidden lg:flex", children: cartEl }), user
36
37
  ? profileEl && _jsx(Div, { className: "hidden lg:flex", children: profileEl })
37
- : authButtonsEl ?? (profileEl && _jsx(Div, { className: "hidden lg:flex", children: profileEl })), searchBtn, promotionsEl, themeBtn, hamburgerBtn] })] }), hasTb2 && (_jsxs(Row, { border: "subtle", as: "nav", "aria-label": "Account actions", justify: "end", gap: "xs", className: "flex lg:hidden h-10 border-t px-1", children: [notificationsEl, wishlistEl, cartEl, profileEl] }))] })] }));
38
+ : authButtonsEl ?? (profileEl && _jsx(Div, { className: "hidden lg:flex", children: profileEl })), searchBtn, promotionsEl, tourBtn, themeBtn, hamburgerBtn] })] }), hasTb2 && (_jsxs(Row, { border: "subtle", as: "nav", "aria-label": "Account actions", justify: "end", gap: "xs", className: "flex lg:hidden h-10 border-t px-1", children: [notificationsEl, wishlistEl, cartEl, profileEl] }))] })] }));
38
39
  }
@@ -37,6 +37,7 @@ export declare const PaymentStatusValues: {
37
37
  /** Runtime-accessible payment method values â€" use instead of bare string literals. */
38
38
  export declare const PaymentMethodValues: {
39
39
  readonly COD: "cod";
40
+ readonly CASH: "cash";
40
41
  readonly ONLINE: "online";
41
42
  readonly UPI_MANUAL: "upi_manual";
42
43
  readonly RAZORPAY: "razorpay";
@@ -209,6 +210,14 @@ export interface OrderDocument extends BaseDocument {
209
210
  pickedAt?: Date;
210
211
  /** Timestamp when the order was packed and ready for courier handoff. */
211
212
  packedAt?: Date;
213
+ /** Media slug for buyer-uploaded UPI/bank screenshot (via /api/media proxy). */
214
+ paymentProofUrl?: string;
215
+ /** UTR / transaction reference entered by the buyer. */
216
+ paymentTransactionId?: string;
217
+ /** MIME type detected at finalize step (image/jpeg, image/png, application/pdf). */
218
+ paymentProofMimeType?: string;
219
+ /** When the buyer submitted the proof. */
220
+ paymentProofUploadedAt?: Date;
212
221
  }
213
222
  export declare const ORDER_COLLECTION: "orders";
214
223
  export declare const ORDER_INDEXED_FIELDS: readonly ["userId", "productId", "storeId", "status", "paymentStatus", "payoutStatus", "shippingMethod", "orderDate", "createdAt", "assignedWorkerId", "pickedAt", "packedAt"];
@@ -31,6 +31,7 @@ export const PaymentStatusValues = {
31
31
  /** Runtime-accessible payment method values â€" use instead of bare string literals. */
32
32
  export const PaymentMethodValues = {
33
33
  COD: "cod",
34
+ CASH: "cash",
34
35
  ONLINE: "online",
35
36
  UPI_MANUAL: "upi_manual",
36
37
  RAZORPAY: "razorpay",
@@ -11,6 +11,7 @@ import { ImageUpload, MediaUploadField, MediaUploadList, } from "../../media";
11
11
  import { useMediaUpload } from "../../media";
12
12
  import { resolveDate } from "../../../utils/date.formatter";
13
13
  import { normalizeRichTextHtml } from "../../../utils/string.formatter";
14
+ import { useListingTypeFlags } from "../../../react/hooks/useListingTypeFlags";
14
15
  import { isAuctionListing, isPreOrderListing, isPrizeDrawListing, } from "../utils/listing-type";
15
16
  import { PrizeDrawItemsEditor } from "./PrizeDrawItemsEditor";
16
17
  export const PRODUCT_STATUS_OPTIONS = [
@@ -30,6 +31,7 @@ export function ProductForm({ product, onChange, isReadonly = false, renderDescr
30
31
  const t = useTranslations("adminProducts");
31
32
  const { upload } = useMediaUpload();
32
33
  const galleryIndexRef = useRef(0);
34
+ const listingTypeFlags = useListingTypeFlags();
33
35
  const update = (partial) => {
34
36
  onChange({ ...product, ...partial });
35
37
  };
@@ -133,7 +135,7 @@ export function ProductForm({ product, onChange, isReadonly = false, renderDescr
133
135
  ] })] }), _jsx(Checkbox, { label: t("formInsurance"), checked: !!product.insurance, onChange: (e) => update({
134
136
  insurance: e.target.checked,
135
137
  insuranceCost: e.target.checked ? product.insuranceCost || 0 : undefined,
136
- }), disabled: isReadonly }), product.insurance && (_jsxs(_Fragment, { children: [_jsx(Alert, { variant: "info", title: t("formInsuranceHelp"), children: t("formInsuranceHelp") }), _jsx(FormField, { name: "insuranceCost", label: t("formInsuranceCost"), type: "number", value: String(product.insuranceCost ?? ""), onChange: (value) => update({ insuranceCost: Number(value) }), disabled: isReadonly, placeholder: `${currencyPrefix}0` })] })), _jsx(Heading, { level: 4, className: "mt-4", children: t("sectionAuctionSettings") }), _jsx(Checkbox, { label: t("formIsAuction"), checked: isAuctionListing(product), onChange: (e) => update({ listingType: e.target.checked ? "auction" : "standard" }), disabled: isReadonly }), isAuctionListing(product) && (_jsxs(_Fragment, { children: [_jsxs(FormGroup, { columns: 2, children: [_jsx(FormField, { name: "startingBid", label: t("formStartingBid"), type: "number", value: String(product.startingBid ?? ""), onChange: (value) => update({ startingBid: Number(value) }), disabled: isReadonly, placeholder: "0" }), _jsx(FormField, { name: "auctionEndDate", label: t("formAuctionEndDate"), type: "datetime-local", value: (() => {
138
+ }), disabled: isReadonly }), product.insurance && (_jsxs(_Fragment, { children: [_jsx(Alert, { variant: "info", title: t("formInsuranceHelp"), children: t("formInsuranceHelp") }), _jsx(FormField, { name: "insuranceCost", label: t("formInsuranceCost"), type: "number", value: String(product.insuranceCost ?? ""), onChange: (value) => update({ insuranceCost: Number(value) }), disabled: isReadonly, placeholder: `${currencyPrefix}0` })] })), listingTypeFlags.auction && (_jsxs(_Fragment, { children: [_jsx(Heading, { level: 4, className: "mt-4", children: t("sectionAuctionSettings") }), _jsx(Checkbox, { label: t("formIsAuction"), checked: isAuctionListing(product), onChange: (e) => update({ listingType: e.target.checked ? "auction" : "standard" }), disabled: isReadonly })] })), isAuctionListing(product) && (_jsxs(_Fragment, { children: [_jsxs(FormGroup, { columns: 2, children: [_jsx(FormField, { name: "startingBid", label: t("formStartingBid"), type: "number", value: String(product.startingBid ?? ""), onChange: (value) => update({ startingBid: Number(value) }), disabled: isReadonly, placeholder: "0" }), _jsx(FormField, { name: "auctionEndDate", label: t("formAuctionEndDate"), type: "datetime-local", value: (() => {
137
139
  const d = resolveDate(product.auctionEndDate);
138
140
  if (!d)
139
141
  return "";
@@ -143,8 +145,8 @@ export function ProductForm({ product, onChange, isReadonly = false, renderDescr
143
145
  }), disabled: isReadonly, options: [
144
146
  { value: "winner", label: t("formAuctionShippingPaidByWinner") },
145
147
  { value: "seller", label: t("formAuctionShippingPaidBySeller") },
146
- ] }), _jsx(Text, { variant: "secondary", weight: "semibold", className: "mt-2", children: t("sectionAuctionAdvanced") }), _jsx(Checkbox, { label: t("formAutoExtendable"), checked: !!product.autoExtendable, onChange: (e) => update({ autoExtendable: e.target.checked }), disabled: isReadonly }), product.autoExtendable && (_jsxs(_Fragment, { children: [_jsx(Alert, { variant: "info", title: t("formAutoExtendableHelp"), children: t("formAutoExtendableHelp") }), _jsx(FormField, { name: "auctionExtensionMinutes", label: t("formAuctionExtensionMinutes"), type: "number", value: String(product.auctionExtensionMinutes ?? 5), onChange: (value) => update({ auctionExtensionMinutes: Number(value) || 5 }), disabled: isReadonly, placeholder: "5", helpText: t("formAuctionExtensionMinutesHelp") })] }))] })), _jsx(Heading, { level: 4, className: "mt-4", children: t("sectionPreOrderSettings") }), _jsx(Checkbox, { label: t("formIsPreOrder"), checked: isPreOrderListing(product), onChange: (e) => update({ listingType: e.target.checked ? "pre-order" : "standard" }), disabled: isReadonly }), _jsx(Heading, { level: 4, className: "mt-4", children: "Prize Draw Settings" }), _jsx(Checkbox, { label: "This is a prize-draw listing", checked: isPrizeDrawListing(product), onChange: (e) => update({ listingType: e.target.checked ? "prize-draw" : "standard" }), disabled: isReadonly ||
147
- (product.prizeDrawItems ?? []).some((it) => it.isWon) }), isPrizeDrawListing(product) && ((() => {
148
+ ] }), _jsx(Text, { variant: "secondary", weight: "semibold", className: "mt-2", children: t("sectionAuctionAdvanced") }), _jsx(Checkbox, { label: t("formAutoExtendable"), checked: !!product.autoExtendable, onChange: (e) => update({ autoExtendable: e.target.checked }), disabled: isReadonly }), product.autoExtendable && (_jsxs(_Fragment, { children: [_jsx(Alert, { variant: "info", title: t("formAutoExtendableHelp"), children: t("formAutoExtendableHelp") }), _jsx(FormField, { name: "auctionExtensionMinutes", label: t("formAuctionExtensionMinutes"), type: "number", value: String(product.auctionExtensionMinutes ?? 5), onChange: (value) => update({ auctionExtensionMinutes: Number(value) || 5 }), disabled: isReadonly, placeholder: "5", helpText: t("formAuctionExtensionMinutesHelp") })] }))] })), listingTypeFlags["pre-order"] && (_jsxs(_Fragment, { children: [_jsx(Heading, { level: 4, className: "mt-4", children: t("sectionPreOrderSettings") }), _jsx(Checkbox, { label: t("formIsPreOrder"), checked: isPreOrderListing(product), onChange: (e) => update({ listingType: e.target.checked ? "pre-order" : "standard" }), disabled: isReadonly })] })), listingTypeFlags["prize-draw"] && (_jsxs(_Fragment, { children: [_jsx(Heading, { level: 4, className: "mt-4", children: "Prize Draw Settings" }), _jsx(Checkbox, { label: "This is a prize-draw listing", checked: isPrizeDrawListing(product), onChange: (e) => update({ listingType: e.target.checked ? "prize-draw" : "standard" }), disabled: isReadonly ||
149
+ (product.prizeDrawItems ?? []).some((it) => it.isWon) })] })), isPrizeDrawListing(product) && ((() => {
148
150
  const prizeItems = (product.prizeDrawItems ?? []);
149
151
  const anyWon = prizeItems.some((it) => it.isWon);
150
152
  const lockedForReveal = anyWon;
@@ -91,10 +91,10 @@ export function ProductCard({ product, href, onClick, onAddToWishlist, isWishlis
91
91
  const MAX_CHIPS = 3;
92
92
  const visible = categories.slice(0, MAX_CHIPS);
93
93
  const overflow = Math.max(0, categories.length - MAX_CHIPS);
94
- return (_jsxs(Row, { className: "mt-1", gap: "xs", wrap: true, children: [visible.map((name) => (_jsxs(Span, { padding: "pill-2xs", layout: "inline-flex", className: "gap-[0.125rem] text-[10px] truncate max-w-[100px]", rounded: "full", surface: "subtle", color: "muted", children: [_jsx("svg", { className: "h-2.5 w-2.5 flex-shrink-0", fill: "none", stroke: "currentColor", strokeWidth: 2, viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3 7a2 2 0 012-2h14a2 2 0 012 2v10a2 2 0 01-2 2H5a2 2 0 01-2-2V7z" }) }), name] }, name))), overflow > 0 && (_jsxs(Span, { padding: "pill-2xs", layout: "inline-flex", weight: "medium", className: "text-[10px]", rounded: "full", surface: "subtle", color: "muted", title: categories.slice(MAX_CHIPS).join(", "), children: ["+", overflow] })), product.brand && (_jsxs(Span, { padding: "pill-2xs", layout: "inline-flex", gap: "2xs", className: "text-[10px] truncate max-w-[90px]", rounded: "full", surface: "subtle", color: "muted", children: [_jsx("svg", { className: "h-2.5 w-2.5 flex-shrink-0", fill: "none", stroke: "currentColor", strokeWidth: 2, viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z" }) }), product.brand] }))] }));
94
+ return (_jsxs(Row, { className: "mt-1", gap: "xs", wrap: true, children: [visible.map((name) => (_jsxs(Span, { padding: "pill-2xs", layout: "inline-flex", className: "gap-[0.125rem] text-[10px]", rounded: "full", surface: "subtle", color: "muted", children: [_jsx("svg", { className: "h-2.5 w-2.5 flex-shrink-0", fill: "none", stroke: "currentColor", strokeWidth: 2, viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3 7a2 2 0 012-2h14a2 2 0 012 2v10a2 2 0 01-2 2H5a2 2 0 01-2-2V7z" }) }), name] }, name))), overflow > 0 && (_jsxs(Span, { padding: "pill-2xs", layout: "inline-flex", weight: "medium", className: "text-[10px]", rounded: "full", surface: "subtle", color: "muted", title: categories.slice(MAX_CHIPS).join(", "), children: ["+", overflow] })), product.brand && (_jsxs(Span, { padding: "pill-2xs", layout: "inline-flex", gap: "2xs", className: "text-[10px]", rounded: "full", surface: "subtle", color: "muted", children: [_jsx("svg", { className: "h-2.5 w-2.5 flex-shrink-0", fill: "none", stroke: "currentColor", strokeWidth: 2, viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z" }) }), product.brand] }))] }));
95
95
  })(), (() => {
96
96
  const seller = safeDisplayName(product.storeName, "");
97
- return seller ? (_jsxs(Text, { className: "mt-0.5 text-[11px] truncate", color: "faint", children: ["by ", seller] })) : null;
97
+ return seller ? (_jsxs(Text, { className: "mt-0.5 text-[11px]", color: "faint", children: ["by ", seller] })) : null;
98
98
  })(), product.rating !== undefined && (_jsxs(Row, { className: "mt-1", gap: "xs", children: [_jsx(Span, { className: CLS_STAR, children: "\u2605" }), _jsxs(Span, { className: "text-[11px]", color: "muted", children: [product.rating.toFixed(1), product.reviewCount ? ` (${product.reviewCount})` : ""] })] })), _jsxs(Div, { className: "mt-auto", padding: "t-xs", children: [_jsxs(Row, { align: "baseline", gap: "sm", children: [_jsx(Span, { size: "base", weight: "bold", className: "text-primary dark:text-primary-400", children: formatCurrency(product.price, getDefaultCurrency()) }), product.originalPrice && product.originalPrice > product.price && (_jsx(Span, { size: "xs", className: "line-through", color: "faint", children: formatCurrency(product.originalPrice, getDefaultCurrency()) }))] }), (() => {
99
99
  const stock = product.stockCount ?? product.stockQuantity ?? product.availableQuantity;
100
100
  if (stock === undefined || isAuction)
package/dist/index.d.ts CHANGED
@@ -609,7 +609,7 @@ export { blogPostsSeedData } from "./seed/index";
609
609
  export { carouselSlidesSeedData } from "./seed/index";
610
610
  export { carouselsSeedData } from "./seed/index";
611
611
  export { cartsSeedData } from "./seed/index";
612
- export { categoriesSeedData } from "./seed/index";
612
+ export { categoriesSeedData, categoriesP1SeedData } from "./seed/index";
613
613
  export { couponsSeedData } from "./seed/index";
614
614
  export type { CouponUsageSeedRecord } from "./seed/index";
615
615
  export { couponUsageSeedData } from "./seed/index";
package/dist/index.js CHANGED
@@ -1236,7 +1236,7 @@ export { cartsSeedData } from "./seed/index";
1236
1236
  // [SERVER-ONLY]-Server-only â€" uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
1237
1237
  // SB-UNI-C â€" brandsSeedData merged into categoriesSeedData with categoryType:"brand".
1238
1238
  // categoriesSeedData - Model for categories seed data.
1239
- export { categoriesSeedData } from "./seed/index";
1239
+ export { categoriesSeedData, categoriesP1SeedData } from "./seed/index";
1240
1240
  // [SERVER-ONLY]-Server-only â€" uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
1241
1241
  // couponsSeedData - Model for coupons seed data.
1242
1242
  export { couponsSeedData } from "./seed/index";
@@ -127,6 +127,7 @@ export declare const DEFAULT_ROUTE_MAP: {
127
127
  readonly ORDER_CANCEL: (id: string) => string;
128
128
  readonly ORDER_TRACK: (id: string) => string;
129
129
  readonly ORDER_INVOICE: (id: string) => string;
130
+ readonly ORDER_PAYMENT: (id: string) => string;
130
131
  readonly NOTIFICATIONS: "/user/notifications";
131
132
  readonly MESSAGES: "/user/messages";
132
133
  /** Plan §10 — claimed-coupons wallet (Active / Expired / Used tabs). */
@@ -463,6 +464,7 @@ export declare const ROUTES: {
463
464
  readonly ORDER_CANCEL: (id: string) => string;
464
465
  readonly ORDER_TRACK: (id: string) => string;
465
466
  readonly ORDER_INVOICE: (id: string) => string;
467
+ readonly ORDER_PAYMENT: (id: string) => string;
466
468
  readonly NOTIFICATIONS: "/user/notifications";
467
469
  readonly MESSAGES: "/user/messages";
468
470
  /** Plan §10 — claimed-coupons wallet (Active / Expired / Used tabs). */
@@ -115,6 +115,7 @@ export const DEFAULT_ROUTE_MAP = {
115
115
  ORDER_CANCEL: (id) => `/user/orders/${id}/cancel`,
116
116
  ORDER_TRACK: (id) => `/user/orders/${id}/track`,
117
117
  ORDER_INVOICE: (id) => `/user/orders/${id}/invoice`,
118
+ ORDER_PAYMENT: (id) => `/user/orders/${id}/payment`,
118
119
  NOTIFICATIONS: "/user/notifications",
119
120
  MESSAGES: "/user/messages",
120
121
  /** Plan §10 — claimed-coupons wallet (Active / Expired / Used tabs). */
@@ -1,2 +1,3 @@
1
1
  import type { CategoryDocument } from "../features/categories/schemas";
2
2
  export declare const categoriesSeedData: Partial<CategoryDocument>[];
3
+ export declare const categoriesP1SeedData: Partial<CategoryDocument>[];
@@ -2211,3 +2211,9 @@ export const categoriesSeedData = [
2211
2211
  ...brandRows.map((b) => ({ ancestors: [], ...b, createdByType: "admin" })),
2212
2212
  ...bundleRows.map((bundle) => ({ ancestors: [], ...bundle, createdByType: "admin" })),
2213
2213
  ];
2214
+ // P-1 default seed: excludes bundle rows (FEATURE_BUNDLES is off in P-1)
2215
+ export const categoriesP1SeedData = [
2216
+ ...rawCategories.map((c) => ({ ancestors: [], ...c, createdByType: "admin" })),
2217
+ ...sublistingRows.map((s) => ({ ancestors: [], ...s, createdByType: "admin" })),
2218
+ ...brandRows.map((b) => ({ ancestors: [], ...b, createdByType: "admin" })),
2219
+ ];
@@ -44,7 +44,7 @@ export { sessionsSeedData, SESSION_COLLECTION } from "./sessions-seed-data";
44
44
  export { addressesSeedData } from "./addresses-seed-data";
45
45
  export { storesSeedData } from "./stores-seed-data";
46
46
  export { storeAddressesSeedData } from "./store-addresses-seed-data";
47
- export { categoriesSeedData } from "./categories-seed-data";
47
+ export { categoriesSeedData, categoriesP1SeedData } from "./categories-seed-data";
48
48
  export { productsStandardSeedData } from "./products-standard-seed-data";
49
49
  export { productsAuctionsSeedData } from "./products-auctions-seed-data";
50
50
  export { productsPreordersSeedData } from "./products-preorders-seed-data";
@@ -32,7 +32,7 @@ export { sessionsSeedData, SESSION_COLLECTION } from "./sessions-seed-data";
32
32
  export { addressesSeedData } from "./addresses-seed-data";
33
33
  export { storesSeedData } from "./stores-seed-data";
34
34
  export { storeAddressesSeedData } from "./store-addresses-seed-data";
35
- export { categoriesSeedData } from "./categories-seed-data";
35
+ export { categoriesSeedData, categoriesP1SeedData } from "./categories-seed-data";
36
36
  export { productsStandardSeedData } from "./products-standard-seed-data";
37
37
  export { productsAuctionsSeedData } from "./products-auctions-seed-data";
38
38
  export { productsPreordersSeedData } from "./products-preorders-seed-data";
@@ -66,7 +66,7 @@ const _rawOrdersSeedData = [
66
66
  currency: "INR",
67
67
  status: "delivered",
68
68
  paymentStatus: "paid",
69
- paymentMethod: "cod",
69
+ paymentMethod: "cash",
70
70
  paymentId: "pay-yugi-kaiba-001",
71
71
  shippingAddress: "addr-yugi-home",
72
72
  trackingNumber: "JP-0001-KAIBA-DELIVERED",
@@ -91,7 +91,7 @@ const _rawOrdersSeedData = [
91
91
  currency: "INR",
92
92
  status: "shipped",
93
93
  paymentStatus: "paid",
94
- paymentMethod: "online",
94
+ paymentMethod: "cash",
95
95
  paymentId: "pay-yugi-kaiba-002",
96
96
  shippingAddress: "addr-yugi-home",
97
97
  trackingNumber: "JP-0002-KAIBA-SHIPPED",
@@ -115,7 +115,7 @@ const _rawOrdersSeedData = [
115
115
  currency: "INR",
116
116
  status: "processing",
117
117
  paymentStatus: "paid",
118
- paymentMethod: "cod",
118
+ paymentMethod: "cash",
119
119
  paymentId: "pay-yugi-kaiba-003",
120
120
  shippingAddress: "addr-yugi-home",
121
121
  orderDate: daysAgo(35),
@@ -136,7 +136,7 @@ const _rawOrdersSeedData = [
136
136
  currency: "INR",
137
137
  status: "pending",
138
138
  paymentStatus: "pending",
139
- paymentMethod: "online",
139
+ paymentMethod: "cash",
140
140
  paymentId: "pay-yugi-kaiba-004",
141
141
  shippingAddress: "addr-yugi-home",
142
142
  orderDate: daysAgo(30),
@@ -160,7 +160,7 @@ const _rawOrdersSeedData = [
160
160
  currency: "INR",
161
161
  status: "delivered",
162
162
  paymentStatus: "paid",
163
- paymentMethod: "online",
163
+ paymentMethod: "cash",
164
164
  paymentId: "pay-yugi-admin-001",
165
165
  shippingAddress: "addr-yugi-home",
166
166
  trackingNumber: "IN-0001-ADMIN-DELIVERED",
@@ -188,7 +188,7 @@ const _rawOrdersSeedData = [
188
188
  currency: "INR",
189
189
  status: "delivered",
190
190
  paymentStatus: "paid",
191
- paymentMethod: "online",
191
+ paymentMethod: "cash",
192
192
  paymentId: "pay-admin-kaiba-001",
193
193
  shippingAddress: "addr-letitrip-hq",
194
194
  trackingNumber: "JP-0010-KAIBA-DELIVERED",
@@ -216,7 +216,7 @@ const _rawOrdersSeedData = [
216
216
  currency: "INR",
217
217
  status: "delivered",
218
218
  paymentStatus: "paid",
219
- paymentMethod: "online",
219
+ paymentMethod: "cash",
220
220
  paymentId: "pay-kaiba-admin-001",
221
221
  shippingAddress: "addr-kaiba-mansion",
222
222
  trackingNumber: "IN-0005-ADMIN-DELIVERED",
@@ -282,7 +282,7 @@ for (let i = _rawOrdersSeedData.length; i < 50; i++) {
282
282
  currency: "INR",
283
283
  status: status,
284
284
  paymentStatus: (paymentStatuses[status] ?? "pending"),
285
- paymentMethod: i % 2 === 0 ? "cod" : "online",
285
+ paymentMethod: "cash",
286
286
  shippingAddress: combo.addressId,
287
287
  orderDate: daysAgo(daysBack),
288
288
  shippingDate: status === "shipped" || status === "delivered" ? daysAgo(daysBack - 5) : undefined,
@@ -291,4 +291,58 @@ for (let i = _rawOrdersSeedData.length; i < 50; i++) {
291
291
  updatedAt: daysAgo(Math.max(0, daysBack - 10)),
292
292
  });
293
293
  }
294
- export const ordersSeedData = [..._rawOrdersSeedData, ...expandedOrders].slice(0, 50);
294
+ // P-1 MVP: two cash/UPI manual payment orders for demo purposes.
295
+ // cashOrderPendingProof: buyer submitted proof, admin has NOT yet verified.
296
+ const cashOrderPendingProof = {
297
+ id: "order-1-20260729-cash01",
298
+ productId: "product-dark-magician-lob-1st",
299
+ productTitle: "Dark Magician — LOB 1st Edition",
300
+ userId: "user-yugi-muto",
301
+ userName: "Yugi Muto",
302
+ userEmail: "yugi@duelkingdom.in",
303
+ storeId: "store-kaiba-corp-cards",
304
+ quantity: 1,
305
+ unitPrice: 499900,
306
+ totalPrice: 499900,
307
+ currency: "INR",
308
+ status: "pending",
309
+ paymentStatus: "pending",
310
+ paymentMethod: "cash",
311
+ paymentProofUrl: "/media/payment-proof-demo-pending.jpg",
312
+ paymentTransactionId: "UPI-DEMO-20260728-PROOF",
313
+ paymentProofMimeType: "image/jpeg",
314
+ paymentProofUploadedAt: daysAgo(1),
315
+ shippingAddress: "addr-yugi-home",
316
+ orderDate: daysAgo(2),
317
+ createdAt: daysAgo(2),
318
+ updatedAt: daysAgo(1),
319
+ };
320
+ const cashOrderVerified = {
321
+ id: "order-1-20260729-cash02",
322
+ productId: "product-hot-wheels-redline-vintage",
323
+ productTitle: "Hot Wheels Redline — Vintage",
324
+ userId: "user-yugi-muto",
325
+ userName: "Yugi Muto",
326
+ userEmail: "yugi@duelkingdom.in",
327
+ storeId: "store-diecast-depot",
328
+ quantity: 1,
329
+ unitPrice: 129900,
330
+ totalPrice: 129900,
331
+ currency: "INR",
332
+ status: "processing",
333
+ paymentStatus: "paid",
334
+ paymentMethod: "cash",
335
+ paymentProofUrl: "/media/payment-proof-demo-verified.jpg",
336
+ paymentTransactionId: "UPI-DEMO-20260727-YUGI",
337
+ paymentProofMimeType: "image/jpeg",
338
+ paymentProofUploadedAt: daysAgo(3),
339
+ shippingAddress: "addr-yugi-home",
340
+ orderDate: daysAgo(4),
341
+ createdAt: daysAgo(4),
342
+ updatedAt: daysAgo(2),
343
+ };
344
+ export const ordersSeedData = [
345
+ cashOrderPendingProof,
346
+ cashOrderVerified,
347
+ ...[..._rawOrdersSeedData, ...expandedOrders].slice(0, 48),
348
+ ];
@@ -269,7 +269,7 @@ const _rawProductsStandardSeedData = [
269
269
  isSold: false,
270
270
  mainImage: seedExtMedia(`https://images.ygoprodeck.com/images/cards/cropped/${CARD_IDS.darkMagician}.jpg`),
271
271
  images: [seedExtMedia(`https://images.ygoprodeck.com/images/cards/cropped/${CARD_IDS.darkMagician}.jpg`)],
272
- status: PRODUCT_FIELDS.STATUS_VALUES.DRAFT,
272
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
273
273
  condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
274
274
  storeId: "store-letitrip-official",
275
275
  storeName: "LetItRip Official",
@@ -410,7 +410,7 @@ const _kaibaSinglesSeedData = [
410
410
  isSold: false,
411
411
  mainImage: seedExtMedia(`https://images.ygoprodeck.com/images/cards/${CARD_IDS.kuriboh}.jpg`),
412
412
  images: [seedExtMedia(`https://images.ygoprodeck.com/images/cards/${CARD_IDS.kuriboh}.jpg`)],
413
- status: PRODUCT_FIELDS.STATUS_VALUES.DRAFT,
413
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
414
414
  condition: PRODUCT_FIELDS.CONDITION_VALUES.USED,
415
415
  storeId: "store-kaiba-corp-cards",
416
416
  storeName: "Kaiba Corp Card Vault",
@@ -474,9 +474,9 @@ const _kaibaSinglesSeedData = [
474
474
  brand: "Konami",
475
475
  price: 899900,
476
476
  currency: "INR",
477
- stockQuantity: 1,
478
- availableQuantity: 0,
479
- isSold: true,
477
+ stockQuantity: 3,
478
+ availableQuantity: 3,
479
+ isSold: false,
480
480
  mainImage: seedExtMedia(`https://images.ygoprodeck.com/images/cards/${CARD_IDS.darkMagicianGirl}.jpg`),
481
481
  images: [seedExtMedia(`https://images.ygoprodeck.com/images/cards/${CARD_IDS.darkMagicianGirl}.jpg`)],
482
482
  status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
@@ -497,8 +497,8 @@ const _kaibaSinglesSeedData = [
497
497
  brand: "Konami",
498
498
  price: 1299900,
499
499
  currency: "INR",
500
- stockQuantity: 0,
501
- availableQuantity: 0,
500
+ stockQuantity: 5,
501
+ availableQuantity: 5,
502
502
  isSold: false,
503
503
  mainImage: seedExtMedia(`https://images.ygoprodeck.com/images/cards/${CARD_IDS.chaosEmperorDragon}.jpg`),
504
504
  images: [seedExtMedia(`https://images.ygoprodeck.com/images/cards/${CARD_IDS.chaosEmperorDragon}.jpg`)],
@@ -548,7 +548,7 @@ const _kaibaSinglesSeedData = [
548
548
  isSold: false,
549
549
  mainImage: seedExtMedia(`https://images.ygoprodeck.com/images/cards/${CARD_IDS.cyberDragon}.jpg`),
550
550
  images: [seedExtMedia(`https://images.ygoprodeck.com/images/cards/${CARD_IDS.cyberDragon}.jpg`)],
551
- status: PRODUCT_FIELDS.STATUS_VALUES.DRAFT,
551
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
552
552
  condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
553
553
  storeId: "store-kaiba-corp-cards",
554
554
  storeName: "Kaiba Corp Card Vault",
@@ -775,9 +775,9 @@ const _kaibaTrapSpellsSeedData = [
775
775
  brand: "Konami",
776
776
  price: 999900,
777
777
  currency: "INR",
778
- stockQuantity: 1,
779
- availableQuantity: 0,
780
- isSold: true,
778
+ stockQuantity: 3,
779
+ availableQuantity: 3,
780
+ isSold: false,
781
781
  mainImage: seedExtMedia(`https://images.ygoprodeck.com/images/cards/${CARD_IDS.mirrorForce}.jpg`),
782
782
  images: [seedExtMedia(`https://images.ygoprodeck.com/images/cards/${CARD_IDS.mirrorForce}.jpg`)],
783
783
  status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
@@ -803,7 +803,7 @@ const _kaibaTrapSpellsSeedData = [
803
803
  isSold: false,
804
804
  mainImage: seedExtMedia(`https://images.ygoprodeck.com/images/cards/${CARD_IDS.mysticalSpaceTyphoon}.jpg`),
805
805
  images: [seedExtMedia(`https://images.ygoprodeck.com/images/cards/${CARD_IDS.mysticalSpaceTyphoon}.jpg`)],
806
- status: PRODUCT_FIELDS.STATUS_VALUES.DRAFT,
806
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
807
807
  condition: PRODUCT_FIELDS.CONDITION_VALUES.USED,
808
808
  storeId: "store-kaiba-corp-cards",
809
809
  storeName: "Kaiba Corp Card Vault",
@@ -984,8 +984,8 @@ const _kaibaSealedExtraDeckSeedData = [
984
984
  brand: "Konami",
985
985
  price: 999900,
986
986
  currency: "INR",
987
- stockQuantity: 0,
988
- availableQuantity: 0,
987
+ stockQuantity: 5,
988
+ availableQuantity: 5,
989
989
  isSold: false,
990
990
  mainImage: seedExtMedia(`https://images.ygoprodeck.com/images/cards/cropped/${CARD_IDS.sliferTheSkyDragon}.jpg`),
991
991
  images: [seedExtMedia(`https://images.ygoprodeck.com/images/cards/cropped/${CARD_IDS.sliferTheSkyDragon}.jpg`)],
@@ -1196,7 +1196,7 @@ const _kaibaSealedExtraDeckSeedData = [
1196
1196
  isSold: false,
1197
1197
  mainImage: seedExtMedia(`https://images.ygoprodeck.com/images/cards/cropped/${CARD_IDS.darkMagician}.jpg`),
1198
1198
  images: [seedExtMedia(`https://images.ygoprodeck.com/images/cards/cropped/${CARD_IDS.darkMagician}.jpg`)],
1199
- status: PRODUCT_FIELDS.STATUS_VALUES.DRAFT,
1199
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
1200
1200
  condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
1201
1201
  storeId: "store-kaiba-corp-cards",
1202
1202
  storeName: "Kaiba Corp Card Vault",
@@ -374,16 +374,26 @@ export const siteSettingsSeedData = {
374
374
  smsVerification: true,
375
375
  translations: true,
376
376
  wishlists: true,
377
- auctions: true,
377
+ auctions: false,
378
378
  reviews: true,
379
- events: true,
380
- blog: true,
381
- coupons: true,
379
+ events: false,
380
+ blog: false,
381
+ coupons: false,
382
382
  notifications: true,
383
383
  sellerRegistration: true,
384
- preOrders: true,
384
+ preOrders: false,
385
385
  seedPanel: true,
386
386
  adminCheckoutBypass: false,
387
+ // P-1 MVP: only standard listing type active; others unlocked in later patches.
388
+ listingTypes: {
389
+ standard: true,
390
+ auction: false,
391
+ "pre-order": false,
392
+ "prize-draw": false,
393
+ classified: false,
394
+ "digital-code": false,
395
+ live: false,
396
+ },
387
397
  },
388
398
  credentials: {
389
399
  razorpayKeyId: "rzp_test_PLACEHOLDER",
package/dist/server.d.ts CHANGED
@@ -6,6 +6,7 @@ export { SERVER_ERRORS_COLLECTION, SERVER_ERROR_FIELDS, SERVER_ERROR_STACK_MAX_B
6
6
  export type { ServerErrorDocument, ServerErrorSource, } from "./features/server-errors/schemas/firestore";
7
7
  export { wrapAction, isOk, unwrap, } from "./_internal/shared/types/action-result";
8
8
  export type { ActionResult } from "./_internal/shared/types/action-result";
9
+ export { attachPaymentProofAction, adminVerifyPaymentAction, } from "./_internal/server/features/orders/actions";
9
10
  export { wrapJobHandler, wrapScheduleHandler, wrapTriggerHandler, wrapCallableHandler, } from "./_internal/server/jobs/core/wrapJobHandler";
10
11
  export { analyzeLogs } from "./_internal/server/features/maintenance/analyze";
11
12
  export type { AnalyzeOptions, AnalyzeReport, } from "./_internal/server/features/maintenance/analyze";
package/dist/server.js CHANGED
@@ -11,6 +11,8 @@ export { SERVER_ERRORS_COLLECTION, SERVER_ERROR_FIELDS, SERVER_ERROR_STACK_MAX_B
11
11
  // [SERVER-ONLY] ActionResult envelope + wrapAction helper for "use server" functions.
12
12
  // Mirrors the routeHandler envelope so client wrappers consume both surfaces uniformly.
13
13
  export { wrapAction, isOk, unwrap, } from "./_internal/shared/types/action-result";
14
+ // [SERVER-ONLY] P-1 manual payment proof server actions.
15
+ export { attachPaymentProofAction, adminVerifyPaymentAction, } from "./_internal/server/features/orders/actions";
14
16
  // [SERVER-ONLY] Cloud Function handler wrappers — persist exceptions to
15
17
  // serverErrors (source: "function") before re-throwing so retry semantics
16
18
  // are preserved. Apply at the consumer's runtime adapter boundary.