@axova/shared 1.0.0

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 (112) hide show
  1. package/CONFIGURATION_GUIDE.md +1 -0
  2. package/README.md +384 -0
  3. package/SCHEMA_ORGANIZATION.md +209 -0
  4. package/dist/configs/index.d.ts +85 -0
  5. package/dist/configs/index.js +555 -0
  6. package/dist/events/kafka.d.ts +40 -0
  7. package/dist/events/kafka.js +311 -0
  8. package/dist/index.d.ts +13 -0
  9. package/dist/index.js +41 -0
  10. package/dist/interfaces/customer-events.d.ts +85 -0
  11. package/dist/interfaces/customer-events.js +2 -0
  12. package/dist/interfaces/inventory-events.d.ts +453 -0
  13. package/dist/interfaces/inventory-events.js +3 -0
  14. package/dist/interfaces/inventory-types.d.ts +894 -0
  15. package/dist/interfaces/inventory-types.js +3 -0
  16. package/dist/interfaces/order-events.d.ts +320 -0
  17. package/dist/interfaces/order-events.js +3 -0
  18. package/dist/lib/auditLogger.d.ts +162 -0
  19. package/dist/lib/auditLogger.js +626 -0
  20. package/dist/lib/authOrganization.d.ts +24 -0
  21. package/dist/lib/authOrganization.js +110 -0
  22. package/dist/lib/db.d.ts +6 -0
  23. package/dist/lib/db.js +88 -0
  24. package/dist/middleware/serviceAuth.d.ts +60 -0
  25. package/dist/middleware/serviceAuth.js +272 -0
  26. package/dist/middleware/storeOwnership.d.ts +15 -0
  27. package/dist/middleware/storeOwnership.js +156 -0
  28. package/dist/middleware/storeValidationMiddleware.d.ts +44 -0
  29. package/dist/middleware/storeValidationMiddleware.js +180 -0
  30. package/dist/middleware/userAuth.d.ts +27 -0
  31. package/dist/middleware/userAuth.js +218 -0
  32. package/dist/schemas/admin/admin-schema.d.ts +741 -0
  33. package/dist/schemas/admin/admin-schema.js +111 -0
  34. package/dist/schemas/ai-moderation/ai-moderation-schema.d.ts +648 -0
  35. package/dist/schemas/ai-moderation/ai-moderation-schema.js +88 -0
  36. package/dist/schemas/common/common-schemas.d.ts +436 -0
  37. package/dist/schemas/common/common-schemas.js +94 -0
  38. package/dist/schemas/compliance/compliance-schema.d.ts +3388 -0
  39. package/dist/schemas/compliance/compliance-schema.js +472 -0
  40. package/dist/schemas/compliance/kyc-schema.d.ts +2642 -0
  41. package/dist/schemas/compliance/kyc-schema.js +361 -0
  42. package/dist/schemas/customer/customer-schema.d.ts +2727 -0
  43. package/dist/schemas/customer/customer-schema.js +399 -0
  44. package/dist/schemas/index.d.ts +27 -0
  45. package/dist/schemas/index.js +138 -0
  46. package/dist/schemas/inventory/inventory-tables.d.ts +9476 -0
  47. package/dist/schemas/inventory/inventory-tables.js +1470 -0
  48. package/dist/schemas/inventory/lot-tables.d.ts +3281 -0
  49. package/dist/schemas/inventory/lot-tables.js +608 -0
  50. package/dist/schemas/order/order-schema.d.ts +5825 -0
  51. package/dist/schemas/order/order-schema.js +954 -0
  52. package/dist/schemas/product/discount-relations.d.ts +15 -0
  53. package/dist/schemas/product/discount-relations.js +34 -0
  54. package/dist/schemas/product/discount-schema.d.ts +1975 -0
  55. package/dist/schemas/product/discount-schema.js +297 -0
  56. package/dist/schemas/product/product-relations.d.ts +41 -0
  57. package/dist/schemas/product/product-relations.js +133 -0
  58. package/dist/schemas/product/product-schema.d.ts +4544 -0
  59. package/dist/schemas/product/product-schema.js +671 -0
  60. package/dist/schemas/store/store-audit-schema.d.ts +4135 -0
  61. package/dist/schemas/store/store-audit-schema.js +556 -0
  62. package/dist/schemas/store/store-schema.d.ts +3100 -0
  63. package/dist/schemas/store/store-schema.js +381 -0
  64. package/dist/schemas/store/store-settings-schema.d.ts +665 -0
  65. package/dist/schemas/store/store-settings-schema.js +141 -0
  66. package/dist/schemas/types.d.ts +50 -0
  67. package/dist/schemas/types.js +3 -0
  68. package/dist/types/events.d.ts +2396 -0
  69. package/dist/types/events.js +505 -0
  70. package/dist/utils/errorHandler.d.ts +12 -0
  71. package/dist/utils/errorHandler.js +36 -0
  72. package/dist/utils/subdomain.d.ts +6 -0
  73. package/dist/utils/subdomain.js +20 -0
  74. package/nul +8 -0
  75. package/package.json +43 -0
  76. package/src/configs/index.ts +654 -0
  77. package/src/events/kafka.ts +429 -0
  78. package/src/index.ts +26 -0
  79. package/src/interfaces/customer-events.ts +106 -0
  80. package/src/interfaces/inventory-events.ts +545 -0
  81. package/src/interfaces/inventory-types.ts +1004 -0
  82. package/src/interfaces/order-events.ts +381 -0
  83. package/src/lib/auditLogger.ts +1117 -0
  84. package/src/lib/authOrganization.ts +153 -0
  85. package/src/lib/db.ts +64 -0
  86. package/src/middleware/serviceAuth.ts +328 -0
  87. package/src/middleware/storeOwnership.ts +199 -0
  88. package/src/middleware/storeValidationMiddleware.ts +247 -0
  89. package/src/middleware/userAuth.ts +248 -0
  90. package/src/schemas/admin/admin-schema.ts +208 -0
  91. package/src/schemas/ai-moderation/ai-moderation-schema.ts +180 -0
  92. package/src/schemas/common/common-schemas.ts +108 -0
  93. package/src/schemas/compliance/compliance-schema.ts +927 -0
  94. package/src/schemas/compliance/kyc-schema.ts +649 -0
  95. package/src/schemas/customer/customer-schema.ts +576 -0
  96. package/src/schemas/index.ts +189 -0
  97. package/src/schemas/inventory/inventory-tables.ts +1927 -0
  98. package/src/schemas/inventory/lot-tables.ts +799 -0
  99. package/src/schemas/order/order-schema.ts +1400 -0
  100. package/src/schemas/product/discount-relations.ts +44 -0
  101. package/src/schemas/product/discount-schema.ts +464 -0
  102. package/src/schemas/product/product-relations.ts +187 -0
  103. package/src/schemas/product/product-schema.ts +955 -0
  104. package/src/schemas/store/ethiopian_business_api.md.resolved +212 -0
  105. package/src/schemas/store/store-audit-schema.ts +1257 -0
  106. package/src/schemas/store/store-schema.ts +661 -0
  107. package/src/schemas/store/store-settings-schema.ts +231 -0
  108. package/src/schemas/types.ts +67 -0
  109. package/src/types/events.ts +646 -0
  110. package/src/utils/errorHandler.ts +44 -0
  111. package/src/utils/subdomain.ts +19 -0
  112. package/tsconfig.json +21 -0
@@ -0,0 +1,297 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.discountAnalytics = exports.customerSegments = exports.discountRules = exports.discountUsages = exports.discounts = exports.discountStackingModeEnum = exports.customerSegmentTypeEnum = exports.discountApplicationTypeEnum = exports.discountTargetTypeEnum = exports.discountStatusEnum = exports.discountTypeEnum = void 0;
4
+ const cuid2_1 = require("@paralleldrive/cuid2");
5
+ const pg_core_1 = require("drizzle-orm/pg-core");
6
+ // =====================================================
7
+ // DISCOUNT ENUMS
8
+ // =====================================================
9
+ exports.discountTypeEnum = (0, pg_core_1.pgEnum)("discount_type", [
10
+ "PERCENTAGE",
11
+ "FIXED_AMOUNT",
12
+ "FREE_SHIPPING",
13
+ "BOGO", // Buy one get one
14
+ "TIERED", // Volume-based tiered discounts
15
+ "LOYALTY_POINTS", // Loyalty points redemption
16
+ "REFERRAL", // Referral rewards
17
+ "MEMBER_ONLY", // Membership-exclusive discounts
18
+ ]);
19
+ exports.discountStatusEnum = (0, pg_core_1.pgEnum)("discount_status", [
20
+ "DRAFT",
21
+ "ACTIVE",
22
+ "PAUSED",
23
+ "SCHEDULED",
24
+ "EXPIRED",
25
+ "DISABLED",
26
+ ]);
27
+ exports.discountTargetTypeEnum = (0, pg_core_1.pgEnum)("discount_target_type", [
28
+ "STORE", // Store-wide discount
29
+ "COLLECTION", // Collection-specific discount
30
+ "PRODUCT", // Product-specific discount
31
+ "VARIANT", // Variant-specific discount
32
+ "CATEGORY", // Category-specific discount
33
+ "CUSTOMER_SEGMENT", // Customer segment-specific
34
+ ]);
35
+ exports.discountApplicationTypeEnum = (0, pg_core_1.pgEnum)("discount_application_type", [
36
+ "AUTOMATIC", // Automatically applied
37
+ "CODE", // Requires coupon code
38
+ "MANUAL", // Manually applied by staff
39
+ ]);
40
+ exports.customerSegmentTypeEnum = (0, pg_core_1.pgEnum)("customer_segment_type", [
41
+ "NEW_CUSTOMER",
42
+ "RETURNING_CUSTOMER",
43
+ "VIP",
44
+ "LOYALTY_TIER_1",
45
+ "LOYALTY_TIER_2",
46
+ "LOYALTY_TIER_3",
47
+ "GEOGRAPHIC",
48
+ "PURCHASE_HISTORY",
49
+ "CUSTOM",
50
+ ]);
51
+ exports.discountStackingModeEnum = (0, pg_core_1.pgEnum)("discount_stacking_mode", [
52
+ "NONE", // Cannot stack with other discounts
53
+ "ADDITIVE", // Add discount values together
54
+ "MULTIPLICATIVE", // Apply discounts multiplicatively
55
+ "BEST_ONLY", // Apply only the best discount
56
+ "CUSTOM", // Custom stacking logic
57
+ ]);
58
+ // =====================================================
59
+ // MAIN DISCOUNTS TABLE
60
+ // =====================================================
61
+ exports.discounts = (0, pg_core_1.pgTable)("discounts", {
62
+ id: (0, pg_core_1.text)("id")
63
+ .primaryKey()
64
+ .$defaultFn(() => (0, cuid2_1.createId)()),
65
+ storeId: (0, pg_core_1.text)("store_id").notNull(),
66
+ // Basic Information
67
+ name: (0, pg_core_1.varchar)("name", { length: 255 }).notNull(),
68
+ description: (0, pg_core_1.text)("description"),
69
+ internalNotes: (0, pg_core_1.text)("internal_notes"), // Staff notes
70
+ // Discount Configuration
71
+ type: (0, exports.discountTypeEnum)("type").notNull(),
72
+ status: (0, exports.discountStatusEnum)("status").notNull().default("DRAFT"),
73
+ applicationType: (0, exports.discountApplicationTypeEnum)("application_type")
74
+ .notNull()
75
+ .default("AUTOMATIC"),
76
+ // Discount Values
77
+ value: (0, pg_core_1.decimal)("value", { precision: 12, scale: 4 }).notNull(), // Main discount value
78
+ maxDiscountAmount: (0, pg_core_1.decimal)("max_discount_amount", { precision: 12, scale: 2 }), // Cap for percentage discounts
79
+ // Coupon Code (for CODE application type)
80
+ couponCode: (0, pg_core_1.varchar)("coupon_code", { length: 100 }),
81
+ codePrefix: (0, pg_core_1.varchar)("code_prefix", { length: 20 }), // For auto-generated codes
82
+ // Targeting Configuration
83
+ targetType: (0, exports.discountTargetTypeEnum)("target_type").notNull().default("STORE"),
84
+ targetIds: (0, pg_core_1.jsonb)("target_ids").$type().default([]), // IDs of targeted items
85
+ // Customer Eligibility
86
+ customerSegments: (0, pg_core_1.jsonb)("customer_segments")
87
+ .$type()
88
+ .default([]),
89
+ excludedCustomerIds: (0, pg_core_1.jsonb)("excluded_customer_ids")
90
+ .$type()
91
+ .default([]),
92
+ // Usage Limits
93
+ usageLimit: (0, pg_core_1.integer)("usage_limit"), // Total usage limit
94
+ usageLimitPerCustomer: (0, pg_core_1.integer)("usage_limit_per_customer"),
95
+ currentUsageCount: (0, pg_core_1.integer)("current_usage_count").notNull().default(0),
96
+ // Minimum Requirements
97
+ minPurchaseAmount: (0, pg_core_1.decimal)("min_purchase_amount", { precision: 12, scale: 2 }),
98
+ minQuantity: (0, pg_core_1.integer)("min_quantity"),
99
+ minItems: (0, pg_core_1.integer)("min_items"), // Minimum number of different items
100
+ // Time Constraints
101
+ startsAt: (0, pg_core_1.timestamp)("starts_at", { withTimezone: true }),
102
+ endsAt: (0, pg_core_1.timestamp)("ends_at", { withTimezone: true }),
103
+ timeZone: (0, pg_core_1.varchar)("time_zone", { length: 50 }).default("UTC"),
104
+ // Schedule Configuration
105
+ scheduleConfig: (0, pg_core_1.jsonb)("schedule_config").$type(),
106
+ // Geographic Restrictions
107
+ geoRestrictions: (0, pg_core_1.jsonb)("geo_restrictions").$type(),
108
+ // Sales Channel Configuration
109
+ salesChannels: (0, pg_core_1.jsonb)("sales_channels")
110
+ .$type()
111
+ .default(["POS", "MARKETPLACE", "STOREFRONT"]),
112
+ // Stacking Configuration
113
+ stackingMode: (0, exports.discountStackingModeEnum)("stacking_mode")
114
+ .notNull()
115
+ .default("NONE"),
116
+ priority: (0, pg_core_1.integer)("priority").notNull().default(0), // Higher number = higher priority
117
+ excludeOtherDiscounts: (0, pg_core_1.boolean)("exclude_other_discounts")
118
+ .notNull()
119
+ .default(false),
120
+ // Advanced Configuration
121
+ customRules: (0, pg_core_1.jsonb)("custom_rules").$type(),
122
+ // BOGO Configuration
123
+ bogoConfig: (0, pg_core_1.jsonb)("bogo_config").$type(),
124
+ // Tiered Discount Configuration
125
+ tieredConfig: (0, pg_core_1.jsonb)("tiered_config").$type(),
126
+ // Loyalty Points Configuration
127
+ loyaltyPointsConfig: (0, pg_core_1.jsonb)("loyalty_points_config").$type(),
128
+ // Performance Tracking
129
+ totalSavings: (0, pg_core_1.decimal)("total_savings", { precision: 12, scale: 2 })
130
+ .notNull()
131
+ .default("0"),
132
+ totalRevenue: (0, pg_core_1.decimal)("total_revenue", { precision: 12, scale: 2 })
133
+ .notNull()
134
+ .default("0"),
135
+ conversionRate: (0, pg_core_1.decimal)("conversion_rate", { precision: 5, scale: 4 }),
136
+ // Metadata
137
+ createdBy: (0, pg_core_1.text)("created_by"), // User ID who created the discount
138
+ lastModifiedBy: (0, pg_core_1.text)("last_modified_by"),
139
+ tags: (0, pg_core_1.jsonb)("tags").$type().default([]),
140
+ // Timestamps
141
+ createdAt: (0, pg_core_1.timestamp)("created_at", { withTimezone: true })
142
+ .defaultNow()
143
+ .notNull(),
144
+ updatedAt: (0, pg_core_1.timestamp)("updated_at", { withTimezone: true })
145
+ .defaultNow()
146
+ .notNull(),
147
+ deletedAt: (0, pg_core_1.timestamp)("deleted_at", { withTimezone: true }),
148
+ }, (table) => ({
149
+ storeIdIndex: (0, pg_core_1.index)("idx_discounts_store_id").on(table.storeId),
150
+ statusIndex: (0, pg_core_1.index)("idx_discounts_status").on(table.status),
151
+ typeIndex: (0, pg_core_1.index)("idx_discounts_type").on(table.type),
152
+ couponCodeIndex: (0, pg_core_1.index)("idx_discounts_coupon_code").on(table.couponCode),
153
+ targetTypeIndex: (0, pg_core_1.index)("idx_discounts_target_type").on(table.targetType),
154
+ priorityIndex: (0, pg_core_1.index)("idx_discounts_priority").on(table.priority),
155
+ timeRangeIndex: (0, pg_core_1.index)("idx_discounts_time_range").on(table.startsAt, table.endsAt),
156
+ usageIndex: (0, pg_core_1.index)("idx_discounts_usage").on(table.currentUsageCount, table.usageLimit),
157
+ salesChannelsIndex: (0, pg_core_1.index)("idx_discounts_sales_channels").on(table.salesChannels),
158
+ // Unique constraints
159
+ couponCodeUniquePerStore: (0, pg_core_1.unique)("idx_discounts_coupon_store_unique").on(table.storeId, table.couponCode),
160
+ }));
161
+ // =====================================================
162
+ // DISCOUNT USAGE TRACKING
163
+ // =====================================================
164
+ exports.discountUsages = (0, pg_core_1.pgTable)("discount_usages", {
165
+ id: (0, pg_core_1.text)("id")
166
+ .primaryKey()
167
+ .$defaultFn(() => (0, cuid2_1.createId)()),
168
+ discountId: (0, pg_core_1.text)("discount_id").notNull(),
169
+ storeId: (0, pg_core_1.text)("store_id").notNull(),
170
+ // Usage Context
171
+ orderId: (0, pg_core_1.text)("order_id"), // Reference to order if applicable
172
+ customerId: (0, pg_core_1.text)("customer_id"),
173
+ sessionId: (0, pg_core_1.text)("session_id"), // For anonymous users
174
+ // Applied Discount Details
175
+ originalAmount: (0, pg_core_1.decimal)("original_amount", { precision: 12, scale: 2 }).notNull(),
176
+ discountAmount: (0, pg_core_1.decimal)("discount_amount", { precision: 12, scale: 2 }).notNull(),
177
+ finalAmount: (0, pg_core_1.decimal)("final_amount", { precision: 12, scale: 2 }).notNull(),
178
+ // Context Information
179
+ appliedProducts: (0, pg_core_1.jsonb)("applied_products").$type(),
180
+ salesChannel: (0, pg_core_1.varchar)("sales_channel", { length: 20 }), // POS, MARKETPLACE, STOREFRONT
181
+ locationId: (0, pg_core_1.text)("location_id"), // Store location or warehouse
182
+ // Metadata
183
+ ipAddress: (0, pg_core_1.varchar)("ip_address", { length: 45 }),
184
+ userAgent: (0, pg_core_1.text)("user_agent"),
185
+ deviceType: (0, pg_core_1.varchar)("device_type", { length: 20 }),
186
+ // Timestamps
187
+ appliedAt: (0, pg_core_1.timestamp)("applied_at", { withTimezone: true })
188
+ .defaultNow()
189
+ .notNull(),
190
+ }, (table) => ({
191
+ discountIdIndex: (0, pg_core_1.index)("idx_discount_usages_discount_id").on(table.discountId),
192
+ storeIdIndex: (0, pg_core_1.index)("idx_discount_usages_store_id").on(table.storeId),
193
+ customerIdIndex: (0, pg_core_1.index)("idx_discount_usages_customer_id").on(table.customerId),
194
+ orderIdIndex: (0, pg_core_1.index)("idx_discount_usages_order_id").on(table.orderId),
195
+ appliedAtIndex: (0, pg_core_1.index)("idx_discount_usages_applied_at").on(table.appliedAt),
196
+ salesChannelIndex: (0, pg_core_1.index)("idx_discount_usages_sales_channel").on(table.salesChannel),
197
+ }));
198
+ // =====================================================
199
+ // DISCOUNT RULES ENGINE
200
+ // =====================================================
201
+ exports.discountRules = (0, pg_core_1.pgTable)("discount_rules", {
202
+ id: (0, pg_core_1.text)("id")
203
+ .primaryKey()
204
+ .$defaultFn(() => (0, cuid2_1.createId)()),
205
+ discountId: (0, pg_core_1.text)("discount_id").notNull(),
206
+ storeId: (0, pg_core_1.text)("store_id").notNull(),
207
+ // Rule Configuration
208
+ name: (0, pg_core_1.varchar)("name", { length: 255 }).notNull(),
209
+ description: (0, pg_core_1.text)("description"),
210
+ ruleType: (0, pg_core_1.varchar)("rule_type", { length: 50 }).notNull(), // CONDITION, ACTION, VALIDATION
211
+ // Rule Logic
212
+ conditions: (0, pg_core_1.jsonb)("conditions").$type().notNull(),
213
+ actions: (0, pg_core_1.jsonb)("actions").$type().default([]),
214
+ // Execution Configuration
215
+ priority: (0, pg_core_1.integer)("priority").notNull().default(0),
216
+ isActive: (0, pg_core_1.boolean)("is_active").notNull().default(true),
217
+ // Timestamps
218
+ createdAt: (0, pg_core_1.timestamp)("created_at", { withTimezone: true })
219
+ .defaultNow()
220
+ .notNull(),
221
+ updatedAt: (0, pg_core_1.timestamp)("updated_at", { withTimezone: true })
222
+ .defaultNow()
223
+ .notNull(),
224
+ }, (table) => ({
225
+ discountIdIndex: (0, pg_core_1.index)("idx_discount_rules_discount_id").on(table.discountId),
226
+ storeIdIndex: (0, pg_core_1.index)("idx_discount_rules_store_id").on(table.storeId),
227
+ priorityIndex: (0, pg_core_1.index)("idx_discount_rules_priority").on(table.priority),
228
+ activeIndex: (0, pg_core_1.index)("idx_discount_rules_active").on(table.isActive),
229
+ }));
230
+ // =====================================================
231
+ // CUSTOMER SEGMENTS
232
+ // =====================================================
233
+ exports.customerSegments = (0, pg_core_1.pgTable)("customer_segments", {
234
+ id: (0, pg_core_1.text)("id")
235
+ .primaryKey()
236
+ .$defaultFn(() => (0, cuid2_1.createId)()),
237
+ storeId: (0, pg_core_1.text)("store_id").notNull(),
238
+ // Segment Information
239
+ name: (0, pg_core_1.varchar)("name", { length: 255 }).notNull(),
240
+ description: (0, pg_core_1.text)("description"),
241
+ segmentType: (0, exports.customerSegmentTypeEnum)("segment_type").notNull(),
242
+ // Segment Criteria
243
+ criteria: (0, pg_core_1.jsonb)("criteria").$type(),
244
+ // Segment Statistics
245
+ memberCount: (0, pg_core_1.integer)("member_count").notNull().default(0),
246
+ lastCalculatedAt: (0, pg_core_1.timestamp)("last_calculated_at", { withTimezone: true }),
247
+ // Configuration
248
+ isActive: (0, pg_core_1.boolean)("is_active").notNull().default(true),
249
+ autoUpdate: (0, pg_core_1.boolean)("auto_update").notNull().default(true), // Auto-recalculate membership
250
+ // Timestamps
251
+ createdAt: (0, pg_core_1.timestamp)("created_at", { withTimezone: true })
252
+ .defaultNow()
253
+ .notNull(),
254
+ updatedAt: (0, pg_core_1.timestamp)("updated_at", { withTimezone: true })
255
+ .defaultNow()
256
+ .notNull(),
257
+ }, (table) => ({
258
+ storeIdIndex: (0, pg_core_1.index)("idx_customer_segments_store_id").on(table.storeId),
259
+ segmentTypeIndex: (0, pg_core_1.index)("idx_customer_segments_type").on(table.segmentType),
260
+ activeIndex: (0, pg_core_1.index)("idx_customer_segments_active").on(table.isActive),
261
+ memberCountIndex: (0, pg_core_1.index)("idx_customer_segments_member_count").on(table.memberCount),
262
+ }));
263
+ // =====================================================
264
+ // DISCOUNT ANALYTICS
265
+ // =====================================================
266
+ exports.discountAnalytics = (0, pg_core_1.pgTable)("discount_analytics", {
267
+ id: (0, pg_core_1.text)("id")
268
+ .primaryKey()
269
+ .$defaultFn(() => (0, cuid2_1.createId)()),
270
+ discountId: (0, pg_core_1.text)("discount_id").notNull(),
271
+ storeId: (0, pg_core_1.text)("store_id").notNull(),
272
+ // Time Period
273
+ periodType: (0, pg_core_1.varchar)("period_type", { length: 20 }).notNull(), // DAILY, WEEKLY, MONTHLY, YEARLY
274
+ periodStart: (0, pg_core_1.timestamp)("period_start", { withTimezone: true }).notNull(),
275
+ periodEnd: (0, pg_core_1.timestamp)("period_end", { withTimezone: true }).notNull(),
276
+ // Usage Metrics
277
+ totalUsages: (0, pg_core_1.integer)("total_usages").notNull().default(0),
278
+ uniqueCustomers: (0, pg_core_1.integer)("unique_customers").notNull().default(0),
279
+ totalSavings: (0, pg_core_1.decimal)("total_savings", { precision: 12, scale: 2 }).notNull().default("0"),
280
+ totalRevenue: (0, pg_core_1.decimal)("total_revenue", { precision: 12, scale: 2 }).notNull().default("0"),
281
+ avgOrderValue: (0, pg_core_1.decimal)("avg_order_value", { precision: 12, scale: 2 }),
282
+ // Performance Metrics
283
+ conversionRate: (0, pg_core_1.decimal)("conversion_rate", { precision: 5, scale: 4 }),
284
+ roi: (0, pg_core_1.decimal)("roi", { precision: 8, scale: 4 }), // Return on Investment
285
+ customerAcquisitionCost: (0, pg_core_1.decimal)("customer_acquisition_cost", { precision: 12, scale: 2 }),
286
+ // Channel Breakdown
287
+ channelBreakdown: (0, pg_core_1.jsonb)("channel_breakdown").$type(),
288
+ // Timestamps
289
+ calculatedAt: (0, pg_core_1.timestamp)("calculated_at", { withTimezone: true })
290
+ .defaultNow()
291
+ .notNull(),
292
+ }, (table) => ({
293
+ discountIdIndex: (0, pg_core_1.index)("idx_discount_analytics_discount_id").on(table.discountId),
294
+ storeIdIndex: (0, pg_core_1.index)("idx_discount_analytics_store_id").on(table.storeId),
295
+ periodIndex: (0, pg_core_1.index)("idx_discount_analytics_period").on(table.periodType, table.periodStart, table.periodEnd),
296
+ calculatedAtIndex: (0, pg_core_1.index)("idx_discount_analytics_calculated_at").on(table.calculatedAt),
297
+ }));
@@ -0,0 +1,41 @@
1
+ export declare const productsRelations: import("drizzle-orm").Relations<"products", {
2
+ variants: import("drizzle-orm").Many<"product_variants">;
3
+ images: import("drizzle-orm").Many<"product_images">;
4
+ reviews: import("drizzle-orm").Many<"product_reviews">;
5
+ analytics: import("drizzle-orm").Many<"product_analytics">;
6
+ productCollections: import("drizzle-orm").Many<"product_collections">;
7
+ wholesalePricingTiers: import("drizzle-orm").Many<"wholesale_pricing_tiers">;
8
+ category: import("drizzle-orm").One<"product_categories", false>;
9
+ }>;
10
+ export declare const productVariantsRelations: import("drizzle-orm").Relations<"product_variants", {
11
+ product: import("drizzle-orm").One<"products", true>;
12
+ images: import("drizzle-orm").Many<"product_images">;
13
+ reviews: import("drizzle-orm").Many<"product_reviews">;
14
+ }>;
15
+ export declare const collectionsRelations: import("drizzle-orm").Relations<"collections", {
16
+ productCollections: import("drizzle-orm").Many<"product_collections">;
17
+ }>;
18
+ export declare const productCollectionsRelations: import("drizzle-orm").Relations<"product_collections", {
19
+ product: import("drizzle-orm").One<"products", true>;
20
+ collection: import("drizzle-orm").One<"collections", true>;
21
+ }>;
22
+ export declare const productImagesRelations: import("drizzle-orm").Relations<"product_images", {
23
+ product: import("drizzle-orm").One<"products", true>;
24
+ variant: import("drizzle-orm").One<"product_variants", false>;
25
+ }>;
26
+ export declare const productCategoriesRelations: import("drizzle-orm").Relations<"product_categories", {
27
+ parent: import("drizzle-orm").One<"product_categories", false>;
28
+ children: import("drizzle-orm").Many<"product_categories">;
29
+ products: import("drizzle-orm").Many<"products">;
30
+ }>;
31
+ export declare const productReviewsRelations: import("drizzle-orm").Relations<"product_reviews", {
32
+ product: import("drizzle-orm").One<"products", true>;
33
+ variant: import("drizzle-orm").One<"product_variants", false>;
34
+ }>;
35
+ export declare const productAnalyticsRelations: import("drizzle-orm").Relations<"product_analytics", {
36
+ product: import("drizzle-orm").One<"products", true>;
37
+ }>;
38
+ export declare const wholesalePricingTiersRelations: import("drizzle-orm").Relations<"wholesale_pricing_tiers", {
39
+ product: import("drizzle-orm").One<"products", true>;
40
+ variant: import("drizzle-orm").One<"product_variants", false>;
41
+ }>;
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.wholesalePricingTiersRelations = exports.productAnalyticsRelations = exports.productReviewsRelations = exports.productCategoriesRelations = exports.productImagesRelations = exports.productCollectionsRelations = exports.collectionsRelations = exports.productVariantsRelations = exports.productsRelations = void 0;
4
+ const drizzle_orm_1 = require("drizzle-orm");
5
+ const product_schema_1 = require("./product-schema");
6
+ // =====================================================
7
+ // PRODUCT RELATIONS
8
+ // =====================================================
9
+ exports.productsRelations = (0, drizzle_orm_1.relations)(product_schema_1.products, ({ many, one }) => ({
10
+ // One product has many variants
11
+ variants: many(product_schema_1.productVariants),
12
+ // One product has many images
13
+ images: many(product_schema_1.productImages),
14
+ // One product has many reviews
15
+ reviews: many(product_schema_1.productReviews),
16
+ // One product has many analytics records
17
+ analytics: many(product_schema_1.productAnalytics),
18
+ // One product belongs to many collections (many-to-many)
19
+ productCollections: many(product_schema_1.productCollections),
20
+ // One product has many wholesale pricing tiers
21
+ wholesalePricingTiers: many(product_schema_1.wholesalePricingTiers),
22
+ // One product belongs to one category (optional)
23
+ category: one(product_schema_1.productCategories, {
24
+ fields: [product_schema_1.products.category],
25
+ references: [product_schema_1.productCategories.handle],
26
+ }),
27
+ }));
28
+ // =====================================================
29
+ // PRODUCT VARIANTS RELATIONS
30
+ // =====================================================
31
+ exports.productVariantsRelations = (0, drizzle_orm_1.relations)(product_schema_1.productVariants, ({ one, many }) => ({
32
+ // One variant belongs to one product
33
+ product: one(product_schema_1.products, {
34
+ fields: [product_schema_1.productVariants.productId],
35
+ references: [product_schema_1.products.id],
36
+ }),
37
+ // One variant can have many images
38
+ images: many(product_schema_1.productImages),
39
+ // One variant can have many reviews
40
+ reviews: many(product_schema_1.productReviews),
41
+ }));
42
+ // =====================================================
43
+ // COLLECTIONS RELATIONS
44
+ // =====================================================
45
+ exports.collectionsRelations = (0, drizzle_orm_1.relations)(product_schema_1.collections, ({ many }) => ({
46
+ // One collection has many products (many-to-many)
47
+ productCollections: many(product_schema_1.productCollections),
48
+ }));
49
+ // =====================================================
50
+ // PRODUCT COLLECTIONS JUNCTION RELATIONS
51
+ // =====================================================
52
+ exports.productCollectionsRelations = (0, drizzle_orm_1.relations)(product_schema_1.productCollections, ({ one }) => ({
53
+ // Junction table relations
54
+ product: one(product_schema_1.products, {
55
+ fields: [product_schema_1.productCollections.productId],
56
+ references: [product_schema_1.products.id],
57
+ }),
58
+ collection: one(product_schema_1.collections, {
59
+ fields: [product_schema_1.productCollections.collectionId],
60
+ references: [product_schema_1.collections.id],
61
+ }),
62
+ }));
63
+ // =====================================================
64
+ // PRODUCT IMAGES RELATIONS
65
+ // =====================================================
66
+ exports.productImagesRelations = (0, drizzle_orm_1.relations)(product_schema_1.productImages, ({ one }) => ({
67
+ // One image belongs to one product
68
+ product: one(product_schema_1.products, {
69
+ fields: [product_schema_1.productImages.productId],
70
+ references: [product_schema_1.products.id],
71
+ }),
72
+ // One image can belong to one variant (optional)
73
+ variant: one(product_schema_1.productVariants, {
74
+ fields: [product_schema_1.productImages.variantId],
75
+ references: [product_schema_1.productVariants.id],
76
+ }),
77
+ }));
78
+ // =====================================================
79
+ // PRODUCT CATEGORIES RELATIONS
80
+ // =====================================================
81
+ exports.productCategoriesRelations = (0, drizzle_orm_1.relations)(product_schema_1.productCategories, ({ one, many }) => ({
82
+ // Self-referencing relationship for hierarchy
83
+ parent: one(product_schema_1.productCategories, {
84
+ fields: [product_schema_1.productCategories.parentId],
85
+ references: [product_schema_1.productCategories.id],
86
+ relationName: "CategoryParent",
87
+ }),
88
+ children: many(product_schema_1.productCategories, {
89
+ relationName: "CategoryParent",
90
+ }),
91
+ // One category can have many products
92
+ products: many(product_schema_1.products),
93
+ }));
94
+ // =====================================================
95
+ // PRODUCT REVIEWS RELATIONS
96
+ // =====================================================
97
+ exports.productReviewsRelations = (0, drizzle_orm_1.relations)(product_schema_1.productReviews, ({ one }) => ({
98
+ // One review belongs to one product
99
+ product: one(product_schema_1.products, {
100
+ fields: [product_schema_1.productReviews.productId],
101
+ references: [product_schema_1.products.id],
102
+ }),
103
+ // One review can belong to one variant (optional)
104
+ variant: one(product_schema_1.productVariants, {
105
+ fields: [product_schema_1.productReviews.variantId],
106
+ references: [product_schema_1.productVariants.id],
107
+ }),
108
+ }));
109
+ // =====================================================
110
+ // PRODUCT ANALYTICS RELATIONS
111
+ // =====================================================
112
+ exports.productAnalyticsRelations = (0, drizzle_orm_1.relations)(product_schema_1.productAnalytics, ({ one }) => ({
113
+ // One analytics record belongs to one product
114
+ product: one(product_schema_1.products, {
115
+ fields: [product_schema_1.productAnalytics.productId],
116
+ references: [product_schema_1.products.id],
117
+ }),
118
+ }));
119
+ // =====================================================
120
+ // WHOLESALE PRICING TIERS RELATIONS
121
+ // =====================================================
122
+ exports.wholesalePricingTiersRelations = (0, drizzle_orm_1.relations)(product_schema_1.wholesalePricingTiers, ({ one }) => ({
123
+ // One tier belongs to one product
124
+ product: one(product_schema_1.products, {
125
+ fields: [product_schema_1.wholesalePricingTiers.productId],
126
+ references: [product_schema_1.products.id],
127
+ }),
128
+ // One tier can belong to one variant (optional)
129
+ variant: one(product_schema_1.productVariants, {
130
+ fields: [product_schema_1.wholesalePricingTiers.variantId],
131
+ references: [product_schema_1.productVariants.id],
132
+ }),
133
+ }));