@odla-ai/chapter 0.42.3 → 0.43.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/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;
@@ -2032,8 +2057,8 @@ function tierPayable(tier, group, hasSecretKey) {
2032
2057
  function byOrder(a, b) {
2033
2058
  return a.sortOrder - b.sortOrder || a.id.localeCompare(b.id);
2034
2059
  }
2035
- function resolveTiers(group, rows2 = []) {
2036
- const stored = rows2.filter((tier) => tier.active);
2060
+ function resolveTiers(group, rows3 = []) {
2061
+ const stored = rows3.filter((tier) => tier.active);
2037
2062
  if (stored.length) return [...stored].sort(byOrder);
2038
2063
  return [{
2039
2064
  id: "standard",
@@ -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) {
@@ -4066,15 +4095,15 @@ function rowToTier(row, groupId) {
4066
4095
  }
4067
4096
  async function loadTiers(db, group) {
4068
4097
  const groupId = String(group.id ?? "");
4069
- let rows2;
4098
+ let rows3;
4070
4099
  try {
4071
- rows2 = (await db.query({
4100
+ rows3 = (await db.query({
4072
4101
  tiers: { $: { where: { groupId }, order: { sortOrder: "asc" }, limit: 100 } }
4073
4102
  })).tiers;
4074
4103
  } catch {
4075
- rows2 = void 0;
4104
+ rows3 = void 0;
4076
4105
  }
4077
- const list = Array.isArray(rows2) ? rows2.map((row) => rowToTier(row, groupId)) : [];
4106
+ const list = Array.isArray(rows3) ? rows3.map((row) => rowToTier(row, groupId)) : [];
4078
4107
  return resolveTiers(group, list);
4079
4108
  }
4080
4109
  async function loadOfferableTiers(db, group, hasSecretKey) {
@@ -4774,6 +4803,448 @@ async function exportChapterPromotion(input) {
4774
4803
  ]
4775
4804
  };
4776
4805
  }
4806
+
4807
+ // src/member-system-authority.ts
4808
+ var rows2 = (group) => group.fields.map((id4) => ({ ...group, id: id4 }));
4809
+ var MEMBER_SYSTEM_AUTHORITY_MATRIX = [
4810
+ ...rows2({
4811
+ scope: "network",
4812
+ writer: "network_person",
4813
+ projections: ["bnf_admin", "chapter_admin", "member_self_service"],
4814
+ sensitivity: "pii",
4815
+ memberAccess: "edit",
4816
+ fields: [
4817
+ "person.legalName",
4818
+ "person.preferredName",
4819
+ "person.namePronunciation",
4820
+ "person.pronouns",
4821
+ "person.displayLegalName",
4822
+ "person.primaryEmail",
4823
+ "person.secondaryEmails",
4824
+ "person.phone",
4825
+ "person.linkedinUrl",
4826
+ "person.photo",
4827
+ "person.homeAddress",
4828
+ "person.fulfillmentFit",
4829
+ "person.fulfillmentSize"
4830
+ ]
4831
+ }),
4832
+ ...rows2({
4833
+ scope: "network",
4834
+ writer: "network_person",
4835
+ projections: ["bnf_admin", "chapter_admin", "member_self_service"],
4836
+ sensitivity: "ordinary",
4837
+ memberAccess: "edit",
4838
+ fields: [
4839
+ "person.title",
4840
+ "person.company",
4841
+ "person.companyObservedAt",
4842
+ "person.region",
4843
+ "person.whyText",
4844
+ "person.whyTokens",
4845
+ "person.skillsOffered",
4846
+ "person.openToRequests",
4847
+ "person.directoryPhotoConsent"
4848
+ ]
4849
+ }),
4850
+ ...rows2({
4851
+ scope: "network",
4852
+ writer: "network_person",
4853
+ projections: ["bnf_admin", "chapter_admin"],
4854
+ sensitivity: "restricted",
4855
+ memberAccess: "none",
4856
+ fields: [
4857
+ "person.linkedinMemberId",
4858
+ "person.identityClaims",
4859
+ "person.aliases",
4860
+ "person.mergeHistory",
4861
+ "person.introducedByPersonId",
4862
+ "person.introducedAt",
4863
+ "person.firstTouch",
4864
+ "person.globalSuppression",
4865
+ "person.deceasedAt",
4866
+ "person.archivedAt"
4867
+ ]
4868
+ }),
4869
+ ...rows2({
4870
+ scope: "network",
4871
+ writer: "network_person",
4872
+ projections: ["bnf_admin", "chapter_admin", "member_self_service"],
4873
+ sensitivity: "sensitive",
4874
+ memberAccess: "edit",
4875
+ fields: ["person.accreditationSelfCertification", "person.accreditationCategory", "person.accreditationExpiresAt"]
4876
+ }),
4877
+ ...rows2({
4878
+ scope: "network",
4879
+ writer: "network_person",
4880
+ projections: ["bnf_admin", "chapter_admin", "member_self_service"],
4881
+ sensitivity: "restricted",
4882
+ memberAccess: "read",
4883
+ fields: ["person.acknowledgements"]
4884
+ }),
4885
+ ...rows2({
4886
+ scope: "provider",
4887
+ writer: "clerk",
4888
+ projections: ["clerk_identity", "bnf_admin", "chapter_admin"],
4889
+ sensitivity: "restricted",
4890
+ memberAccess: "none",
4891
+ fields: ["identity.clerkUserIds", "identity.clerkEmailVerification"]
4892
+ }),
4893
+ ...rows2({
4894
+ scope: "chapter",
4895
+ writer: "chapter_journey",
4896
+ projections: ["chapter_admin", "chapter_crm", "bnf_admin"],
4897
+ sensitivity: "ordinary",
4898
+ memberAccess: "none",
4899
+ fields: [
4900
+ "journey.chapterId",
4901
+ "journey.stage",
4902
+ "journey.stageEnteredAt",
4903
+ "journey.stageHistory",
4904
+ "journey.ending",
4905
+ "journey.endingReason",
4906
+ "journey.source",
4907
+ "journey.entryChapterId",
4908
+ "journey.route",
4909
+ "journey.flags",
4910
+ "journey.applicationStartedAt",
4911
+ "journey.appliedAt",
4912
+ "journey.paidAt",
4913
+ "journey.callBookedAt",
4914
+ "journey.metAt",
4915
+ "journey.approvedAt",
4916
+ "journey.onboardedAt",
4917
+ "journey.firstLoginAt",
4918
+ "journey.firstDealAt"
4919
+ ]
4920
+ }),
4921
+ ...rows2({
4922
+ scope: "chapter",
4923
+ writer: "chapter_journey",
4924
+ projections: ["chapter_admin", "chapter_crm"],
4925
+ sensitivity: "sensitive",
4926
+ memberAccess: "none",
4927
+ fields: [
4928
+ "journey.relationshipOwnerId",
4929
+ "journey.lastContactAt",
4930
+ "journey.nextAction",
4931
+ "journey.owes",
4932
+ "journey.asks",
4933
+ "journey.preparation",
4934
+ "journey.notes"
4935
+ ]
4936
+ }),
4937
+ ...rows2({
4938
+ scope: "chapter",
4939
+ writer: "chapter_journey",
4940
+ projections: ["chapter_admin", "chapter_crm", "member_self_service"],
4941
+ sensitivity: "ordinary",
4942
+ memberAccess: "edit",
4943
+ fields: ["journey.dealFlowConsent", "journey.directoryConsent", "journey.emailConsent", "journey.smsConsent"]
4944
+ }),
4945
+ ...rows2({
4946
+ scope: "chapter",
4947
+ writer: "chapter_journey",
4948
+ projections: ["chapter_admin", "bnf_admin", "member_self_service"],
4949
+ sensitivity: "ordinary",
4950
+ memberAccess: "read",
4951
+ fields: ["journey.memberNumber"]
4952
+ }),
4953
+ ...rows2({
4954
+ scope: "network",
4955
+ writer: "network_membership",
4956
+ projections: ["bnf_admin", "chapter_admin", "member_self_service"],
4957
+ sensitivity: "ordinary",
4958
+ memberAccess: "read",
4959
+ fields: [
4960
+ "membership.chapterId",
4961
+ "membership.journeyId",
4962
+ "membership.termStartsAt",
4963
+ "membership.termEndsAt",
4964
+ "membership.tier",
4965
+ "membership.status",
4966
+ "membership.joinedAt",
4967
+ "membership.autoRenews",
4968
+ "membership.renewalAt",
4969
+ "membership.cancelsAt",
4970
+ "membership.graceEndsAt",
4971
+ "membership.foundingCohort",
4972
+ "membership.offeringPolicyVersion",
4973
+ "membership.discountPolicyVersion"
4974
+ ]
4975
+ }),
4976
+ ...rows2({
4977
+ scope: "network",
4978
+ writer: "network_commercial_projection",
4979
+ projections: ["bnf_admin", "chapter_admin"],
4980
+ sensitivity: "restricted",
4981
+ memberAccess: "none",
4982
+ fields: [
4983
+ "membership.stripeCustomerId",
4984
+ "membership.stripeSubscriptionId",
4985
+ "membership.stripePriceId",
4986
+ "membership.lastInvoiceId",
4987
+ "membership.paymentOutcome",
4988
+ "membership.refundOutcome"
4989
+ ]
4990
+ }),
4991
+ ...rows2({
4992
+ scope: "network",
4993
+ writer: "network_discount_policy",
4994
+ projections: ["bnf_admin", "chapter_admin", "stripe_billing"],
4995
+ sensitivity: "ordinary",
4996
+ memberAccess: "none",
4997
+ fields: [
4998
+ "discountPolicy.chapterId",
4999
+ "discountPolicy.version",
5000
+ "discountPolicy.eligibleOfferingIds",
5001
+ "discountPolicy.percentOff",
5002
+ "discountPolicy.amountOff",
5003
+ "discountPolicy.activatesOn",
5004
+ "discountPolicy.invoiceCount",
5005
+ "discountPolicy.expiresAt",
5006
+ "discountPolicy.stackingOrder",
5007
+ "discountPolicy.status"
5008
+ ]
5009
+ }),
5010
+ ...rows2({
5011
+ scope: "network",
5012
+ writer: "network_entitlement",
5013
+ projections: ["bnf_admin", "chapter_admin", "member_self_service", "stripe_billing"],
5014
+ sensitivity: "ordinary",
5015
+ memberAccess: "read",
5016
+ fields: [
5017
+ "entitlement.membershipId",
5018
+ "entitlement.kind",
5019
+ "entitlement.priceCents",
5020
+ "entitlement.currency",
5021
+ "entitlement.payerPersonId",
5022
+ "entitlement.purchasedAt",
5023
+ "entitlement.termEndsAt",
5024
+ "entitlement.renewsWithMembership",
5025
+ "entitlement.status"
5026
+ ]
5027
+ }),
5028
+ ...rows2({
5029
+ scope: "network",
5030
+ writer: "network_seat",
5031
+ projections: ["bnf_admin", "chapter_admin", "member_self_service"],
5032
+ sensitivity: "pii",
5033
+ memberAccess: "read",
5034
+ fields: [
5035
+ "seat.membershipId",
5036
+ "seat.entitlementId",
5037
+ "seat.personId",
5038
+ "seat.recipientName",
5039
+ "seat.recipientEmail",
5040
+ "seat.role",
5041
+ "seat.status",
5042
+ "seat.acceptanceExpiresAt",
5043
+ "seat.acceptedAt",
5044
+ "seat.activatedAt",
5045
+ "seat.refundedAt"
5046
+ ]
5047
+ }),
5048
+ ...rows2({
5049
+ scope: "network",
5050
+ writer: "network_referral_ledger",
5051
+ projections: ["bnf_admin", "chapter_admin", "member_self_service"],
5052
+ sensitivity: "ordinary",
5053
+ memberAccess: "read",
5054
+ fields: [
5055
+ "referral.referrerPersonId",
5056
+ "referral.referredPersonId",
5057
+ "referral.qualifiedMembershipId",
5058
+ "referral.creditCents",
5059
+ "referral.status",
5060
+ "referral.appliedInvoiceId",
5061
+ "referral.carryForwardCents",
5062
+ "referral.adjustmentOf"
5063
+ ]
5064
+ }),
5065
+ ...rows2({
5066
+ scope: "network",
5067
+ writer: "network_investment_ledger",
5068
+ projections: ["bnf_admin", "chapter_admin", "member_self_service"],
5069
+ sensitivity: "restricted",
5070
+ memberAccess: "read",
5071
+ fields: [
5072
+ "investment.personId",
5073
+ "investment.chapterId",
5074
+ "investment.season",
5075
+ "investment.purpose",
5076
+ "investment.targetCount",
5077
+ "investment.status",
5078
+ "investment.amountCents",
5079
+ "investment.closedAt",
5080
+ "investment.sourceReference"
5081
+ ]
5082
+ }),
5083
+ ...rows2({
5084
+ scope: "provider",
5085
+ writer: "stripe",
5086
+ projections: ["stripe_billing", "bnf_admin", "chapter_admin"],
5087
+ sensitivity: "restricted",
5088
+ memberAccess: "none",
5089
+ fields: [
5090
+ "commercial.charge",
5091
+ "commercial.invoice",
5092
+ "commercial.refund",
5093
+ "commercial.providerSubscription",
5094
+ "commercial.paymentMethod"
5095
+ ]
5096
+ })
5097
+ ];
5098
+ var MEMBER_SELF_EDITABLE_FIELDS = new Set(
5099
+ MEMBER_SYSTEM_AUTHORITY_MATRIX.filter((row) => row.memberAccess === "edit").map((row) => row.id)
5100
+ );
5101
+ var MEMBER_SELF_READABLE_FIELDS = new Set(
5102
+ MEMBER_SYSTEM_AUTHORITY_MATRIX.filter((row) => row.memberAccess !== "none").map((row) => row.id)
5103
+ );
5104
+ function projectMemberSelf(record4) {
5105
+ return Object.fromEntries(Object.entries(record4).filter(([field]) => MEMBER_SELF_READABLE_FIELDS.has(field)));
5106
+ }
5107
+ function classifyMemberSystemWrite(intent) {
5108
+ if (intent.actor === "bnf") return "reject_bnf_surface";
5109
+ const authority = MEMBER_SYSTEM_AUTHORITY_MATRIX.find((row) => row.id === intent.field);
5110
+ if (!authority) return "reject_unknown_field";
5111
+ if (authority.writer !== intent.actor) return "reject_wrong_writer";
5112
+ if (intent.expectedRevision !== intent.actualRevision) return "reject_stale_revision";
5113
+ return "apply";
5114
+ }
5115
+ function validateMemberSystemAuthority(matrix = MEMBER_SYSTEM_AUTHORITY_MATRIX) {
5116
+ const errors = [];
5117
+ const ids = /* @__PURE__ */ new Set();
5118
+ for (const row of matrix) {
5119
+ if (!row.id || !row.id.includes(".")) errors.push(`invalid field id "${row.id}"`);
5120
+ if (ids.has(row.id)) errors.push(`duplicate field authority "${row.id}"`);
5121
+ ids.add(row.id);
5122
+ if (row.memberAccess !== "none" && !row.projections.includes("member_self_service")) {
5123
+ errors.push(`${row.id} grants member access without a member_self_service projection`);
5124
+ }
5125
+ if (row.id.startsWith("person.") && (row.scope !== "network" || row.writer !== "network_person")) {
5126
+ errors.push(`${row.id} must be network_person authority`);
5127
+ }
5128
+ if (row.id.startsWith("journey.") && (row.scope !== "chapter" || row.writer !== "chapter_journey")) {
5129
+ errors.push(`${row.id} must be chapter_journey authority`);
5130
+ }
5131
+ }
5132
+ return { ok: errors.length === 0, errors };
5133
+ }
5134
+
5135
+ // src/member-system-contract.ts
5136
+ var MEMBER_SYSTEM_CONTRACT_VERSION = 1;
5137
+ var JOURNEY_STAGES = [
5138
+ "identified",
5139
+ "researched",
5140
+ "outreach",
5141
+ "in_conversation",
5142
+ "invited_or_requested",
5143
+ "application_started",
5144
+ "applied",
5145
+ "paid_awaiting_conversation",
5146
+ "ready_to_book",
5147
+ "booked",
5148
+ "met",
5149
+ "approved",
5150
+ "onboarded",
5151
+ "active",
5152
+ "first_deal"
5153
+ ];
5154
+ var JOURNEY_ENDINGS = ["passed", "declined", "withdrew", "lapsed"];
5155
+ var REQUIRED_NOTICE_KINDS = [
5156
+ "payment_receipt",
5157
+ "refund_confirmation",
5158
+ "security_alert",
5159
+ "legal_notice",
5160
+ "membership_status",
5161
+ "renewal_notice",
5162
+ "cancellation_confirmation"
5163
+ ];
5164
+ function memberSystemAvailability(input) {
5165
+ if (!input.odlaReachable) {
5166
+ return {
5167
+ bnfAdministration: false,
5168
+ chapterWorkflow: false,
5169
+ memberSelfService: false,
5170
+ newApplication: false,
5171
+ newCheckout: false,
5172
+ providerRenewalsMayContinue: true,
5173
+ reason: "odla_unavailable"
5174
+ };
5175
+ }
5176
+ return {
5177
+ bnfAdministration: input.bnfFrontendReachable,
5178
+ chapterWorkflow: true,
5179
+ memberSelfService: true,
5180
+ newApplication: true,
5181
+ newCheckout: true,
5182
+ providerRenewalsMayContinue: true,
5183
+ ...!input.bnfFrontendReachable ? { reason: "bnf_frontend_unavailable" } : {}
5184
+ };
5185
+ }
5186
+ function classifyMemberStripeEvent(identity, target, hasProvenLegacyLocalLink) {
5187
+ const keys = ["appId", "environment", "dataEnvironment", "runtime", "chapterId"];
5188
+ const supplied = keys.filter((key) => identity[key] !== void 0);
5189
+ if (supplied.some((key) => identity[key] !== target[key])) return "ignore_sibling";
5190
+ if (supplied.length === keys.length) return "apply";
5191
+ return hasProvenLegacyLocalLink ? "apply_legacy" : "quarantine_unmatched";
5192
+ }
5193
+ function planMemberSystemEventReplay(events) {
5194
+ const seen = /* @__PURE__ */ new Map();
5195
+ const plan = { accepted: [], replayed: [], collisions: [] };
5196
+ for (const event of events) {
5197
+ const digest = seen.get(event.id);
5198
+ if (digest === void 0) {
5199
+ seen.set(event.id, event.digest);
5200
+ plan.accepted.push(event.id);
5201
+ } else if (digest === event.digest) plan.replayed.push(event.id);
5202
+ else plan.collisions.push(event.id);
5203
+ }
5204
+ return plan;
5205
+ }
5206
+ var MEMBER_SYSTEM_RECOVERY_OBJECTIVES = {
5207
+ failClosedWithinMs: 0,
5208
+ replayProjectionWithinMinutes: 15,
5209
+ providerEventsRemainReplayable: true,
5210
+ requireHumanReviewForCollision: true
5211
+ };
5212
+ function planMemberSystemMigration(rows3) {
5213
+ const plan = { importIds: [], fixtureIds: [], rejectedIds: [] };
5214
+ for (const row of rows3) {
5215
+ if (row.source === "synthetic_fixture" && !row.isRealPerson) plan.fixtureIds.push(row.id);
5216
+ else if (row.source === "external_reimport" && row.isRealPerson && row.provenance) plan.importIds.push(row.id);
5217
+ else plan.rejectedIds.push(row.id);
5218
+ }
5219
+ return plan;
5220
+ }
5221
+ function memberSystemRollbackPlan() {
5222
+ return {
5223
+ stopNetworkWrites: true,
5224
+ disableBnfMemberMutations: true,
5225
+ keepChapterProductionReads: true,
5226
+ keepStripeBillingAuthority: true,
5227
+ deleteProviderObjects: false,
5228
+ reverseProviderPayments: false,
5229
+ reconciliationRequired: true
5230
+ };
5231
+ }
5232
+ var SILVER_SALT_P0_FIXTURE = {
5233
+ sourceInventory: { applications: 36, meetings: 7, emails: 49, realPeople: 0 },
5234
+ application: { id: "fixture_application_001", personId: "fixture_person_001", migrates: false },
5235
+ crm: { recordId: "fixture_crm_001", email: "fixture.member@example.invalid", migrates: false },
5236
+ clerk: { userId: "user_fixture_001", verifiedEmail: "fixture.member@example.invalid", migrates: false },
5237
+ stripe: {
5238
+ customerId: "cus_fixture_001",
5239
+ subscriptionId: "sub_fixture_001",
5240
+ productId: "prod_fixture_001",
5241
+ priceId: "price_fixture_001",
5242
+ eventId: "evt_fixture_001",
5243
+ migrates: false
5244
+ },
5245
+ unmatchedStripeEvent: { id: "evt_fixture_unmatched", disposition: "quarantine_unmatched" },
5246
+ legacyStripeEvent: { id: "evt_fixture_legacy", requiresProvenLocalLink: true }
5247
+ };
4777
5248
  export {
4778
5249
  ADMISSION_GRANTS_PATH,
4779
5250
  ADMISSION_GRANTS_SCHEMA_VERSION,
@@ -4787,16 +5258,25 @@ export {
4787
5258
  DEFAULT_CHAPTER_COPY,
4788
5259
  DEFAULT_SHARE_FIELDS,
4789
5260
  GIFT_OFFER_CATALOG_VERSION,
5261
+ JOURNEY_ENDINGS,
5262
+ JOURNEY_STAGES,
4790
5263
  MAX_GIFT_OFFERS,
4791
5264
  MEMBERSHIP_PAGE_RENDERER,
4792
5265
  MEMBER_CONTENT_CONTROL_PATH,
4793
5266
  MEMBER_CONTENT_PATH,
4794
5267
  MEMBER_CONTENT_SCHEMA_VERSION,
5268
+ MEMBER_SELF_EDITABLE_FIELDS,
5269
+ MEMBER_SELF_READABLE_FIELDS,
5270
+ MEMBER_SYSTEM_AUTHORITY_MATRIX,
5271
+ MEMBER_SYSTEM_CONTRACT_VERSION,
5272
+ MEMBER_SYSTEM_RECOVERY_OBJECTIVES,
5273
+ REQUIRED_NOTICE_KINDS,
4795
5274
  SCHEDULING_DEFAULTS,
4796
5275
  SIGNUP_CONTROL_PATH,
4797
5276
  SIGNUP_CONTROL_SCHEMA_VERSION,
4798
5277
  SIGNUP_CONTROL_THEME_MARKER,
4799
5278
  SIGNUP_CONTROL_THEME_STYLE_ID,
5279
+ SILVER_SALT_P0_FIXTURE,
4800
5280
  applicantProfile,
4801
5281
  applicationBookingUpdate,
4802
5282
  applicationFlowFields,
@@ -4823,6 +5303,8 @@ export {
4823
5303
  chapterDb,
4824
5304
  chapterFlowFieldContract,
4825
5305
  clampArray,
5306
+ classifyMemberStripeEvent,
5307
+ classifyMemberSystemWrite,
4826
5308
  clerkGetUser,
4827
5309
  clerkGetUserByEmail,
4828
5310
  clerkIntegration,
@@ -4876,6 +5358,8 @@ export {
4876
5358
  memberContentDigest,
4877
5359
  memberContentDocument,
4878
5360
  memberSession,
5361
+ memberSystemAvailability,
5362
+ memberSystemRollbackPlan,
4879
5363
  membershipPageDocument,
4880
5364
  membershipTierPresentationFromMarkdown,
4881
5365
  networkSourceTag,
@@ -4887,9 +5371,12 @@ export {
4887
5371
  paymentsReady,
4888
5372
  personInputFromApp,
4889
5373
  planDelivery,
5374
+ planMemberSystemEventReplay,
5375
+ planMemberSystemMigration,
4890
5376
  projectApplicant,
4891
5377
  projectBuilderLibraryDelivery,
4892
5378
  projectMemberContent,
5379
+ projectMemberSelf,
4893
5380
  projectSharedRecord,
4894
5381
  promoteBuilderLibraryResource,
4895
5382
  publicGiftOffers,
@@ -4932,6 +5419,7 @@ export {
4932
5419
  validateBuilderLibraryDocument,
4933
5420
  validateGiftOfferCatalog,
4934
5421
  validateMemberContentDocument,
5422
+ validateMemberSystemAuthority,
4935
5423
  validateMembershipPageDocument,
4936
5424
  validateScheduling,
4937
5425
  validateSignupControlDocument,