@odla-ai/chapter 0.42.4 → 0.43.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.
package/dist/index.d.cts CHANGED
@@ -963,7 +963,8 @@ declare function createChapterIntegration(chapter: Chapter, options?: ChapterInt
963
963
  * "table"` adds the `admins` allowlist (hub/BNF); `superAdmins` adds the
964
964
  * read-only super-admin tier (default on for the `"claim"` ladder). A `"claim"`
965
965
  * chapter therefore emits the reference namespace set — `applications`,
966
- * `groups`, `meetings`, `emailLog`, `superAdmins` — with no `admins` table. */
966
+ * `groups`, `meetings`, `emailLog`, `stripeEventReceipts`, `superAdmins` — with
967
+ * no `admins` table. */
967
968
  declare function chapterDb(mode: ChapterMode, auth: ResolvedAuth, includeNetworkNotes?: boolean, application?: ResolvedApplication, includeSignupControl?: boolean, includeMemberContent?: boolean, includeBuilderLibrary?: boolean, includeLeaderAdmissions?: boolean): {
968
969
  schema: DbSchema;
969
970
  rules: DbRules;
@@ -1531,8 +1532,9 @@ declare function paymentsReady(group: PaymentsGroup, hasSecretKey: boolean): boo
1531
1532
  /** The Stripe idempotency key for creating an application's subscription — one
1532
1533
  * per application, so a client retry can't orphan a second subscription. */
1533
1534
  declare function subscriptionIdempotencyKey(applicationId: string): string;
1534
- /** The db mutationId for a webhook-driven write — exactly-once per Stripe event,
1535
- * so replays are deduped at the db layer. */
1535
+ /** The db mutationId for a webhook-driven application write. A separate signed
1536
+ * event receipt fences replays and event-id collisions across every write in
1537
+ * the route; this id keeps the application mutation itself idempotent. */
1536
1538
  declare function webhookMutationId(eventId: string): string;
1537
1539
  /** A raw Stripe event, as far as normalization cares. */
1538
1540
  interface StripeEvent {
@@ -1578,6 +1580,7 @@ type WebhookEvent = ({
1578
1580
  environment?: string;
1579
1581
  dataEnvironment?: string;
1580
1582
  runtime?: string;
1583
+ chapterId?: string;
1581
1584
  };
1582
1585
  /** Resolve the application reference on a Stripe object: `applicationId` from
1583
1586
  * metadata (direct, then subscription_details, then nested
@@ -1589,6 +1592,7 @@ declare function findApplicationRef(obj: Record<string, unknown>): {
1589
1592
  environment?: string;
1590
1593
  dataEnvironment?: string;
1591
1594
  runtime?: string;
1595
+ chapterId?: string;
1592
1596
  };
1593
1597
  /** Normalize a verified Stripe event into a {@link WebhookEvent}. `invoice.paid`
1594
1598
  * splits into first_payment vs renewal by `billing_reason`; refunds and
package/dist/index.d.ts CHANGED
@@ -963,7 +963,8 @@ declare function createChapterIntegration(chapter: Chapter, options?: ChapterInt
963
963
  * "table"` adds the `admins` allowlist (hub/BNF); `superAdmins` adds the
964
964
  * read-only super-admin tier (default on for the `"claim"` ladder). A `"claim"`
965
965
  * chapter therefore emits the reference namespace set — `applications`,
966
- * `groups`, `meetings`, `emailLog`, `superAdmins` — with no `admins` table. */
966
+ * `groups`, `meetings`, `emailLog`, `stripeEventReceipts`, `superAdmins` — with
967
+ * no `admins` table. */
967
968
  declare function chapterDb(mode: ChapterMode, auth: ResolvedAuth, includeNetworkNotes?: boolean, application?: ResolvedApplication, includeSignupControl?: boolean, includeMemberContent?: boolean, includeBuilderLibrary?: boolean, includeLeaderAdmissions?: boolean): {
968
969
  schema: DbSchema;
969
970
  rules: DbRules;
@@ -1531,8 +1532,9 @@ declare function paymentsReady(group: PaymentsGroup, hasSecretKey: boolean): boo
1531
1532
  /** The Stripe idempotency key for creating an application's subscription — one
1532
1533
  * per application, so a client retry can't orphan a second subscription. */
1533
1534
  declare function subscriptionIdempotencyKey(applicationId: string): string;
1534
- /** The db mutationId for a webhook-driven write — exactly-once per Stripe event,
1535
- * so replays are deduped at the db layer. */
1535
+ /** The db mutationId for a webhook-driven application write. A separate signed
1536
+ * event receipt fences replays and event-id collisions across every write in
1537
+ * the route; this id keeps the application mutation itself idempotent. */
1536
1538
  declare function webhookMutationId(eventId: string): string;
1537
1539
  /** A raw Stripe event, as far as normalization cares. */
1538
1540
  interface StripeEvent {
@@ -1578,6 +1580,7 @@ type WebhookEvent = ({
1578
1580
  environment?: string;
1579
1581
  dataEnvironment?: string;
1580
1582
  runtime?: string;
1583
+ chapterId?: string;
1581
1584
  };
1582
1585
  /** Resolve the application reference on a Stripe object: `applicationId` from
1583
1586
  * metadata (direct, then subscription_details, then nested
@@ -1589,6 +1592,7 @@ declare function findApplicationRef(obj: Record<string, unknown>): {
1589
1592
  environment?: string;
1590
1593
  dataEnvironment?: string;
1591
1594
  runtime?: string;
1595
+ chapterId?: string;
1592
1596
  };
1593
1597
  /** Normalize a verified Stripe event into a {@link WebhookEvent}. `invoice.paid`
1594
1598
  * splits into first_payment vs renewal by `billing_reason`; refunds and
package/dist/index.js CHANGED
@@ -442,8 +442,32 @@ var giftRedemptionAttemptsEntity = { attrs: {
442
442
  updatedAt: attr3("number")
443
443
  } };
444
444
 
445
+ // src/schema-stripe.ts
446
+ var attr4 = (type, flags = {}) => ({
447
+ type,
448
+ unique: flags.unique ?? false,
449
+ indexed: flags.indexed ?? false,
450
+ optional: flags.optional ?? false
451
+ });
452
+ var stripeEventReceiptsEntity = {
453
+ attrs: {
454
+ id: attr4("string", { unique: true, indexed: true }),
455
+ eventId: attr4("string", { unique: true, indexed: true }),
456
+ digest: attr4("string", { indexed: true }),
457
+ disposition: attr4("string", { indexed: true }),
458
+ kind: attr4("string", { indexed: true }),
459
+ matched: attr4("boolean", { indexed: true }),
460
+ appId: attr4("string", { indexed: true, optional: true }),
461
+ environment: attr4("string", { indexed: true, optional: true }),
462
+ dataEnvironment: attr4("string", { indexed: true, optional: true }),
463
+ runtime: attr4("string", { indexed: true, optional: true }),
464
+ chapterId: attr4("string", { indexed: true, optional: true }),
465
+ receivedAt: attr4("number", { indexed: true })
466
+ }
467
+ };
468
+
445
469
  // src/schema.ts
446
- function attr4(type, flags = {}) {
470
+ function attr5(type, flags = {}) {
447
471
  return {
448
472
  type,
449
473
  unique: flags.unique ?? false,
@@ -451,167 +475,167 @@ function attr4(type, flags = {}) {
451
475
  optional: flags.optional ?? false
452
476
  };
453
477
  }
454
- var id3 = () => attr4("string", { unique: true, indexed: true });
478
+ var id3 = () => attr5("string", { unique: true, indexed: true });
455
479
  var admins = {
456
480
  attrs: {
457
481
  id: id3(),
458
- email: attr4("string", { unique: true, indexed: true }),
459
- name: attr4("string", { optional: true }),
460
- note: attr4("string", { optional: true })
482
+ email: attr5("string", { unique: true, indexed: true }),
483
+ name: attr5("string", { optional: true }),
484
+ note: attr5("string", { optional: true })
461
485
  }
462
486
  };
463
487
  var superAdmins = {
464
488
  attrs: {
465
489
  id: id3(),
466
- email: attr4("string", { unique: true, indexed: true }),
467
- note: attr4("string", { optional: true }),
468
- createdAt: attr4("number", { indexed: true })
490
+ email: attr5("string", { unique: true, indexed: true }),
491
+ note: attr5("string", { optional: true }),
492
+ createdAt: attr5("number", { indexed: true })
469
493
  }
470
494
  };
471
495
  var networkNotes = {
472
496
  attrs: {
473
497
  id: id3(),
474
- recordKey: attr4("string", { indexed: true }),
475
- targetId: attr4("string", { indexed: true }),
476
- recordType: attr4("string", { indexed: true }),
477
- recordId: attr4("string", { indexed: true }),
478
- body: attr4("string"),
479
- authorId: attr4("string", { indexed: true }),
480
- authorEmail: attr4("string", { optional: true }),
481
- createdAt: attr4("number", { indexed: true })
498
+ recordKey: attr5("string", { indexed: true }),
499
+ targetId: attr5("string", { indexed: true }),
500
+ recordType: attr5("string", { indexed: true }),
501
+ recordId: attr5("string", { indexed: true }),
502
+ body: attr5("string"),
503
+ authorId: attr5("string", { indexed: true }),
504
+ authorEmail: attr5("string", { optional: true }),
505
+ createdAt: attr5("number", { indexed: true })
482
506
  }
483
507
  };
484
508
  var signupControls = {
485
509
  attrs: {
486
510
  id: id3(),
487
- sourceId: attr4("string", { indexed: true }),
488
- targetId: attr4("string", { indexed: true }),
489
- environment: attr4("string", { indexed: true }),
490
- revision: attr4("number", { indexed: true }),
491
- digest: attr4("string", { indexed: true }),
492
- document: attr4("json"),
493
- active: attr4("boolean", { indexed: true }),
494
- receivedAt: attr4("number", { indexed: true })
511
+ sourceId: attr5("string", { indexed: true }),
512
+ targetId: attr5("string", { indexed: true }),
513
+ environment: attr5("string", { indexed: true }),
514
+ revision: attr5("number", { indexed: true }),
515
+ digest: attr5("string", { indexed: true }),
516
+ document: attr5("json"),
517
+ active: attr5("boolean", { indexed: true }),
518
+ receivedAt: attr5("number", { indexed: true })
495
519
  }
496
520
  };
497
521
  var memberContentControls = {
498
522
  attrs: {
499
523
  id: id3(),
500
- sourceId: attr4("string", { indexed: true }),
501
- targetId: attr4("string", { indexed: true }),
502
- environment: attr4("string", { indexed: true }),
503
- revision: attr4("number", { indexed: true }),
504
- digest: attr4("string", { indexed: true }),
505
- document: attr4("json"),
506
- active: attr4("boolean", { indexed: true }),
507
- receivedAt: attr4("number", { indexed: true })
524
+ sourceId: attr5("string", { indexed: true }),
525
+ targetId: attr5("string", { indexed: true }),
526
+ environment: attr5("string", { indexed: true }),
527
+ revision: attr5("number", { indexed: true }),
528
+ digest: attr5("string", { indexed: true }),
529
+ document: attr5("json"),
530
+ active: attr5("boolean", { indexed: true }),
531
+ receivedAt: attr5("number", { indexed: true })
508
532
  }
509
533
  };
510
534
  var memberContentLocal = {
511
535
  attrs: {
512
536
  id: id3(),
513
- chapterId: attr4("string", { indexed: true }),
514
- environment: attr4("string", { indexed: true }),
515
- revision: attr4("number", { indexed: true }),
516
- document: attr4("json"),
517
- updatedAt: attr4("number", { indexed: true }),
518
- updatedBy: attr4("string", { optional: true })
537
+ chapterId: attr5("string", { indexed: true }),
538
+ environment: attr5("string", { indexed: true }),
539
+ revision: attr5("number", { indexed: true }),
540
+ document: attr5("json"),
541
+ updatedAt: attr5("number", { indexed: true }),
542
+ updatedBy: attr5("string", { optional: true })
519
543
  }
520
544
  };
521
545
  var builderLibraryControls = {
522
546
  attrs: {
523
547
  id: id3(),
524
- sourceId: attr4("string", { indexed: true }),
525
- targetId: attr4("string", { indexed: true }),
526
- environment: attr4("string", { indexed: true }),
527
- revision: attr4("number", { indexed: true }),
528
- digest: attr4("string", { indexed: true }),
529
- document: attr4("json"),
530
- active: attr4("boolean", { indexed: true }),
531
- receivedAt: attr4("number", { indexed: true })
548
+ sourceId: attr5("string", { indexed: true }),
549
+ targetId: attr5("string", { indexed: true }),
550
+ environment: attr5("string", { indexed: true }),
551
+ revision: attr5("number", { indexed: true }),
552
+ digest: attr5("string", { indexed: true }),
553
+ document: attr5("json"),
554
+ active: attr5("boolean", { indexed: true }),
555
+ receivedAt: attr5("number", { indexed: true })
532
556
  }
533
557
  };
534
558
  var builderLibraryLocal = {
535
559
  attrs: {
536
560
  id: id3(),
537
- appId: attr4("string", { indexed: true }),
538
- environment: attr4("string", { indexed: true }),
539
- revision: attr4("number", { indexed: true }),
540
- document: attr4("json"),
541
- updatedAt: attr4("number", { indexed: true }),
542
- updatedBy: attr4("string", { optional: true })
561
+ appId: attr5("string", { indexed: true }),
562
+ environment: attr5("string", { indexed: true }),
563
+ revision: attr5("number", { indexed: true }),
564
+ document: attr5("json"),
565
+ updatedAt: attr5("number", { indexed: true }),
566
+ updatedBy: attr5("string", { optional: true })
543
567
  }
544
568
  };
545
569
  var groups = {
546
570
  attrs: {
547
571
  id: id3(),
548
- name: attr4("string"),
549
- standardPriceCents: attr4("number"),
550
- foundingDiscountCents: attr4("number"),
551
- stripePriceId: attr4("string", { optional: true }),
552
- stripePublishableKey: attr4("string", { optional: true }),
553
- notificationEmail: attr4("string"),
554
- replyTo: attr4("string"),
555
- debugEmail: attr4("string", { optional: true }),
556
- calendarLink: attr4("string", { optional: true }),
557
- disclaimerText: attr4("string"),
558
- refundPolicyText: attr4("string"),
559
- merchantDisclosureText: attr4("string", { optional: true }),
560
- trustCopy: attr4("string"),
561
- commitmentText: attr4("string", { optional: true }),
562
- normsText: attr4("string", { optional: true }),
563
- emailTemplates: attr4("json"),
564
- schedulingJson: attr4("json", { optional: true }),
565
- createdAt: attr4("number", { indexed: true })
572
+ name: attr5("string"),
573
+ standardPriceCents: attr5("number"),
574
+ foundingDiscountCents: attr5("number"),
575
+ stripePriceId: attr5("string", { optional: true }),
576
+ stripePublishableKey: attr5("string", { optional: true }),
577
+ notificationEmail: attr5("string"),
578
+ replyTo: attr5("string"),
579
+ debugEmail: attr5("string", { optional: true }),
580
+ calendarLink: attr5("string", { optional: true }),
581
+ disclaimerText: attr5("string"),
582
+ refundPolicyText: attr5("string"),
583
+ merchantDisclosureText: attr5("string", { optional: true }),
584
+ trustCopy: attr5("string"),
585
+ commitmentText: attr5("string", { optional: true }),
586
+ normsText: attr5("string", { optional: true }),
587
+ emailTemplates: attr5("json"),
588
+ schedulingJson: attr5("json", { optional: true }),
589
+ createdAt: attr5("number", { indexed: true })
566
590
  }
567
591
  };
568
592
  var tiers = {
569
593
  attrs: {
570
594
  id: id3(),
571
- groupId: attr4("string", { indexed: true }),
572
- name: attr4("string"),
573
- priceCents: attr4("number"),
574
- stripePriceId: attr4("string", { optional: true }),
575
- blurb: attr4("string", { optional: true }),
576
- sortOrder: attr4("number", { indexed: true }),
577
- active: attr4("boolean", { indexed: true }),
578
- createdAt: attr4("number", { indexed: true })
595
+ groupId: attr5("string", { indexed: true }),
596
+ name: attr5("string"),
597
+ priceCents: attr5("number"),
598
+ stripePriceId: attr5("string", { optional: true }),
599
+ blurb: attr5("string", { optional: true }),
600
+ sortOrder: attr5("number", { indexed: true }),
601
+ active: attr5("boolean", { indexed: true }),
602
+ createdAt: attr5("number", { indexed: true })
579
603
  }
580
604
  };
581
605
  var meetings = {
582
606
  attrs: {
583
607
  id: id3(),
584
- applicationId: attr4("string", { indexed: true }),
585
- groupId: attr4("string", { indexed: true }),
586
- startAt: attr4("number", { indexed: true }),
587
- endAt: attr4("number"),
588
- timezone: attr4("string"),
589
- status: attr4("string", { indexed: true }),
590
- googleEventId: attr4("string", { indexed: true, optional: true }),
591
- meetUrl: attr4("string", { optional: true }),
592
- htmlLink: attr4("string", { optional: true }),
593
- drift: attr4("string", { indexed: true, optional: true }),
594
- driftGoogleStartAt: attr4("number", { optional: true }),
595
- driftDetectedAt: attr4("number", { optional: true }),
596
- adoptedFromGoogleAt: attr4("number", { optional: true }),
597
- createdAt: attr4("number", { indexed: true })
608
+ applicationId: attr5("string", { indexed: true }),
609
+ groupId: attr5("string", { indexed: true }),
610
+ startAt: attr5("number", { indexed: true }),
611
+ endAt: attr5("number"),
612
+ timezone: attr5("string"),
613
+ status: attr5("string", { indexed: true }),
614
+ googleEventId: attr5("string", { indexed: true, optional: true }),
615
+ meetUrl: attr5("string", { optional: true }),
616
+ htmlLink: attr5("string", { optional: true }),
617
+ drift: attr5("string", { indexed: true, optional: true }),
618
+ driftGoogleStartAt: attr5("number", { optional: true }),
619
+ driftDetectedAt: attr5("number", { optional: true }),
620
+ adoptedFromGoogleAt: attr5("number", { optional: true }),
621
+ createdAt: attr5("number", { indexed: true })
598
622
  }
599
623
  };
600
624
  var emailLog = {
601
625
  attrs: {
602
626
  id: id3(),
603
- groupId: attr4("string", { indexed: true }),
604
- applicationId: attr4("string", { indexed: true, optional: true }),
605
- to: attr4("string", { indexed: true }),
606
- template: attr4("string", { indexed: true }),
607
- subject: attr4("string"),
608
- body: attr4("string", { optional: true }),
609
- transport: attr4("string"),
610
- messageId: attr4("string", { optional: true }),
611
- redirected: attr4("boolean", { optional: true }),
612
- dedupeKey: attr4("string", { indexed: true, optional: true }),
613
- error: attr4("string", { optional: true }),
614
- sentAt: attr4("number", { indexed: true })
627
+ groupId: attr5("string", { indexed: true }),
628
+ applicationId: attr5("string", { indexed: true, optional: true }),
629
+ to: attr5("string", { indexed: true }),
630
+ template: attr5("string", { indexed: true }),
631
+ subject: attr5("string"),
632
+ body: attr5("string", { optional: true }),
633
+ transport: attr5("string"),
634
+ messageId: attr5("string", { optional: true }),
635
+ redirected: attr5("boolean", { optional: true }),
636
+ dedupeKey: attr5("string", { indexed: true, optional: true }),
637
+ error: attr5("string", { optional: true }),
638
+ sentAt: attr5("number", { indexed: true })
615
639
  }
616
640
  };
617
641
  function chapterDb(mode, auth, includeNetworkNotes = false, application = resolveApplication(void 0), includeSignupControl = false, includeMemberContent = false, includeBuilderLibrary = false, includeLeaderAdmissions = false) {
@@ -622,6 +646,7 @@ function chapterDb(mode, auth, includeNetworkNotes = false, application = resolv
622
646
  entities.tiers = tiers;
623
647
  entities.meetings = meetings;
624
648
  entities.emailLog = emailLog;
649
+ entities.stripeEventReceipts = stripeEventReceiptsEntity;
625
650
  entities.admissionGrants = admissionGrantsEntity;
626
651
  entities.admissionGrantRevisions = admissionGrantRevisionsEntity;
627
652
  entities.giftPurchaseIntents = giftPurchaseIntentsEntity;
@@ -2821,6 +2846,7 @@ function findApplicationRef(obj) {
2821
2846
  const environment = candidates.map((metadata) => typeof metadata.odlaEnvironment === "string" ? metadata.odlaEnvironment : void 0).find(Boolean);
2822
2847
  const dataEnvironment = candidates.map((metadata) => typeof metadata.odlaDataEnvironment === "string" ? metadata.odlaDataEnvironment : void 0).find(Boolean);
2823
2848
  const runtime = candidates.map((metadata) => typeof metadata.odlaRuntime === "string" ? metadata.odlaRuntime : void 0).find(Boolean);
2849
+ const chapterId = candidates.map((metadata) => typeof metadata.chapterId === "string" ? metadata.chapterId : void 0).find(Boolean);
2824
2850
  const customerId = typeof obj.customer === "string" ? obj.customer : void 0;
2825
2851
  return {
2826
2852
  ...applicationId ? { applicationId } : {},
@@ -2828,7 +2854,8 @@ function findApplicationRef(obj) {
2828
2854
  ...appId ? { appId } : {},
2829
2855
  ...environment ? { environment } : {},
2830
2856
  ...dataEnvironment ? { dataEnvironment } : {},
2831
- ...runtime ? { runtime } : {}
2857
+ ...runtime ? { runtime } : {},
2858
+ ...chapterId ? { chapterId } : {}
2832
2859
  };
2833
2860
  }
2834
2861
  function findGiftRef(obj) {
@@ -2844,13 +2871,15 @@ function findGiftRef(obj) {
2844
2871
  const environment = pickIdentity("odlaEnvironment");
2845
2872
  const dataEnvironment = pickIdentity("odlaDataEnvironment");
2846
2873
  const runtime = pickIdentity("odlaRuntime");
2874
+ const chapterId = pickIdentity("chapterId");
2847
2875
  return {
2848
2876
  ...giftIntentId ? { giftIntentId } : {},
2849
2877
  providerObjectId: subscriptionId ?? String(obj.id ?? ""),
2850
2878
  ...appId ? { appId } : {},
2851
2879
  ...environment ? { environment } : {},
2852
2880
  ...dataEnvironment ? { dataEnvironment } : {},
2853
- ...runtime ? { runtime } : {}
2881
+ ...runtime ? { runtime } : {},
2882
+ ...chapterId ? { chapterId } : {}
2854
2883
  };
2855
2884
  }
2856
2885
  function normalizeWebhookEvent(event) {