@foundrynorth/compass-schema 1.0.21 → 1.0.22
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/schema.d.ts +2198 -324
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +136 -5
- package/dist/schema.js.map +1 -1
- package/package.json +1 -1
- package/src/schema.ts +195 -5
package/dist/schema.js
CHANGED
|
@@ -475,6 +475,30 @@ export const competitorSchema = z.object({
|
|
|
475
475
|
lng: z.number(),
|
|
476
476
|
})
|
|
477
477
|
.optional(), // Detailed location information
|
|
478
|
+
// Ad library data from Apify deep enrichment
|
|
479
|
+
ads: z
|
|
480
|
+
.object({
|
|
481
|
+
facebook: z
|
|
482
|
+
.array(z.object({
|
|
483
|
+
adImage: z.string().optional(),
|
|
484
|
+
headline: z.string().optional(),
|
|
485
|
+
adCopy: z.string().optional(),
|
|
486
|
+
callToAction: z.string().optional(),
|
|
487
|
+
publisherPlatforms: z.array(z.string()).optional(),
|
|
488
|
+
startDate: z.string().optional(),
|
|
489
|
+
}))
|
|
490
|
+
.optional(),
|
|
491
|
+
google: z
|
|
492
|
+
.array(z.object({
|
|
493
|
+
headline: z.string().optional(),
|
|
494
|
+
description: z.string().optional(),
|
|
495
|
+
landingPage: z.string().optional(),
|
|
496
|
+
adType: z.string().optional(),
|
|
497
|
+
imageUrl: z.string().optional(),
|
|
498
|
+
}))
|
|
499
|
+
.optional(),
|
|
500
|
+
})
|
|
501
|
+
.optional(),
|
|
478
502
|
});
|
|
479
503
|
export const extractionResultSchema = z.object({
|
|
480
504
|
brand: z.string(),
|
|
@@ -1016,6 +1040,7 @@ export const plans = pgTable("plans", {
|
|
|
1016
1040
|
defaultTargeting: text("default_targeting"),
|
|
1017
1041
|
defaultAudience: text("default_audience"),
|
|
1018
1042
|
defaultPromoting: text("default_promoting"),
|
|
1043
|
+
defaultCreativeSource: varchar("default_creative_source"),
|
|
1019
1044
|
defaultFlightStart: date("default_flight_start"),
|
|
1020
1045
|
defaultFlightEnd: date("default_flight_end"),
|
|
1021
1046
|
// Slack integration — per-plan client channel for alert routing
|
|
@@ -1069,8 +1094,12 @@ export const proposals = pgTable("proposals", {
|
|
|
1069
1094
|
.primaryKey()
|
|
1070
1095
|
.default(sql `gen_random_uuid()`),
|
|
1071
1096
|
// Optional plan reference (nullable — can be standalone)
|
|
1072
|
-
planId: varchar("plan_id"),
|
|
1073
|
-
|
|
1097
|
+
planId: varchar("plan_id").references(() => plans.id, {
|
|
1098
|
+
onDelete: "set null",
|
|
1099
|
+
}),
|
|
1100
|
+
engagementId: varchar("engagement_id").references(() => engagements.id, {
|
|
1101
|
+
onDelete: "set null",
|
|
1102
|
+
}), // nullable during transition
|
|
1074
1103
|
// Configuration references (which plan_configurations to include)
|
|
1075
1104
|
configurationIds: jsonb("configuration_ids").$type(),
|
|
1076
1105
|
optionIds: jsonb("option_ids").$type(),
|
|
@@ -1122,6 +1151,35 @@ export const insertPlanSchema = createInsertSchema(plans).omit({
|
|
|
1122
1151
|
id: true,
|
|
1123
1152
|
createdAt: true,
|
|
1124
1153
|
});
|
|
1154
|
+
// ============================================================================
|
|
1155
|
+
// Proposal Engagement Tracking
|
|
1156
|
+
// ============================================================================
|
|
1157
|
+
export const proposalEngagement = pgTable("proposal_engagement", {
|
|
1158
|
+
id: varchar("id")
|
|
1159
|
+
.primaryKey()
|
|
1160
|
+
.default(sql `gen_random_uuid()`),
|
|
1161
|
+
proposalId: varchar("proposal_id"), // FK → proposals.id (nullable for legacy plan-based shares)
|
|
1162
|
+
planId: varchar("plan_id"), // FK → plans.id (fallback for legacy shares)
|
|
1163
|
+
shareToken: text("share_token").notNull(), // The share token used to access
|
|
1164
|
+
sessionId: text("session_id").notNull(), // Anonymous session ID (crypto.randomUUID on client)
|
|
1165
|
+
// Engagement data
|
|
1166
|
+
events: jsonb("events").notNull().default(sql `'[]'::jsonb`), // Array of engagement events
|
|
1167
|
+
engagementScore: integer("engagement_score").default(0), // Computed 0-100 score
|
|
1168
|
+
summary: text("summary"), // AI-generated follow-up brief
|
|
1169
|
+
// Device context
|
|
1170
|
+
device: text("device"), // "desktop" | "mobile" | "tablet"
|
|
1171
|
+
referrer: text("referrer"), // HTTP referrer
|
|
1172
|
+
userAgent: text("user_agent"),
|
|
1173
|
+
// Timestamps
|
|
1174
|
+
firstSeenAt: timestamp("first_seen_at").notNull().defaultNow(),
|
|
1175
|
+
lastSeenAt: timestamp("last_seen_at").notNull().defaultNow(),
|
|
1176
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
1177
|
+
}, (table) => [
|
|
1178
|
+
index("proposal_engagement_proposal_id_idx").on(table.proposalId),
|
|
1179
|
+
index("proposal_engagement_plan_id_idx").on(table.planId),
|
|
1180
|
+
index("proposal_engagement_share_token_idx").on(table.shareToken),
|
|
1181
|
+
index("proposal_engagement_token_session_idx").on(table.shareToken, table.sessionId),
|
|
1182
|
+
]);
|
|
1125
1183
|
// Plan Configurations — Named product mixes (replaces monolithic planAllocations)
|
|
1126
1184
|
// A plan can have multiple configurations (e.g., "Digital Focus", "Full Mix", "Print Heavy")
|
|
1127
1185
|
export const planConfigurations = pgTable("plan_configurations", {
|
|
@@ -3333,20 +3391,84 @@ export const insertSalesInitiativeSchema = createInsertSchema(salesInitiatives).
|
|
|
3333
3391
|
updatedAt: true,
|
|
3334
3392
|
});
|
|
3335
3393
|
export const updateSalesInitiativeSchema = insertSalesInitiativeSchema.partial();
|
|
3394
|
+
export const salesPackages = pgTable("sales_packages", {
|
|
3395
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
3396
|
+
code: varchar("code").notNull().unique(),
|
|
3397
|
+
name: varchar("name").notNull(),
|
|
3398
|
+
description: text("description"),
|
|
3399
|
+
initiativeCode: varchar("initiative_code"),
|
|
3400
|
+
sellerSummary: text("seller_summary"),
|
|
3401
|
+
packagePrice: numeric("package_price", { precision: 12, scale: 2 }),
|
|
3402
|
+
discountPercent: numeric("discount_percent", { precision: 5, scale: 2 }),
|
|
3403
|
+
addedValueAmount: numeric("added_value_amount", { precision: 12, scale: 2 }),
|
|
3404
|
+
addedValueDescription: varchar("added_value_description", { length: 255 }),
|
|
3405
|
+
hubspotPackageValue: varchar("hubspot_package_value").notNull().unique(),
|
|
3406
|
+
startsAt: date("starts_at"),
|
|
3407
|
+
endsAt: date("ends_at"),
|
|
3408
|
+
status: varchar("status").notNull().default("draft"),
|
|
3409
|
+
recommendationMode: varchar("recommendation_mode").notNull().default("both"),
|
|
3410
|
+
recommendationPriority: integer("recommendation_priority").notNull().default(0),
|
|
3411
|
+
eligibilityRules: jsonb("eligibility_rules").$type(),
|
|
3412
|
+
assistantHints: jsonb("assistant_hints").$type(),
|
|
3413
|
+
taskTemplateMode: varchar("task_template_mode").notNull().default("standard"),
|
|
3414
|
+
displayOrder: integer("display_order").notNull().default(0),
|
|
3415
|
+
isActive: boolean("is_active").notNull().default(true),
|
|
3416
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
3417
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
3418
|
+
}, (table) => [
|
|
3419
|
+
index("sales_packages_active_idx").on(table.isActive),
|
|
3420
|
+
index("sales_packages_status_idx").on(table.status),
|
|
3421
|
+
index("sales_packages_display_order_idx").on(table.displayOrder),
|
|
3422
|
+
index("sales_packages_initiative_code_idx").on(table.initiativeCode),
|
|
3423
|
+
]);
|
|
3424
|
+
export const insertSalesPackageSchema = createInsertSchema(salesPackages).omit({
|
|
3425
|
+
id: true,
|
|
3426
|
+
createdAt: true,
|
|
3427
|
+
updatedAt: true,
|
|
3428
|
+
});
|
|
3429
|
+
export const updateSalesPackageSchema = insertSalesPackageSchema.partial();
|
|
3430
|
+
export const salesPackageProducts = pgTable("sales_package_products", {
|
|
3431
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
3432
|
+
salesPackageCode: varchar("sales_package_code").notNull(),
|
|
3433
|
+
stribProductId: uuid("strib_product_id")
|
|
3434
|
+
.notNull()
|
|
3435
|
+
.references(() => stribProducts.id, { onDelete: "cascade" }),
|
|
3436
|
+
displayOrder: integer("display_order").notNull().default(0),
|
|
3437
|
+
approvedUnitRate: numeric("approved_unit_rate", { precision: 12, scale: 4 }),
|
|
3438
|
+
approvedRateType: varchar("approved_rate_type"),
|
|
3439
|
+
allocationMode: varchar("allocation_mode").notNull().default("percent"),
|
|
3440
|
+
allocationValue: numeric("allocation_value", { precision: 12, scale: 4 }),
|
|
3441
|
+
required: boolean("required").notNull().default(true),
|
|
3442
|
+
defaultFulfillmentDetails: jsonb("default_fulfillment_details"),
|
|
3443
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
3444
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
3445
|
+
}, (table) => [
|
|
3446
|
+
uniqueIndex("sales_package_products_unique_idx").on(table.salesPackageCode, table.stribProductId),
|
|
3447
|
+
index("sales_package_products_code_idx").on(table.salesPackageCode),
|
|
3448
|
+
index("sales_package_products_product_idx").on(table.stribProductId),
|
|
3449
|
+
]);
|
|
3336
3450
|
export const mediaOrders = pgTable("media_orders", {
|
|
3337
3451
|
id: varchar("id")
|
|
3338
3452
|
.primaryKey()
|
|
3339
3453
|
.default(sql `gen_random_uuid()`),
|
|
3340
|
-
planId: varchar("plan_id")
|
|
3341
|
-
|
|
3454
|
+
planId: varchar("plan_id").references(() => plans.id, {
|
|
3455
|
+
onDelete: "set null",
|
|
3456
|
+
}), // nullable — can exist without a plan
|
|
3457
|
+
engagementId: varchar("engagement_id").references(() => engagements.id, {
|
|
3458
|
+
onDelete: "set null",
|
|
3459
|
+
}), // nullable during transition
|
|
3342
3460
|
configurationId: varchar("configuration_id"), // FK → plan_configurations.id (named product mix)
|
|
3343
3461
|
optionId: varchar("option_id"), // FK → plan_options.id (canonical selected option)
|
|
3344
|
-
contractId: uuid("contract_id")
|
|
3462
|
+
contractId: uuid("contract_id").references(() => contracts.id, {
|
|
3463
|
+
onDelete: "set null",
|
|
3464
|
+
}), // nullable — links to annual contract
|
|
3345
3465
|
partnerId: varchar("partner_id"),
|
|
3346
3466
|
hubspotDealId: text("hubspot_deal_id"),
|
|
3347
3467
|
hubspotCompanyId: text("hubspot_company_id"),
|
|
3348
3468
|
parentHubspotCompanyId: text("parent_hubspot_company_id"),
|
|
3349
3469
|
initiativeCode: varchar("initiative_code"),
|
|
3470
|
+
salesPackageCode: varchar("sales_package_code"),
|
|
3471
|
+
salesPackageSnapshot: jsonb("sales_package_snapshot").$type(),
|
|
3350
3472
|
// Client header
|
|
3351
3473
|
clientName: text("client_name").notNull(),
|
|
3352
3474
|
clientContactName: text("client_contact_name"),
|
|
@@ -3451,6 +3573,7 @@ export const mediaOrders = pgTable("media_orders", {
|
|
|
3451
3573
|
index("media_orders_parent_company_idx").on(table.parentHubspotCompanyId),
|
|
3452
3574
|
index("media_orders_contract_id_idx").on(table.contractId),
|
|
3453
3575
|
index("media_orders_initiative_code_idx").on(table.initiativeCode),
|
|
3576
|
+
index("media_orders_sales_package_code_idx").on(table.salesPackageCode),
|
|
3454
3577
|
]);
|
|
3455
3578
|
export const insertMediaOrderSchema = createInsertSchema(mediaOrders).omit({
|
|
3456
3579
|
id: true,
|
|
@@ -3544,6 +3667,10 @@ export const mediaOrderLineItems = pgTable("media_order_line_items", {
|
|
|
3544
3667
|
fulfillmentDetails: jsonb("fulfillment_details"),
|
|
3545
3668
|
creativeSource: varchar("creative_source"),
|
|
3546
3669
|
initiativeCode: varchar("initiative_code"),
|
|
3670
|
+
salesPackageCode: varchar("sales_package_code"),
|
|
3671
|
+
salesPackageComponentRef: varchar("sales_package_component_ref"),
|
|
3672
|
+
isPackageDerived: boolean("is_package_derived").notNull().default(false),
|
|
3673
|
+
packagePricingSource: varchar("package_pricing_source"),
|
|
3547
3674
|
// Ad trafficking reference key (auto-generated naming convention)
|
|
3548
3675
|
trafficKey: text("traffic_key"),
|
|
3549
3676
|
// Canonical tracking fields for DSP/reporting consistency
|
|
@@ -3558,6 +3685,7 @@ export const mediaOrderLineItems = pgTable("media_order_line_items", {
|
|
|
3558
3685
|
index("media_order_line_items_location_id_idx").on(table.locationId),
|
|
3559
3686
|
index("media_order_line_items_tracking_key_idx").on(table.trackingKey),
|
|
3560
3687
|
index("media_order_line_items_initiative_code_idx").on(table.initiativeCode),
|
|
3688
|
+
index("media_order_line_items_sales_package_code_idx").on(table.salesPackageCode),
|
|
3561
3689
|
]);
|
|
3562
3690
|
export const insertMediaOrderLineItemSchema = createInsertSchema(mediaOrderLineItems).omit({
|
|
3563
3691
|
id: true,
|
|
@@ -6044,6 +6172,7 @@ export const semCampaigns = pgTable("sem_campaigns", {
|
|
|
6044
6172
|
// =============================================================================
|
|
6045
6173
|
export const compassEventOutboxStatusEnum = pgEnum("compass_event_outbox_status", [
|
|
6046
6174
|
"pending",
|
|
6175
|
+
"processing",
|
|
6047
6176
|
"failed",
|
|
6048
6177
|
"delivered",
|
|
6049
6178
|
"dead_letter",
|
|
@@ -6116,6 +6245,8 @@ export const pendingActions = pgTable("pending_actions", {
|
|
|
6116
6245
|
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
6117
6246
|
}, (table) => [
|
|
6118
6247
|
index("pending_actions_order_idx").on(table.mediaOrderId),
|
|
6248
|
+
index("pending_actions_line_item_idx").on(table.lineItemId),
|
|
6249
|
+
index("pending_actions_activity_feed_idx").on(table.activityFeedId),
|
|
6119
6250
|
index("pending_actions_unresolved_idx").on(table.mediaOrderId).where(sql `resolved_at IS NULL`),
|
|
6120
6251
|
]);
|
|
6121
6252
|
// ─── Order Version Snapshots ────────────────────────────────────────────────
|