@voyantjs/sellability 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
package/dist/schema.js ADDED
@@ -0,0 +1,276 @@
1
+ import { typeId, typeIdRef } from "@voyantjs/db/lib/typeid-column";
2
+ import { relations } from "drizzle-orm";
3
+ import { boolean, index, integer, jsonb, pgEnum, pgTable, text, timestamp, } from "drizzle-orm/pg-core";
4
+ export const sellabilitySnapshotStatusEnum = pgEnum("sellability_snapshot_status", [
5
+ "resolved",
6
+ "offer_constructed",
7
+ "expired",
8
+ ]);
9
+ export const sellabilitySnapshotComponentKindEnum = pgEnum("sellability_snapshot_component_kind", [
10
+ "base",
11
+ "unit",
12
+ "pickup",
13
+ "start_time_adjustment",
14
+ ]);
15
+ export const sellabilityPolicyScopeEnum = pgEnum("sellability_policy_scope", [
16
+ "global",
17
+ "product",
18
+ "option",
19
+ "market",
20
+ "channel",
21
+ ]);
22
+ export const sellabilityPolicyTypeEnum = pgEnum("sellability_policy_type", [
23
+ "capability",
24
+ "occupancy",
25
+ "pickup",
26
+ "question",
27
+ "allotment",
28
+ "availability_window",
29
+ "currency",
30
+ "custom",
31
+ ]);
32
+ export const sellabilityPolicyResultStatusEnum = pgEnum("sellability_policy_result_status", [
33
+ "passed",
34
+ "blocked",
35
+ "warning",
36
+ "adjusted",
37
+ ]);
38
+ export const offerRefreshRunStatusEnum = pgEnum("offer_refresh_run_status", [
39
+ "pending",
40
+ "running",
41
+ "completed",
42
+ "failed",
43
+ "expired",
44
+ ]);
45
+ export const offerExpirationEventStatusEnum = pgEnum("offer_expiration_event_status", [
46
+ "scheduled",
47
+ "expired",
48
+ "cancelled",
49
+ "superseded",
50
+ ]);
51
+ export const sellabilityExplanationTypeEnum = pgEnum("sellability_explanation_type", [
52
+ "sellable",
53
+ "blocked",
54
+ "warning",
55
+ "pricing",
56
+ "allotment",
57
+ "pickup",
58
+ "policy",
59
+ ]);
60
+ export const sellabilitySnapshots = pgTable("sellability_snapshots", {
61
+ id: typeId("sellability_snapshots"),
62
+ offerId: text("offer_id"),
63
+ marketId: text("market_id"),
64
+ channelId: text("channel_id"),
65
+ productId: text("product_id"),
66
+ optionId: text("option_id"),
67
+ slotId: text("slot_id"),
68
+ requestedCurrencyCode: text("requested_currency_code"),
69
+ sourceCurrencyCode: text("source_currency_code"),
70
+ fxRateSetId: text("fx_rate_set_id"),
71
+ status: sellabilitySnapshotStatusEnum("status").notNull().default("resolved"),
72
+ queryPayload: jsonb("query_payload").$type().notNull(),
73
+ pricingSummary: jsonb("pricing_summary").$type().notNull(),
74
+ expiresAt: timestamp("expires_at", { withTimezone: true }),
75
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
76
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
77
+ }, (table) => [
78
+ index("idx_sellability_snapshots_offer").on(table.offerId),
79
+ index("idx_sellability_snapshots_market").on(table.marketId),
80
+ index("idx_sellability_snapshots_channel").on(table.channelId),
81
+ index("idx_sellability_snapshots_product").on(table.productId),
82
+ index("idx_sellability_snapshots_option").on(table.optionId),
83
+ index("idx_sellability_snapshots_slot").on(table.slotId),
84
+ index("idx_sellability_snapshots_status").on(table.status),
85
+ ]);
86
+ export const sellabilitySnapshotItems = pgTable("sellability_snapshot_items", {
87
+ id: typeId("sellability_snapshot_items"),
88
+ snapshotId: typeIdRef("snapshot_id")
89
+ .notNull()
90
+ .references(() => sellabilitySnapshots.id, { onDelete: "cascade" }),
91
+ candidateIndex: integer("candidate_index").notNull().default(0),
92
+ componentIndex: integer("component_index").notNull().default(0),
93
+ productId: text("product_id"),
94
+ optionId: text("option_id"),
95
+ slotId: text("slot_id"),
96
+ unitId: text("unit_id"),
97
+ requestRef: text("request_ref"),
98
+ componentKind: sellabilitySnapshotComponentKindEnum("component_kind").notNull(),
99
+ title: text("title").notNull(),
100
+ quantity: integer("quantity").notNull().default(1),
101
+ pricingMode: text("pricing_mode").notNull(),
102
+ pricingCategoryId: text("pricing_category_id"),
103
+ pricingCategoryName: text("pricing_category_name"),
104
+ unitName: text("unit_name"),
105
+ unitType: text("unit_type"),
106
+ currencyCode: text("currency_code").notNull(),
107
+ sellAmountCents: integer("sell_amount_cents").notNull().default(0),
108
+ costAmountCents: integer("cost_amount_cents").notNull().default(0),
109
+ sourceRuleId: text("source_rule_id"),
110
+ tierId: text("tier_id"),
111
+ isSelected: boolean("is_selected").notNull().default(true),
112
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
113
+ }, (table) => [
114
+ index("idx_sellability_snapshot_items_snapshot").on(table.snapshotId),
115
+ index("idx_sellability_snapshot_items_candidate").on(table.candidateIndex),
116
+ index("idx_sellability_snapshot_items_component").on(table.componentKind),
117
+ index("idx_sellability_snapshot_items_product").on(table.productId),
118
+ index("idx_sellability_snapshot_items_option").on(table.optionId),
119
+ index("idx_sellability_snapshot_items_slot").on(table.slotId),
120
+ index("idx_sellability_snapshot_items_unit").on(table.unitId),
121
+ ]);
122
+ export const sellabilityPolicies = pgTable("sellability_policies", {
123
+ id: typeId("sellability_policies"),
124
+ name: text("name").notNull(),
125
+ scope: sellabilityPolicyScopeEnum("scope").notNull().default("global"),
126
+ policyType: sellabilityPolicyTypeEnum("policy_type").notNull().default("custom"),
127
+ productId: text("product_id"),
128
+ optionId: text("option_id"),
129
+ marketId: text("market_id"),
130
+ channelId: text("channel_id"),
131
+ priority: integer("priority").notNull().default(0),
132
+ active: boolean("active").notNull().default(true),
133
+ conditions: jsonb("conditions").$type().notNull().default({}),
134
+ effects: jsonb("effects").$type().notNull().default({}),
135
+ notes: text("notes"),
136
+ metadata: jsonb("metadata").$type(),
137
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
138
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
139
+ }, (table) => [
140
+ index("idx_sellability_policies_scope").on(table.scope),
141
+ index("idx_sellability_policies_type").on(table.policyType),
142
+ index("idx_sellability_policies_product").on(table.productId),
143
+ index("idx_sellability_policies_option").on(table.optionId),
144
+ index("idx_sellability_policies_market").on(table.marketId),
145
+ index("idx_sellability_policies_channel").on(table.channelId),
146
+ index("idx_sellability_policies_active").on(table.active),
147
+ ]);
148
+ export const sellabilityPolicyResults = pgTable("sellability_policy_results", {
149
+ id: typeId("sellability_policy_results"),
150
+ snapshotId: typeIdRef("snapshot_id")
151
+ .notNull()
152
+ .references(() => sellabilitySnapshots.id, { onDelete: "cascade" }),
153
+ snapshotItemId: typeIdRef("snapshot_item_id").references(() => sellabilitySnapshotItems.id, {
154
+ onDelete: "set null",
155
+ }),
156
+ policyId: typeIdRef("policy_id").references(() => sellabilityPolicies.id, {
157
+ onDelete: "set null",
158
+ }),
159
+ candidateIndex: integer("candidate_index").notNull().default(0),
160
+ status: sellabilityPolicyResultStatusEnum("status").notNull().default("passed"),
161
+ message: text("message"),
162
+ details: jsonb("details").$type(),
163
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
164
+ }, (table) => [
165
+ index("idx_sellability_policy_results_snapshot").on(table.snapshotId),
166
+ index("idx_sellability_policy_results_snapshot_item").on(table.snapshotItemId),
167
+ index("idx_sellability_policy_results_policy").on(table.policyId),
168
+ index("idx_sellability_policy_results_status").on(table.status),
169
+ ]);
170
+ export const offerRefreshRuns = pgTable("offer_refresh_runs", {
171
+ id: typeId("offer_refresh_runs"),
172
+ offerId: text("offer_id").notNull(),
173
+ snapshotId: typeIdRef("snapshot_id").references(() => sellabilitySnapshots.id, {
174
+ onDelete: "set null",
175
+ }),
176
+ status: offerRefreshRunStatusEnum("status").notNull().default("pending"),
177
+ startedAt: timestamp("started_at", { withTimezone: true }).notNull().defaultNow(),
178
+ completedAt: timestamp("completed_at", { withTimezone: true }),
179
+ notes: text("notes"),
180
+ metadata: jsonb("metadata").$type(),
181
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
182
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
183
+ }, (table) => [
184
+ index("idx_offer_refresh_runs_offer").on(table.offerId),
185
+ index("idx_offer_refresh_runs_snapshot").on(table.snapshotId),
186
+ index("idx_offer_refresh_runs_status").on(table.status),
187
+ ]);
188
+ export const offerExpirationEvents = pgTable("offer_expiration_events", {
189
+ id: typeId("offer_expiration_events"),
190
+ offerId: text("offer_id").notNull(),
191
+ snapshotId: typeIdRef("snapshot_id").references(() => sellabilitySnapshots.id, {
192
+ onDelete: "set null",
193
+ }),
194
+ expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
195
+ expiredAt: timestamp("expired_at", { withTimezone: true }),
196
+ status: offerExpirationEventStatusEnum("status").notNull().default("scheduled"),
197
+ reason: text("reason"),
198
+ metadata: jsonb("metadata").$type(),
199
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
200
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
201
+ }, (table) => [
202
+ index("idx_offer_expiration_events_offer").on(table.offerId),
203
+ index("idx_offer_expiration_events_snapshot").on(table.snapshotId),
204
+ index("idx_offer_expiration_events_status").on(table.status),
205
+ ]);
206
+ export const sellabilityExplanations = pgTable("sellability_explanations", {
207
+ id: typeId("sellability_explanations"),
208
+ snapshotId: typeIdRef("snapshot_id")
209
+ .notNull()
210
+ .references(() => sellabilitySnapshots.id, { onDelete: "cascade" }),
211
+ snapshotItemId: typeIdRef("snapshot_item_id").references(() => sellabilitySnapshotItems.id, {
212
+ onDelete: "set null",
213
+ }),
214
+ candidateIndex: integer("candidate_index").notNull().default(0),
215
+ explanationType: sellabilityExplanationTypeEnum("explanation_type").notNull().default("policy"),
216
+ code: text("code"),
217
+ message: text("message").notNull(),
218
+ details: jsonb("details").$type(),
219
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
220
+ }, (table) => [
221
+ index("idx_sellability_explanations_snapshot").on(table.snapshotId),
222
+ index("idx_sellability_explanations_snapshot_item").on(table.snapshotItemId),
223
+ index("idx_sellability_explanations_type").on(table.explanationType),
224
+ ]);
225
+ export const sellabilitySnapshotsRelations = relations(sellabilitySnapshots, ({ many }) => ({
226
+ items: many(sellabilitySnapshotItems),
227
+ policyResults: many(sellabilityPolicyResults),
228
+ explanations: many(sellabilityExplanations),
229
+ refreshRuns: many(offerRefreshRuns),
230
+ expirationEvents: many(offerExpirationEvents),
231
+ }));
232
+ export const sellabilitySnapshotItemsRelations = relations(sellabilitySnapshotItems, ({ one }) => ({
233
+ snapshot: one(sellabilitySnapshots, {
234
+ fields: [sellabilitySnapshotItems.snapshotId],
235
+ references: [sellabilitySnapshots.id],
236
+ }),
237
+ }));
238
+ export const sellabilityPoliciesRelations = relations(sellabilityPolicies, ({ many }) => ({
239
+ results: many(sellabilityPolicyResults),
240
+ }));
241
+ export const sellabilityPolicyResultsRelations = relations(sellabilityPolicyResults, ({ one }) => ({
242
+ snapshot: one(sellabilitySnapshots, {
243
+ fields: [sellabilityPolicyResults.snapshotId],
244
+ references: [sellabilitySnapshots.id],
245
+ }),
246
+ snapshotItem: one(sellabilitySnapshotItems, {
247
+ fields: [sellabilityPolicyResults.snapshotItemId],
248
+ references: [sellabilitySnapshotItems.id],
249
+ }),
250
+ policy: one(sellabilityPolicies, {
251
+ fields: [sellabilityPolicyResults.policyId],
252
+ references: [sellabilityPolicies.id],
253
+ }),
254
+ }));
255
+ export const offerRefreshRunsRelations = relations(offerRefreshRuns, ({ one }) => ({
256
+ snapshot: one(sellabilitySnapshots, {
257
+ fields: [offerRefreshRuns.snapshotId],
258
+ references: [sellabilitySnapshots.id],
259
+ }),
260
+ }));
261
+ export const offerExpirationEventsRelations = relations(offerExpirationEvents, ({ one }) => ({
262
+ snapshot: one(sellabilitySnapshots, {
263
+ fields: [offerExpirationEvents.snapshotId],
264
+ references: [sellabilitySnapshots.id],
265
+ }),
266
+ }));
267
+ export const sellabilityExplanationsRelations = relations(sellabilityExplanations, ({ one }) => ({
268
+ snapshot: one(sellabilitySnapshots, {
269
+ fields: [sellabilityExplanations.snapshotId],
270
+ references: [sellabilitySnapshots.id],
271
+ }),
272
+ snapshotItem: one(sellabilitySnapshotItems, {
273
+ fields: [sellabilityExplanations.snapshotItemId],
274
+ references: [sellabilitySnapshotItems.id],
275
+ }),
276
+ }));