@foundrynorth/flux-schema 1.19.11 → 1.21.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.
package/dist/schema.d.ts CHANGED
@@ -40,6 +40,24 @@ export declare const fluxSecretsStatusEnum: import("drizzle-orm/pg-core").PgEnum
40
40
  export declare const fluxSecretsPlatformEnum: import("drizzle-orm/pg-core").PgEnum<["railway", "vercel", "trigger", "local"]>;
41
41
  export declare const fluxSecretsSyncStatusEnum: import("drizzle-orm/pg-core").PgEnum<["synced", "pending", "failed", "unknown"]>;
42
42
  export declare const fluxSecretsAuditActionEnum: import("drizzle-orm/pg-core").PgEnum<["created", "rotated", "revoked", "synced", "sync_failed"]>;
43
+ /**
44
+ * Milestone events that can trigger a per-user Slack DM. Owners on a ticket
45
+ * (account manager, account executive, strategist, fulfillment owner) receive
46
+ * these by default; non-owner subscribers must opt in per event type via
47
+ * `flux_users.notificationPreferences.milestones.subscriberOptIn`.
48
+ */
49
+ export declare const MILESTONE_EVENT_TYPES: readonly ["ticket_created", "creative_needed", "creative_approved", "ready_to_traffic", "campaign_live", "campaign_completed", "campaign_paused", "campaign_cancelled", "change_required", "sem_live", "sem_failed"];
50
+ export type MilestoneEventType = (typeof MILESTONE_EVENT_TYPES)[number];
51
+ export interface MilestonePreferences {
52
+ /** Owner default behavior: "all" (every event), "lifecycle_only" (live/completed/paused/cancelled), or "none". Defaults to "all". */
53
+ ownerDefaults?: "all" | "lifecycle_only" | "none";
54
+ /** Event types a non-owner subscriber wants DMs for. Defaults to []. */
55
+ subscriberOptIn?: MilestoneEventType[];
56
+ /** Project IDs the user has muted. */
57
+ mutedProjectIds?: string[];
58
+ /** ISO timestamp until which all milestone DMs are suppressed. */
59
+ mutedUntil?: string;
60
+ }
43
61
  /**
44
62
  * Flux user profiles - extends Clerk user identity with Flux-specific data.
45
63
  *
@@ -315,6 +333,7 @@ export declare const fluxUsers: import("drizzle-orm/pg-core").PgTableWithColumns
315
333
  sentinelSeverityThreshold?: "all" | "notable" | "urgent" | "crisis";
316
334
  sentinelDigestFrequency?: "daily" | "weekly" | "none";
317
335
  sentinelSlackDMs?: boolean;
336
+ milestones?: MilestonePreferences;
318
337
  };
319
338
  driverParam: unknown;
320
339
  notNull: false;
@@ -333,6 +352,7 @@ export declare const fluxUsers: import("drizzle-orm/pg-core").PgTableWithColumns
333
352
  sentinelSeverityThreshold?: "all" | "notable" | "urgent" | "crisis";
334
353
  sentinelDigestFrequency?: "daily" | "weekly" | "none";
335
354
  sentinelSlackDMs?: boolean;
355
+ milestones?: MilestonePreferences;
336
356
  };
337
357
  }>;
338
358
  onboardingComplete: import("drizzle-orm/pg-core").PgColumn<{
@@ -2376,6 +2396,194 @@ export declare const fluxActivityItems: import("drizzle-orm/pg-core").PgTableWit
2376
2396
  };
2377
2397
  dialect: "pg";
2378
2398
  }>;
2399
+ /**
2400
+ * Idempotency ledger for milestone Slack DMs. The dispatcher inserts one row
2401
+ * per (user, source, event) before sending the DM; the unique index causes
2402
+ * `ON CONFLICT DO NOTHING` to no-op on retries / re-syncs / webhook replays.
2403
+ *
2404
+ * Source rows:
2405
+ * sourceType = "fulfillment_ticket" → sourceId = flux_fulfillment_tickets.id
2406
+ * sourceType = "sem_campaign" → sourceId = flux_sem_campaigns.id
2407
+ *
2408
+ * `slackTs` captures the Slack message timestamp so future code can thread
2409
+ * follow-up updates (e.g. edit the "campaign live" message when it completes).
2410
+ */
2411
+ export declare const fluxMilestoneNotifications: import("drizzle-orm/pg-core").PgTableWithColumns<{
2412
+ name: "flux_milestone_notifications";
2413
+ schema: undefined;
2414
+ columns: {
2415
+ id: import("drizzle-orm/pg-core").PgColumn<{
2416
+ name: "id";
2417
+ tableName: "flux_milestone_notifications";
2418
+ dataType: "string";
2419
+ columnType: "PgVarchar";
2420
+ data: string;
2421
+ driverParam: string;
2422
+ notNull: true;
2423
+ hasDefault: true;
2424
+ isPrimaryKey: true;
2425
+ isAutoincrement: false;
2426
+ hasRuntimeDefault: false;
2427
+ enumValues: [string, ...string[]];
2428
+ baseColumn: never;
2429
+ identity: undefined;
2430
+ generated: undefined;
2431
+ }, {}, {
2432
+ length: number | undefined;
2433
+ }>;
2434
+ userId: import("drizzle-orm/pg-core").PgColumn<{
2435
+ name: "user_id";
2436
+ tableName: "flux_milestone_notifications";
2437
+ dataType: "string";
2438
+ columnType: "PgVarchar";
2439
+ data: string;
2440
+ driverParam: string;
2441
+ notNull: true;
2442
+ hasDefault: false;
2443
+ isPrimaryKey: false;
2444
+ isAutoincrement: false;
2445
+ hasRuntimeDefault: false;
2446
+ enumValues: [string, ...string[]];
2447
+ baseColumn: never;
2448
+ identity: undefined;
2449
+ generated: undefined;
2450
+ }, {}, {
2451
+ length: number | undefined;
2452
+ }>;
2453
+ sourceType: import("drizzle-orm/pg-core").PgColumn<{
2454
+ name: "source_type";
2455
+ tableName: "flux_milestone_notifications";
2456
+ dataType: "string";
2457
+ columnType: "PgVarchar";
2458
+ data: string;
2459
+ driverParam: string;
2460
+ notNull: true;
2461
+ hasDefault: false;
2462
+ isPrimaryKey: false;
2463
+ isAutoincrement: false;
2464
+ hasRuntimeDefault: false;
2465
+ enumValues: [string, ...string[]];
2466
+ baseColumn: never;
2467
+ identity: undefined;
2468
+ generated: undefined;
2469
+ }, {}, {
2470
+ length: number | undefined;
2471
+ }>;
2472
+ sourceId: import("drizzle-orm/pg-core").PgColumn<{
2473
+ name: "source_id";
2474
+ tableName: "flux_milestone_notifications";
2475
+ dataType: "string";
2476
+ columnType: "PgVarchar";
2477
+ data: string;
2478
+ driverParam: string;
2479
+ notNull: true;
2480
+ hasDefault: false;
2481
+ isPrimaryKey: false;
2482
+ isAutoincrement: false;
2483
+ hasRuntimeDefault: false;
2484
+ enumValues: [string, ...string[]];
2485
+ baseColumn: never;
2486
+ identity: undefined;
2487
+ generated: undefined;
2488
+ }, {}, {
2489
+ length: number | undefined;
2490
+ }>;
2491
+ eventType: import("drizzle-orm/pg-core").PgColumn<{
2492
+ name: "event_type";
2493
+ tableName: "flux_milestone_notifications";
2494
+ dataType: "string";
2495
+ columnType: "PgVarchar";
2496
+ data: string;
2497
+ driverParam: string;
2498
+ notNull: true;
2499
+ hasDefault: false;
2500
+ isPrimaryKey: false;
2501
+ isAutoincrement: false;
2502
+ hasRuntimeDefault: false;
2503
+ enumValues: [string, ...string[]];
2504
+ baseColumn: never;
2505
+ identity: undefined;
2506
+ generated: undefined;
2507
+ }, {}, {
2508
+ length: number | undefined;
2509
+ }>;
2510
+ projectId: import("drizzle-orm/pg-core").PgColumn<{
2511
+ name: "project_id";
2512
+ tableName: "flux_milestone_notifications";
2513
+ dataType: "string";
2514
+ columnType: "PgVarchar";
2515
+ data: string;
2516
+ driverParam: string;
2517
+ notNull: false;
2518
+ hasDefault: false;
2519
+ isPrimaryKey: false;
2520
+ isAutoincrement: false;
2521
+ hasRuntimeDefault: false;
2522
+ enumValues: [string, ...string[]];
2523
+ baseColumn: never;
2524
+ identity: undefined;
2525
+ generated: undefined;
2526
+ }, {}, {
2527
+ length: number | undefined;
2528
+ }>;
2529
+ deliveredAt: import("drizzle-orm/pg-core").PgColumn<{
2530
+ name: "delivered_at";
2531
+ tableName: "flux_milestone_notifications";
2532
+ dataType: "date";
2533
+ columnType: "PgTimestamp";
2534
+ data: Date;
2535
+ driverParam: string;
2536
+ notNull: true;
2537
+ hasDefault: true;
2538
+ isPrimaryKey: false;
2539
+ isAutoincrement: false;
2540
+ hasRuntimeDefault: false;
2541
+ enumValues: undefined;
2542
+ baseColumn: never;
2543
+ identity: undefined;
2544
+ generated: undefined;
2545
+ }, {}, {}>;
2546
+ slackTs: import("drizzle-orm/pg-core").PgColumn<{
2547
+ name: "slack_ts";
2548
+ tableName: "flux_milestone_notifications";
2549
+ dataType: "string";
2550
+ columnType: "PgVarchar";
2551
+ data: string;
2552
+ driverParam: string;
2553
+ notNull: false;
2554
+ hasDefault: false;
2555
+ isPrimaryKey: false;
2556
+ isAutoincrement: false;
2557
+ hasRuntimeDefault: false;
2558
+ enumValues: [string, ...string[]];
2559
+ baseColumn: never;
2560
+ identity: undefined;
2561
+ generated: undefined;
2562
+ }, {}, {
2563
+ length: number | undefined;
2564
+ }>;
2565
+ metadata: import("drizzle-orm/pg-core").PgColumn<{
2566
+ name: "metadata";
2567
+ tableName: "flux_milestone_notifications";
2568
+ dataType: "json";
2569
+ columnType: "PgJsonb";
2570
+ data: Record<string, unknown>;
2571
+ driverParam: unknown;
2572
+ notNull: false;
2573
+ hasDefault: true;
2574
+ isPrimaryKey: false;
2575
+ isAutoincrement: false;
2576
+ hasRuntimeDefault: false;
2577
+ enumValues: undefined;
2578
+ baseColumn: never;
2579
+ identity: undefined;
2580
+ generated: undefined;
2581
+ }, {}, {
2582
+ $type: Record<string, unknown>;
2583
+ }>;
2584
+ };
2585
+ dialect: "pg";
2586
+ }>;
2379
2587
  export declare const fluxAlertRules: import("drizzle-orm/pg-core").PgTableWithColumns<{
2380
2588
  name: "flux_alert_rules";
2381
2589
  schema: undefined;
@@ -5411,6 +5619,184 @@ export declare const fluxServiceUsageEvents: import("drizzle-orm/pg-core").PgTab
5411
5619
  };
5412
5620
  dialect: "pg";
5413
5621
  }>;
5622
+ /**
5623
+ * flux_search_cache — deterministic-key cache for paid search APIs.
5624
+ *
5625
+ * Phase 1 of the search-stack-cost optimization initiative. Wraps the
5626
+ * Exa, GNews, Firecrawl, and DataForSEO clients in fn-flux + fn-v2 so
5627
+ * the same query (same options, same lookback window) doesn't hit the
5628
+ * upstream API multiple times within its TTL.
5629
+ *
5630
+ * Key shape: `{provider}:{operation}:{sha256-of-options-bag}`. Payload
5631
+ * is the verbatim provider response array. `expiresAt` controls TTL
5632
+ * eviction; `hits` is bumped on each cache hit so we can rank
5633
+ * highest-savings keys.
5634
+ *
5635
+ * Cache is bypassed when the caller passes an `AbortSignal` (assistant
5636
+ * tool calls always want fresh data).
5637
+ */
5638
+ export declare const fluxSearchCache: import("drizzle-orm/pg-core").PgTableWithColumns<{
5639
+ name: "flux_search_cache";
5640
+ schema: undefined;
5641
+ columns: {
5642
+ cacheKey: import("drizzle-orm/pg-core").PgColumn<{
5643
+ name: "cache_key";
5644
+ tableName: "flux_search_cache";
5645
+ dataType: "string";
5646
+ columnType: "PgText";
5647
+ data: string;
5648
+ driverParam: string;
5649
+ notNull: true;
5650
+ hasDefault: false;
5651
+ isPrimaryKey: true;
5652
+ isAutoincrement: false;
5653
+ hasRuntimeDefault: false;
5654
+ enumValues: [string, ...string[]];
5655
+ baseColumn: never;
5656
+ identity: undefined;
5657
+ generated: undefined;
5658
+ }, {}, {}>;
5659
+ providerKey: import("drizzle-orm/pg-core").PgColumn<{
5660
+ name: "provider_key";
5661
+ tableName: "flux_search_cache";
5662
+ dataType: "string";
5663
+ columnType: "PgText";
5664
+ data: string;
5665
+ driverParam: string;
5666
+ notNull: true;
5667
+ hasDefault: false;
5668
+ isPrimaryKey: false;
5669
+ isAutoincrement: false;
5670
+ hasRuntimeDefault: false;
5671
+ enumValues: [string, ...string[]];
5672
+ baseColumn: never;
5673
+ identity: undefined;
5674
+ generated: undefined;
5675
+ }, {}, {}>;
5676
+ operationKey: import("drizzle-orm/pg-core").PgColumn<{
5677
+ name: "operation_key";
5678
+ tableName: "flux_search_cache";
5679
+ dataType: "string";
5680
+ columnType: "PgText";
5681
+ data: string;
5682
+ driverParam: string;
5683
+ notNull: true;
5684
+ hasDefault: false;
5685
+ isPrimaryKey: false;
5686
+ isAutoincrement: false;
5687
+ hasRuntimeDefault: false;
5688
+ enumValues: [string, ...string[]];
5689
+ baseColumn: never;
5690
+ identity: undefined;
5691
+ generated: undefined;
5692
+ }, {}, {}>;
5693
+ payload: import("drizzle-orm/pg-core").PgColumn<{
5694
+ name: "payload";
5695
+ tableName: "flux_search_cache";
5696
+ dataType: "json";
5697
+ columnType: "PgJsonb";
5698
+ data: unknown;
5699
+ driverParam: unknown;
5700
+ notNull: true;
5701
+ hasDefault: false;
5702
+ isPrimaryKey: false;
5703
+ isAutoincrement: false;
5704
+ hasRuntimeDefault: false;
5705
+ enumValues: undefined;
5706
+ baseColumn: never;
5707
+ identity: undefined;
5708
+ generated: undefined;
5709
+ }, {}, {}>;
5710
+ queryFingerprint: import("drizzle-orm/pg-core").PgColumn<{
5711
+ name: "query_fingerprint";
5712
+ tableName: "flux_search_cache";
5713
+ dataType: "json";
5714
+ columnType: "PgJsonb";
5715
+ data: Record<string, unknown> | null;
5716
+ driverParam: unknown;
5717
+ notNull: false;
5718
+ hasDefault: false;
5719
+ isPrimaryKey: false;
5720
+ isAutoincrement: false;
5721
+ hasRuntimeDefault: false;
5722
+ enumValues: undefined;
5723
+ baseColumn: never;
5724
+ identity: undefined;
5725
+ generated: undefined;
5726
+ }, {}, {
5727
+ $type: Record<string, unknown> | null;
5728
+ }>;
5729
+ expiresAt: import("drizzle-orm/pg-core").PgColumn<{
5730
+ name: "expires_at";
5731
+ tableName: "flux_search_cache";
5732
+ dataType: "date";
5733
+ columnType: "PgTimestamp";
5734
+ data: Date;
5735
+ driverParam: string;
5736
+ notNull: true;
5737
+ hasDefault: false;
5738
+ isPrimaryKey: false;
5739
+ isAutoincrement: false;
5740
+ hasRuntimeDefault: false;
5741
+ enumValues: undefined;
5742
+ baseColumn: never;
5743
+ identity: undefined;
5744
+ generated: undefined;
5745
+ }, {}, {}>;
5746
+ hits: import("drizzle-orm/pg-core").PgColumn<{
5747
+ name: "hits";
5748
+ tableName: "flux_search_cache";
5749
+ dataType: "number";
5750
+ columnType: "PgInteger";
5751
+ data: number;
5752
+ driverParam: string | number;
5753
+ notNull: true;
5754
+ hasDefault: true;
5755
+ isPrimaryKey: false;
5756
+ isAutoincrement: false;
5757
+ hasRuntimeDefault: false;
5758
+ enumValues: undefined;
5759
+ baseColumn: never;
5760
+ identity: undefined;
5761
+ generated: undefined;
5762
+ }, {}, {}>;
5763
+ lastHitAt: import("drizzle-orm/pg-core").PgColumn<{
5764
+ name: "last_hit_at";
5765
+ tableName: "flux_search_cache";
5766
+ dataType: "date";
5767
+ columnType: "PgTimestamp";
5768
+ data: Date;
5769
+ driverParam: string;
5770
+ notNull: false;
5771
+ hasDefault: false;
5772
+ isPrimaryKey: false;
5773
+ isAutoincrement: false;
5774
+ hasRuntimeDefault: false;
5775
+ enumValues: undefined;
5776
+ baseColumn: never;
5777
+ identity: undefined;
5778
+ generated: undefined;
5779
+ }, {}, {}>;
5780
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
5781
+ name: "created_at";
5782
+ tableName: "flux_search_cache";
5783
+ dataType: "date";
5784
+ columnType: "PgTimestamp";
5785
+ data: Date;
5786
+ driverParam: string;
5787
+ notNull: true;
5788
+ hasDefault: true;
5789
+ isPrimaryKey: false;
5790
+ isAutoincrement: false;
5791
+ hasRuntimeDefault: false;
5792
+ enumValues: undefined;
5793
+ baseColumn: never;
5794
+ identity: undefined;
5795
+ generated: undefined;
5796
+ }, {}, {}>;
5797
+ };
5798
+ dialect: "pg";
5799
+ }>;
5414
5800
  export declare const fluxServiceBudgetAlerts: import("drizzle-orm/pg-core").PgTableWithColumns<{
5415
5801
  name: "flux_service_budget_alerts";
5416
5802
  schema: undefined;
@@ -14402,7 +14788,7 @@ export declare const fluxFulfillmentTickets: import("drizzle-orm/pg-core").PgTab
14402
14788
  tableName: "flux_fulfillment_tickets";
14403
14789
  dataType: "string";
14404
14790
  columnType: "PgEnumColumn";
14405
- data: "paused" | "pending_form" | "submitted" | "pending_creative" | "pending_fulfillment" | "ready" | "running" | "completed" | "cancelled" | "change_required" | "billing_change_required";
14791
+ data: "paused" | "change_required" | "pending_form" | "submitted" | "pending_creative" | "pending_fulfillment" | "ready" | "running" | "completed" | "cancelled" | "billing_change_required";
14406
14792
  driverParam: string;
14407
14793
  notNull: true;
14408
14794
  hasDefault: true;
@@ -16514,7 +16900,7 @@ export declare const fluxFulfillmentTaskTemplates: import("drizzle-orm/pg-core")
16514
16900
  tableName: "flux_fulfillment_task_templates";
16515
16901
  dataType: "string";
16516
16902
  columnType: "PgEnumColumn";
16517
- data: "paused" | "pending_form" | "submitted" | "pending_creative" | "pending_fulfillment" | "ready" | "running" | "completed" | "cancelled" | "change_required" | "billing_change_required";
16903
+ data: "paused" | "change_required" | "pending_form" | "submitted" | "pending_creative" | "pending_fulfillment" | "ready" | "running" | "completed" | "cancelled" | "billing_change_required";
16518
16904
  driverParam: string;
16519
16905
  notNull: true;
16520
16906
  hasDefault: false;
@@ -18222,6 +18608,8 @@ export type FluxEmailThread = typeof fluxEmailThreads.$inferSelect;
18222
18608
  export type NewFluxEmailThread = typeof fluxEmailThreads.$inferInsert;
18223
18609
  export type FluxActivityItem = typeof fluxActivityItems.$inferSelect;
18224
18610
  export type NewFluxActivityItem = typeof fluxActivityItems.$inferInsert;
18611
+ export type FluxMilestoneNotification = typeof fluxMilestoneNotifications.$inferSelect;
18612
+ export type NewFluxMilestoneNotification = typeof fluxMilestoneNotifications.$inferInsert;
18225
18613
  export type FluxAlertRule = typeof fluxAlertRules.$inferSelect;
18226
18614
  export type NewFluxAlertRule = typeof fluxAlertRules.$inferInsert;
18227
18615
  export type FluxAlert = typeof fluxAlerts.$inferSelect;
@@ -18248,6 +18636,8 @@ export type FluxSecretsProvider = typeof fluxSecretsProviders.$inferSelect;
18248
18636
  export type NewFluxSecretsProvider = typeof fluxSecretsProviders.$inferInsert;
18249
18637
  export type FluxServiceUsageEvent = typeof fluxServiceUsageEvents.$inferSelect;
18250
18638
  export type NewFluxServiceUsageEvent = typeof fluxServiceUsageEvents.$inferInsert;
18639
+ export type FluxSearchCache = typeof fluxSearchCache.$inferSelect;
18640
+ export type NewFluxSearchCache = typeof fluxSearchCache.$inferInsert;
18251
18641
  export type FluxServiceBudgetAlert = typeof fluxServiceBudgetAlerts.$inferSelect;
18252
18642
  export type NewFluxServiceBudgetAlert = typeof fluxServiceBudgetAlerts.$inferInsert;
18253
18643
  export type FluxServiceCostReconciliation = typeof fluxServiceCostReconciliations.$inferSelect;