@odla-ai/chapter 0.58.0 → 0.59.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.
@@ -1,6 +1,11 @@
1
1
  import { CrmConfig, Crm, FieldConditions } from '@odla-ai/crm';
2
2
  import { initAdmin } from '@odla-ai/db';
3
3
 
4
+ /** The part of a Workers ExecutionContext a chapter route needs: let work outlive the response. */
5
+ interface ExecutionLike {
6
+ waitUntil(promise: Promise<unknown>): void;
7
+ }
8
+
4
9
  /** One membership tier a chapter offers. `priceCents: 0` means free. */
5
10
  interface ChapterTier {
6
11
  /** Stable slug, referenced by `applications.tierId`. Never renumbered. */
@@ -83,6 +88,10 @@ interface ChapterCopy {
83
88
  booking: TextFields<"unavailable" | "loadFailed" | "slotTaken" | "failed" | "loading" | "book" | "booking"> & {
84
89
  title?: string;
85
90
  intro?: string;
91
+ /** Shown under the booking button until a date is chosen. */
92
+ pickDate?: string;
93
+ /** Shown under the booking button once a date is chosen, until a time is. */
94
+ pickTime?: string;
86
95
  };
87
96
  /**
88
97
  * `consent` is the affirmative statement a member agrees to before the card
@@ -1493,6 +1502,8 @@ declare function createWorkerContext(options: ChapterWorkerOptions): {
1493
1502
  stripeSecretName?: string;
1494
1503
  } | undefined;
1495
1504
  recordError: ChapterErrorRecorder;
1505
+ bindExecution: (req: Request, execution: ExecutionLike | undefined) => void;
1506
+ defer: (req: Request, task: () => Promise<unknown>) => Promise<void>;
1496
1507
  getPublicConfig: (env: ChapterEnv) => Promise<PublicConfig>;
1497
1508
  verifyUser: (req: Request, env: ChapterEnv) => Promise<Verified | null>;
1498
1509
  makeDb: (env: ChapterEnv) => Db;
@@ -1564,6 +1575,55 @@ type NamedSeatOperatorRefundInput = MembershipQuoteTarget & {
1564
1575
  */
1565
1576
  declare function refundNamedSeatByOperator(db: ChapterDb, input: NamedSeatOperatorRefundInput, stripeSecretKey: string, now: number): Promise<NamedSeatRefundReceipt>;
1566
1577
 
1578
+ /** Membership status while a card-network dispute has the payment pulled back. Access is refused until the dispute is won
1579
+ * or an operator re-issues the charge. */
1580
+ declare const MEMBERSHIP_DISPUTED_STATUS = "payment_disputed";
1581
+ /** The charge a dispute names, read from Stripe so a webhook body never chooses which membership it touches. */
1582
+ interface DisputedCharge {
1583
+ chargeId: string;
1584
+ customerId: string;
1585
+ invoiceId?: string;
1586
+ subscriptionId?: string;
1587
+ paymentIntentId?: string;
1588
+ /** Present when the charge paid a named seat; the primary membership is then not the disputed purchase. */
1589
+ seatId?: string;
1590
+ }
1591
+ /** Billing receipt plus the dispute's current standing and whether this event changed anything. */
1592
+ interface MembershipDisputeReceipt extends MembershipRenewalReceipt {
1593
+ disputeStatus?: string;
1594
+ applied: boolean;
1595
+ }
1596
+ /** Resolve the disputed charge, and the subscription behind its invoice, with the network's own Stripe credential. */
1597
+ declare function readDisputedCharge(secretKey: string, chargeId: string, fetch?: typeof globalThis.fetch): Promise<DisputedCharge>;
1598
+ /** Apply one verified `charge.dispute.*` fact to the membership it names. An open dispute suspends access; a won dispute
1599
+ * restores the status it interrupted; a lost one leaves the membership suspended until an operator re-issues the charge.
1600
+ * Idempotent per event, a closed dispute outranks a late opening event, and a charge that is not this membership's
1601
+ * (a seat, another purchase) changes nothing. */
1602
+ declare function reconcileMembershipDispute(db: ChapterDb, input: MembershipQuoteTarget & {
1603
+ eventId: string;
1604
+ }, now: number, secretKey: string, resolved?: DisputedCharge): Promise<MembershipDisputeReceipt>;
1605
+
1606
+ /** What an operator sees after asking the network to collect a lost dispute's amount again. */
1607
+ interface MembershipRechargeReceipt {
1608
+ membershipId: string;
1609
+ status: string;
1610
+ paymentIntentId: string;
1611
+ amountCents: number;
1612
+ currency: string;
1613
+ replayed?: true;
1614
+ }
1615
+ /** Stripe's final answer to a re-issued charge, with the decline code when the card refused it. */
1616
+ interface MembershipRechargeError extends Error {
1617
+ code: string;
1618
+ declineCode?: string;
1619
+ paymentStatus?: string;
1620
+ }
1621
+ /** Collect a lost dispute's amount again on the member's saved card, because an operator decided to after the member cleared the
1622
+ * report with their bank. Never automatic. One idempotency key lives on the row until Stripe answers, so a lost response cannot
1623
+ * charge twice; a declined card ends the attempt so the next click starts a fresh one. Success restores the status the dispute
1624
+ * interrupted. */
1625
+ declare function rechargeDisputedMembership(db: ChapterDb, membershipId: string, secretKey: string, now: number): Promise<MembershipRechargeReceipt>;
1626
+
1567
1627
  /** Seat states in which the purchaser may still name someone else: invited or accepted, never active, refunded or unpaid. */
1568
1628
  declare const REGIFTABLE_SEAT_STATUSES: readonly ["pending_acceptance", "pending_approval", "pending_primary"];
1569
1629
  /** Whether a seat may be given to a different recipient (BNF bug 38000934): final once active. */
@@ -2332,7 +2392,9 @@ declare function withActiveSignupControlTheme(response: Response, options: Activ
2332
2392
  * keep those alerts as structured `console.error` lines.
2333
2393
  */
2334
2394
  declare function chapterWorker(options: ChapterWorkerOptions): {
2335
- fetch(req: Request, env: ChapterEnv): Promise<Response>;
2395
+ fetch(req: Request, env: ChapterEnv, execution?: {
2396
+ waitUntil(promise: Promise<unknown>): void;
2397
+ }): Promise<Response>;
2336
2398
  };
2337
2399
 
2338
- export { type ActiveSignupControlHtml, type ActiveSignupControlThemeOptions, AdmissionGrantDeliveryError, type AdmissionGrantDeliveryOptions, type BuilderLibraryDeliveryOptions, type ChapterEnv, type ChapterErrorRecorder, type ChapterErrorReport, type ChapterWorkerOptions, DECLINABLE_FROM, type FormerNamedSeatRecipient, type IncludedNamedSeatReceipt, type LeaderAdmissionAssignment, type LeaderAdmissionDelivery, type LeaderAdmissionDeliveryStatus, MEMBERSHIP_AUTHORITY_PATH, MEMBERSHIP_CHAPTER_EFFECT_KINDS, type MemberContentDeliveryOptions, type MembershipAuthorityHandlerOptions, type MembershipAuthorityPeer, type MembershipChapterEffect, type MembershipChapterEffectKind, type MembershipEffectScope, type MembershipRetermInput, type MembershipRetermReceipt, type MembershipRetermSkipReason, type MembershipWorkerAdapter, type MembershipWorkerAdapterOptions, type NamedSeatOffer, type NamedSeatOfferSeat, type NamedSeatOperatorRefundInput, type NamedSeatRecipientState, type NamedSeatRefundReason, type NamedSeatRegiftReceipt, type NamedSeatReleaseInput, type NetworkTargetTransport, NetworkTargetTransportError, REGIFTABLE_SEAT_STATUSES, type RegiftNamedSeatInput, type Route, type SeatRepriceReceipt, type SeatRepriceScope, type SignupControlDeliveryOptions, type SignupEligibility, type SignupPredecessor, type WorkerContext, chapterMembershipAccess, chapterWorker, closedApplication, continueApplicationOnFreeTier, createMembershipAuthorityHandler, createMembershipAuthorityStorage, createMembershipChapterEffectRoute, createMembershipWorkerAdapter, createWorkerContext, declineApplication, deliverAdmissionGrants, deliverBuilderLibrary, deliverMemberContent, deliverMembershipChapterEffect, deliverSignupControl, drainMembershipEffects, grantIncludedNamedSeat, liftSeatPurchaseWindow, lowerSeatPrice, namedSeatIncluded, namedSeatInvitationOpen, namedSeatRecipientState, namedSeatRegiftable, readNamedSeatOffer, refundNamedSeatByOperator, regiftNamedSeat, releaseNamedSeatRecipientApplications, renderActiveSignupControlHtml, resolveNetworkTargetTransport, resolveSignupEligibility, retermMembershipDiscount, retryChapterApprovalEffects, retryLeaderAdmissionDeliveries, withActiveSignupControlTheme };
2400
+ export { type ActiveSignupControlHtml, type ActiveSignupControlThemeOptions, AdmissionGrantDeliveryError, type AdmissionGrantDeliveryOptions, type BuilderLibraryDeliveryOptions, type ChapterEnv, type ChapterErrorRecorder, type ChapterErrorReport, type ChapterWorkerOptions, DECLINABLE_FROM, type DisputedCharge, type FormerNamedSeatRecipient, type IncludedNamedSeatReceipt, type LeaderAdmissionAssignment, type LeaderAdmissionDelivery, type LeaderAdmissionDeliveryStatus, MEMBERSHIP_AUTHORITY_PATH, MEMBERSHIP_CHAPTER_EFFECT_KINDS, MEMBERSHIP_DISPUTED_STATUS, type MemberContentDeliveryOptions, type MembershipAuthorityHandlerOptions, type MembershipAuthorityPeer, type MembershipChapterEffect, type MembershipChapterEffectKind, type MembershipDisputeReceipt, type MembershipEffectScope, type MembershipRechargeError, type MembershipRechargeReceipt, type MembershipRetermInput, type MembershipRetermReceipt, type MembershipRetermSkipReason, type MembershipWorkerAdapter, type MembershipWorkerAdapterOptions, type NamedSeatOffer, type NamedSeatOfferSeat, type NamedSeatOperatorRefundInput, type NamedSeatRecipientState, type NamedSeatRefundReason, type NamedSeatRegiftReceipt, type NamedSeatReleaseInput, type NetworkTargetTransport, NetworkTargetTransportError, REGIFTABLE_SEAT_STATUSES, type RegiftNamedSeatInput, type Route, type SeatRepriceReceipt, type SeatRepriceScope, type SignupControlDeliveryOptions, type SignupEligibility, type SignupPredecessor, type WorkerContext, chapterMembershipAccess, chapterWorker, closedApplication, continueApplicationOnFreeTier, createMembershipAuthorityHandler, createMembershipAuthorityStorage, createMembershipChapterEffectRoute, createMembershipWorkerAdapter, createWorkerContext, declineApplication, deliverAdmissionGrants, deliverBuilderLibrary, deliverMemberContent, deliverMembershipChapterEffect, deliverSignupControl, drainMembershipEffects, grantIncludedNamedSeat, liftSeatPurchaseWindow, lowerSeatPrice, namedSeatIncluded, namedSeatInvitationOpen, namedSeatRecipientState, namedSeatRegiftable, readDisputedCharge, readNamedSeatOffer, rechargeDisputedMembership, reconcileMembershipDispute, refundNamedSeatByOperator, regiftNamedSeat, releaseNamedSeatRecipientApplications, renderActiveSignupControlHtml, resolveNetworkTargetTransport, resolveSignupEligibility, retermMembershipDiscount, retryChapterApprovalEffects, retryLeaderAdmissionDeliveries, withActiveSignupControlTheme };
@@ -1,6 +1,11 @@
1
1
  import { CrmConfig, Crm, FieldConditions } from '@odla-ai/crm';
2
2
  import { initAdmin } from '@odla-ai/db';
3
3
 
4
+ /** The part of a Workers ExecutionContext a chapter route needs: let work outlive the response. */
5
+ interface ExecutionLike {
6
+ waitUntil(promise: Promise<unknown>): void;
7
+ }
8
+
4
9
  /** One membership tier a chapter offers. `priceCents: 0` means free. */
5
10
  interface ChapterTier {
6
11
  /** Stable slug, referenced by `applications.tierId`. Never renumbered. */
@@ -83,6 +88,10 @@ interface ChapterCopy {
83
88
  booking: TextFields<"unavailable" | "loadFailed" | "slotTaken" | "failed" | "loading" | "book" | "booking"> & {
84
89
  title?: string;
85
90
  intro?: string;
91
+ /** Shown under the booking button until a date is chosen. */
92
+ pickDate?: string;
93
+ /** Shown under the booking button once a date is chosen, until a time is. */
94
+ pickTime?: string;
86
95
  };
87
96
  /**
88
97
  * `consent` is the affirmative statement a member agrees to before the card
@@ -1493,6 +1502,8 @@ declare function createWorkerContext(options: ChapterWorkerOptions): {
1493
1502
  stripeSecretName?: string;
1494
1503
  } | undefined;
1495
1504
  recordError: ChapterErrorRecorder;
1505
+ bindExecution: (req: Request, execution: ExecutionLike | undefined) => void;
1506
+ defer: (req: Request, task: () => Promise<unknown>) => Promise<void>;
1496
1507
  getPublicConfig: (env: ChapterEnv) => Promise<PublicConfig>;
1497
1508
  verifyUser: (req: Request, env: ChapterEnv) => Promise<Verified | null>;
1498
1509
  makeDb: (env: ChapterEnv) => Db;
@@ -1564,6 +1575,55 @@ type NamedSeatOperatorRefundInput = MembershipQuoteTarget & {
1564
1575
  */
1565
1576
  declare function refundNamedSeatByOperator(db: ChapterDb, input: NamedSeatOperatorRefundInput, stripeSecretKey: string, now: number): Promise<NamedSeatRefundReceipt>;
1566
1577
 
1578
+ /** Membership status while a card-network dispute has the payment pulled back. Access is refused until the dispute is won
1579
+ * or an operator re-issues the charge. */
1580
+ declare const MEMBERSHIP_DISPUTED_STATUS = "payment_disputed";
1581
+ /** The charge a dispute names, read from Stripe so a webhook body never chooses which membership it touches. */
1582
+ interface DisputedCharge {
1583
+ chargeId: string;
1584
+ customerId: string;
1585
+ invoiceId?: string;
1586
+ subscriptionId?: string;
1587
+ paymentIntentId?: string;
1588
+ /** Present when the charge paid a named seat; the primary membership is then not the disputed purchase. */
1589
+ seatId?: string;
1590
+ }
1591
+ /** Billing receipt plus the dispute's current standing and whether this event changed anything. */
1592
+ interface MembershipDisputeReceipt extends MembershipRenewalReceipt {
1593
+ disputeStatus?: string;
1594
+ applied: boolean;
1595
+ }
1596
+ /** Resolve the disputed charge, and the subscription behind its invoice, with the network's own Stripe credential. */
1597
+ declare function readDisputedCharge(secretKey: string, chargeId: string, fetch?: typeof globalThis.fetch): Promise<DisputedCharge>;
1598
+ /** Apply one verified `charge.dispute.*` fact to the membership it names. An open dispute suspends access; a won dispute
1599
+ * restores the status it interrupted; a lost one leaves the membership suspended until an operator re-issues the charge.
1600
+ * Idempotent per event, a closed dispute outranks a late opening event, and a charge that is not this membership's
1601
+ * (a seat, another purchase) changes nothing. */
1602
+ declare function reconcileMembershipDispute(db: ChapterDb, input: MembershipQuoteTarget & {
1603
+ eventId: string;
1604
+ }, now: number, secretKey: string, resolved?: DisputedCharge): Promise<MembershipDisputeReceipt>;
1605
+
1606
+ /** What an operator sees after asking the network to collect a lost dispute's amount again. */
1607
+ interface MembershipRechargeReceipt {
1608
+ membershipId: string;
1609
+ status: string;
1610
+ paymentIntentId: string;
1611
+ amountCents: number;
1612
+ currency: string;
1613
+ replayed?: true;
1614
+ }
1615
+ /** Stripe's final answer to a re-issued charge, with the decline code when the card refused it. */
1616
+ interface MembershipRechargeError extends Error {
1617
+ code: string;
1618
+ declineCode?: string;
1619
+ paymentStatus?: string;
1620
+ }
1621
+ /** Collect a lost dispute's amount again on the member's saved card, because an operator decided to after the member cleared the
1622
+ * report with their bank. Never automatic. One idempotency key lives on the row until Stripe answers, so a lost response cannot
1623
+ * charge twice; a declined card ends the attempt so the next click starts a fresh one. Success restores the status the dispute
1624
+ * interrupted. */
1625
+ declare function rechargeDisputedMembership(db: ChapterDb, membershipId: string, secretKey: string, now: number): Promise<MembershipRechargeReceipt>;
1626
+
1567
1627
  /** Seat states in which the purchaser may still name someone else: invited or accepted, never active, refunded or unpaid. */
1568
1628
  declare const REGIFTABLE_SEAT_STATUSES: readonly ["pending_acceptance", "pending_approval", "pending_primary"];
1569
1629
  /** Whether a seat may be given to a different recipient (BNF bug 38000934): final once active. */
@@ -2332,7 +2392,9 @@ declare function withActiveSignupControlTheme(response: Response, options: Activ
2332
2392
  * keep those alerts as structured `console.error` lines.
2333
2393
  */
2334
2394
  declare function chapterWorker(options: ChapterWorkerOptions): {
2335
- fetch(req: Request, env: ChapterEnv): Promise<Response>;
2395
+ fetch(req: Request, env: ChapterEnv, execution?: {
2396
+ waitUntil(promise: Promise<unknown>): void;
2397
+ }): Promise<Response>;
2336
2398
  };
2337
2399
 
2338
- export { type ActiveSignupControlHtml, type ActiveSignupControlThemeOptions, AdmissionGrantDeliveryError, type AdmissionGrantDeliveryOptions, type BuilderLibraryDeliveryOptions, type ChapterEnv, type ChapterErrorRecorder, type ChapterErrorReport, type ChapterWorkerOptions, DECLINABLE_FROM, type FormerNamedSeatRecipient, type IncludedNamedSeatReceipt, type LeaderAdmissionAssignment, type LeaderAdmissionDelivery, type LeaderAdmissionDeliveryStatus, MEMBERSHIP_AUTHORITY_PATH, MEMBERSHIP_CHAPTER_EFFECT_KINDS, type MemberContentDeliveryOptions, type MembershipAuthorityHandlerOptions, type MembershipAuthorityPeer, type MembershipChapterEffect, type MembershipChapterEffectKind, type MembershipEffectScope, type MembershipRetermInput, type MembershipRetermReceipt, type MembershipRetermSkipReason, type MembershipWorkerAdapter, type MembershipWorkerAdapterOptions, type NamedSeatOffer, type NamedSeatOfferSeat, type NamedSeatOperatorRefundInput, type NamedSeatRecipientState, type NamedSeatRefundReason, type NamedSeatRegiftReceipt, type NamedSeatReleaseInput, type NetworkTargetTransport, NetworkTargetTransportError, REGIFTABLE_SEAT_STATUSES, type RegiftNamedSeatInput, type Route, type SeatRepriceReceipt, type SeatRepriceScope, type SignupControlDeliveryOptions, type SignupEligibility, type SignupPredecessor, type WorkerContext, chapterMembershipAccess, chapterWorker, closedApplication, continueApplicationOnFreeTier, createMembershipAuthorityHandler, createMembershipAuthorityStorage, createMembershipChapterEffectRoute, createMembershipWorkerAdapter, createWorkerContext, declineApplication, deliverAdmissionGrants, deliverBuilderLibrary, deliverMemberContent, deliverMembershipChapterEffect, deliverSignupControl, drainMembershipEffects, grantIncludedNamedSeat, liftSeatPurchaseWindow, lowerSeatPrice, namedSeatIncluded, namedSeatInvitationOpen, namedSeatRecipientState, namedSeatRegiftable, readNamedSeatOffer, refundNamedSeatByOperator, regiftNamedSeat, releaseNamedSeatRecipientApplications, renderActiveSignupControlHtml, resolveNetworkTargetTransport, resolveSignupEligibility, retermMembershipDiscount, retryChapterApprovalEffects, retryLeaderAdmissionDeliveries, withActiveSignupControlTheme };
2400
+ export { type ActiveSignupControlHtml, type ActiveSignupControlThemeOptions, AdmissionGrantDeliveryError, type AdmissionGrantDeliveryOptions, type BuilderLibraryDeliveryOptions, type ChapterEnv, type ChapterErrorRecorder, type ChapterErrorReport, type ChapterWorkerOptions, DECLINABLE_FROM, type DisputedCharge, type FormerNamedSeatRecipient, type IncludedNamedSeatReceipt, type LeaderAdmissionAssignment, type LeaderAdmissionDelivery, type LeaderAdmissionDeliveryStatus, MEMBERSHIP_AUTHORITY_PATH, MEMBERSHIP_CHAPTER_EFFECT_KINDS, MEMBERSHIP_DISPUTED_STATUS, type MemberContentDeliveryOptions, type MembershipAuthorityHandlerOptions, type MembershipAuthorityPeer, type MembershipChapterEffect, type MembershipChapterEffectKind, type MembershipDisputeReceipt, type MembershipEffectScope, type MembershipRechargeError, type MembershipRechargeReceipt, type MembershipRetermInput, type MembershipRetermReceipt, type MembershipRetermSkipReason, type MembershipWorkerAdapter, type MembershipWorkerAdapterOptions, type NamedSeatOffer, type NamedSeatOfferSeat, type NamedSeatOperatorRefundInput, type NamedSeatRecipientState, type NamedSeatRefundReason, type NamedSeatRegiftReceipt, type NamedSeatReleaseInput, type NetworkTargetTransport, NetworkTargetTransportError, REGIFTABLE_SEAT_STATUSES, type RegiftNamedSeatInput, type Route, type SeatRepriceReceipt, type SeatRepriceScope, type SignupControlDeliveryOptions, type SignupEligibility, type SignupPredecessor, type WorkerContext, chapterMembershipAccess, chapterWorker, closedApplication, continueApplicationOnFreeTier, createMembershipAuthorityHandler, createMembershipAuthorityStorage, createMembershipChapterEffectRoute, createMembershipWorkerAdapter, createWorkerContext, declineApplication, deliverAdmissionGrants, deliverBuilderLibrary, deliverMemberContent, deliverMembershipChapterEffect, deliverSignupControl, drainMembershipEffects, grantIncludedNamedSeat, liftSeatPurchaseWindow, lowerSeatPrice, namedSeatIncluded, namedSeatInvitationOpen, namedSeatRecipientState, namedSeatRegiftable, readDisputedCharge, readNamedSeatOffer, rechargeDisputedMembership, reconcileMembershipDispute, refundNamedSeatByOperator, regiftNamedSeat, releaseNamedSeatRecipientApplications, renderActiveSignupControlHtml, resolveNetworkTargetTransport, resolveSignupEligibility, retermMembershipDiscount, retryChapterApprovalEffects, retryLeaderAdmissionDeliveries, withActiveSignupControlTheme };