@odla-ai/chapter 0.59.0 → 0.59.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.
@@ -1091,7 +1091,7 @@ declare const namedSeatIncluded: (seat: {
1091
1091
  amountCents?: unknown;
1092
1092
  }) => boolean;
1093
1093
  /** Where the named recipient stands, from the purchaser's side, folded from the seat's lifecycle status. */
1094
- type NamedSeatRecipientState = "payment_pending" | "invited" | "accepted" | "joined" | "declined" | "refunded" | "canceled";
1094
+ type NamedSeatRecipientState = "payment_pending" | "invited" | "accepted" | "joined" | "declined" | "refunded" | "canceled" | "disputed";
1095
1095
  /** Fold the seat status machine into the words a members page needs: whether the person was invited, accepted, joined or left. */
1096
1096
  declare function namedSeatRecipientState(seat: {
1097
1097
  status?: unknown;
@@ -1287,6 +1287,71 @@ type NamedSeatEvidenceRequest = MembershipQuoteTarget & {
1287
1287
  eventId: string;
1288
1288
  };
1289
1289
 
1290
+ /** Stripe metadata fields used to bind one fact to an exact configured source. */
1291
+ interface CommercialIdentity {
1292
+ appId?: string;
1293
+ chapterId?: string;
1294
+ environment?: string;
1295
+ dataEnvironment?: string;
1296
+ runtime?: string;
1297
+ }
1298
+ /** Provider object categories materialized by the network commercial shadow. */
1299
+ type CommercialObjectKind = "customer" | "subscription" | "invoice" | "refund" | "seat";
1300
+ /** One verified, allowlisted, PII-free Stripe event fact retained for replay. */
1301
+ interface NetworkCommercialFact {
1302
+ eventId: string;
1303
+ digest: string;
1304
+ eventType: string;
1305
+ eventCreated: number;
1306
+ livemode: boolean;
1307
+ objectKind: CommercialObjectKind | "payment_intent" | "dispute" | "ignored";
1308
+ objectId: string;
1309
+ identity: CommercialIdentity;
1310
+ applicationId?: string;
1311
+ personId?: string;
1312
+ membershipId?: string;
1313
+ seatId?: string;
1314
+ customerId?: string;
1315
+ subscriptionId?: string;
1316
+ invoiceId?: string;
1317
+ chargeId?: string;
1318
+ paymentIntentId?: string;
1319
+ /** Stripe's dispute reason (`fraudulent`, `product_not_received`, …) on a `charge.dispute.*` fact. */
1320
+ disputeReason?: string;
1321
+ subscriptionItemId?: string;
1322
+ refundedCents?: number;
1323
+ /** Complete recurring seat item references, with no recipient PII. */
1324
+ seatSubscriptionItems?: Array<{
1325
+ seatId: string;
1326
+ membershipId: string;
1327
+ subscriptionItemId: string;
1328
+ priceId: string;
1329
+ currentPeriodEnd?: number;
1330
+ }>;
1331
+ priceId?: string;
1332
+ quantity?: number;
1333
+ status?: string;
1334
+ currency?: string;
1335
+ amountCents?: number;
1336
+ amountPaidCents?: number;
1337
+ amountReceivedCents?: number;
1338
+ invoiceTotalCents?: number;
1339
+ billingReason?: string;
1340
+ invoicePaidAt?: number;
1341
+ invoicePeriodEndsAt?: number;
1342
+ /** Complete, non-prorated recurring invoice lines; absent when ambiguous or truncated. */
1343
+ recurringInvoiceLines?: Array<{
1344
+ priceId: string;
1345
+ quantity: number;
1346
+ startsAt: number;
1347
+ endsAt: number;
1348
+ }>;
1349
+ amountRemainingCents?: number;
1350
+ currentPeriodStart?: number;
1351
+ currentPeriodEnd?: number;
1352
+ cancelAtPeriodEnd?: boolean;
1353
+ }
1354
+
1290
1355
  /** Content-free operator alert attached to an error report. Its shape is a subset of
1291
1356
  * the `ErrorReport` that `recordError` from `@odla-ai/o11y` accepts, so a host passes
1292
1357
  * that function straight through as `ChapterWorkerOptions.recordError`. */
@@ -1575,9 +1640,49 @@ type NamedSeatOperatorRefundInput = MembershipQuoteTarget & {
1575
1640
  */
1576
1641
  declare function refundNamedSeatByOperator(db: ChapterDb, input: NamedSeatOperatorRefundInput, stripeSecretKey: string, now: number): Promise<NamedSeatRefundReceipt>;
1577
1642
 
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. */
1643
+ /** Fence both absence of a collision and an audited resolution of this exact retained fact. */
1644
+ declare function commercialEvidenceGuard(db: ChapterDb, eventId: string, digest: unknown, code?: string): Promise<{
1645
+ ns: string;
1646
+ id: string;
1647
+ exists: boolean;
1648
+ equals?: undefined;
1649
+ } | {
1650
+ ns: string;
1651
+ id: string;
1652
+ exists: boolean;
1653
+ equals: {
1654
+ status: string;
1655
+ resolvedDigest: string;
1656
+ updatedAt: unknown;
1657
+ };
1658
+ }>;
1659
+
1660
+ type Row$4 = Record<string, unknown>;
1661
+ type EvidenceGuard = Awaited<ReturnType<typeof commercialEvidenceGuard>>;
1662
+ /** The seat's own standing on a membership dispute receipt, present when the disputed charge paid a named seat. */
1663
+ interface NamedSeatDisputeStanding {
1664
+ seatId: string;
1665
+ status: string;
1666
+ disputeStatus?: string;
1667
+ applied: boolean;
1668
+ }
1669
+ /** True when the disputed charge paid this seat: its own PaymentIntent, or an operator's re-issued one. A seat line on the
1670
+ * primary subscription's invoice is the primary's charge and is handled there. */
1671
+ declare function disputedChargeCoversSeat(charge: DisputedCharge, seat: Row$4): boolean;
1672
+ /** Apply one verified `charge.dispute.*` fact to the named seat whose payment it names. The primary membership is never
1673
+ * touched: the recipient loses access through the seat's status alone, and a won dispute restores exactly the seat
1674
+ * status the dispute interrupted. Idempotent per event. */
1675
+ declare function reconcileNamedSeatDispute(db: ChapterDb, input: MembershipQuoteTarget & {
1676
+ eventId: string;
1677
+ }, now: number, charge: DisputedCharge, evidence: {
1678
+ row: Row$4;
1679
+ fact: NetworkCommercialFact;
1680
+ guard: EvidenceGuard;
1681
+ }): Promise<MembershipDisputeReceipt>;
1682
+
1683
+ /** Status a membership or named seat holds while a card-network dispute has its payment pulled back. */
1580
1684
  declare const MEMBERSHIP_DISPUTED_STATUS = "payment_disputed";
1685
+
1581
1686
  /** The charge a dispute names, read from Stripe so a webhook body never chooses which membership it touches. */
1582
1687
  interface DisputedCharge {
1583
1688
  chargeId: string;
@@ -1585,20 +1690,22 @@ interface DisputedCharge {
1585
1690
  invoiceId?: string;
1586
1691
  subscriptionId?: string;
1587
1692
  paymentIntentId?: string;
1588
- /** Present when the charge paid a named seat; the primary membership is then not the disputed purchase. */
1693
+ /** Present when the charge paid a named seat's own PaymentIntent; the dispute is then the seat's, not the primary's. */
1589
1694
  seatId?: string;
1590
1695
  }
1591
1696
  /** Billing receipt plus the dispute's current standing and whether this event changed anything. */
1592
1697
  interface MembershipDisputeReceipt extends MembershipRenewalReceipt {
1593
1698
  disputeStatus?: string;
1594
1699
  applied: boolean;
1700
+ /** The seat's standing when the disputed charge paid a named seat; the membership fields are then unchanged. */
1701
+ seat?: NamedSeatDisputeStanding;
1595
1702
  }
1596
1703
  /** Resolve the disputed charge, and the subscription behind its invoice, with the network's own Stripe credential. */
1597
1704
  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. */
1705
+ /** Apply one verified `charge.dispute.*` fact to the membership it names, or to the named seat when the charge paid a
1706
+ * seat's own PaymentIntent. An open dispute suspends access; a won dispute restores the status it interrupted; a lost
1707
+ * one leaves the record suspended until an operator re-issues the charge. Idempotent per event, a closed dispute
1708
+ * outranks a late opening event, and a charge that is neither this membership's nor its seat's changes nothing. */
1602
1709
  declare function reconcileMembershipDispute(db: ChapterDb, input: MembershipQuoteTarget & {
1603
1710
  eventId: string;
1604
1711
  }, now: number, secretKey: string, resolved?: DisputedCharge): Promise<MembershipDisputeReceipt>;
@@ -1611,6 +1718,8 @@ interface MembershipRechargeReceipt {
1611
1718
  amountCents: number;
1612
1719
  currency: string;
1613
1720
  replayed?: true;
1721
+ /** Present when the re-issued charge paid a named seat; `membershipId` is then the seat's primary membership. */
1722
+ seatId?: string;
1614
1723
  }
1615
1724
  /** Stripe's final answer to a re-issued charge, with the decline code when the card refused it. */
1616
1725
  interface MembershipRechargeError extends Error {
@@ -1618,11 +1727,10 @@ interface MembershipRechargeError extends Error {
1618
1727
  declineCode?: string;
1619
1728
  paymentStatus?: string;
1620
1729
  }
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>;
1730
+ /** Re-issue a membership's lost dispute amount; see {@link rechargeDisputed}. */
1731
+ declare const rechargeDisputedMembership: (db: ChapterDb, membershipId: string, secretKey: string, now: number) => Promise<MembershipRechargeReceipt>;
1732
+ /** Re-issue a named seat's lost dispute amount on the purchaser's saved card; the primary membership is untouched. */
1733
+ declare const rechargeDisputedSeat: (db: ChapterDb, seatId: string, secretKey: string, now: number) => Promise<MembershipRechargeReceipt>;
1626
1734
 
1627
1735
  /** Seat states in which the purchaser may still name someone else: invited or accepted, never active, refunded or unpaid. */
1628
1736
  declare const REGIFTABLE_SEAT_STATUSES: readonly ["pending_acceptance", "pending_approval", "pending_primary"];
@@ -2397,4 +2505,4 @@ declare function chapterWorker(options: ChapterWorkerOptions): {
2397
2505
  }): Promise<Response>;
2398
2506
  };
2399
2507
 
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 };
2508
+ 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 NamedSeatDisputeStanding, 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, disputedChargeCoversSeat, drainMembershipEffects, grantIncludedNamedSeat, liftSeatPurchaseWindow, lowerSeatPrice, namedSeatIncluded, namedSeatInvitationOpen, namedSeatRecipientState, namedSeatRegiftable, readDisputedCharge, readNamedSeatOffer, rechargeDisputedMembership, rechargeDisputedSeat, reconcileMembershipDispute, reconcileNamedSeatDispute, refundNamedSeatByOperator, regiftNamedSeat, releaseNamedSeatRecipientApplications, renderActiveSignupControlHtml, resolveNetworkTargetTransport, resolveSignupEligibility, retermMembershipDiscount, retryChapterApprovalEffects, retryLeaderAdmissionDeliveries, withActiveSignupControlTheme };
@@ -1091,7 +1091,7 @@ declare const namedSeatIncluded: (seat: {
1091
1091
  amountCents?: unknown;
1092
1092
  }) => boolean;
1093
1093
  /** Where the named recipient stands, from the purchaser's side, folded from the seat's lifecycle status. */
1094
- type NamedSeatRecipientState = "payment_pending" | "invited" | "accepted" | "joined" | "declined" | "refunded" | "canceled";
1094
+ type NamedSeatRecipientState = "payment_pending" | "invited" | "accepted" | "joined" | "declined" | "refunded" | "canceled" | "disputed";
1095
1095
  /** Fold the seat status machine into the words a members page needs: whether the person was invited, accepted, joined or left. */
1096
1096
  declare function namedSeatRecipientState(seat: {
1097
1097
  status?: unknown;
@@ -1287,6 +1287,71 @@ type NamedSeatEvidenceRequest = MembershipQuoteTarget & {
1287
1287
  eventId: string;
1288
1288
  };
1289
1289
 
1290
+ /** Stripe metadata fields used to bind one fact to an exact configured source. */
1291
+ interface CommercialIdentity {
1292
+ appId?: string;
1293
+ chapterId?: string;
1294
+ environment?: string;
1295
+ dataEnvironment?: string;
1296
+ runtime?: string;
1297
+ }
1298
+ /** Provider object categories materialized by the network commercial shadow. */
1299
+ type CommercialObjectKind = "customer" | "subscription" | "invoice" | "refund" | "seat";
1300
+ /** One verified, allowlisted, PII-free Stripe event fact retained for replay. */
1301
+ interface NetworkCommercialFact {
1302
+ eventId: string;
1303
+ digest: string;
1304
+ eventType: string;
1305
+ eventCreated: number;
1306
+ livemode: boolean;
1307
+ objectKind: CommercialObjectKind | "payment_intent" | "dispute" | "ignored";
1308
+ objectId: string;
1309
+ identity: CommercialIdentity;
1310
+ applicationId?: string;
1311
+ personId?: string;
1312
+ membershipId?: string;
1313
+ seatId?: string;
1314
+ customerId?: string;
1315
+ subscriptionId?: string;
1316
+ invoiceId?: string;
1317
+ chargeId?: string;
1318
+ paymentIntentId?: string;
1319
+ /** Stripe's dispute reason (`fraudulent`, `product_not_received`, …) on a `charge.dispute.*` fact. */
1320
+ disputeReason?: string;
1321
+ subscriptionItemId?: string;
1322
+ refundedCents?: number;
1323
+ /** Complete recurring seat item references, with no recipient PII. */
1324
+ seatSubscriptionItems?: Array<{
1325
+ seatId: string;
1326
+ membershipId: string;
1327
+ subscriptionItemId: string;
1328
+ priceId: string;
1329
+ currentPeriodEnd?: number;
1330
+ }>;
1331
+ priceId?: string;
1332
+ quantity?: number;
1333
+ status?: string;
1334
+ currency?: string;
1335
+ amountCents?: number;
1336
+ amountPaidCents?: number;
1337
+ amountReceivedCents?: number;
1338
+ invoiceTotalCents?: number;
1339
+ billingReason?: string;
1340
+ invoicePaidAt?: number;
1341
+ invoicePeriodEndsAt?: number;
1342
+ /** Complete, non-prorated recurring invoice lines; absent when ambiguous or truncated. */
1343
+ recurringInvoiceLines?: Array<{
1344
+ priceId: string;
1345
+ quantity: number;
1346
+ startsAt: number;
1347
+ endsAt: number;
1348
+ }>;
1349
+ amountRemainingCents?: number;
1350
+ currentPeriodStart?: number;
1351
+ currentPeriodEnd?: number;
1352
+ cancelAtPeriodEnd?: boolean;
1353
+ }
1354
+
1290
1355
  /** Content-free operator alert attached to an error report. Its shape is a subset of
1291
1356
  * the `ErrorReport` that `recordError` from `@odla-ai/o11y` accepts, so a host passes
1292
1357
  * that function straight through as `ChapterWorkerOptions.recordError`. */
@@ -1575,9 +1640,49 @@ type NamedSeatOperatorRefundInput = MembershipQuoteTarget & {
1575
1640
  */
1576
1641
  declare function refundNamedSeatByOperator(db: ChapterDb, input: NamedSeatOperatorRefundInput, stripeSecretKey: string, now: number): Promise<NamedSeatRefundReceipt>;
1577
1642
 
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. */
1643
+ /** Fence both absence of a collision and an audited resolution of this exact retained fact. */
1644
+ declare function commercialEvidenceGuard(db: ChapterDb, eventId: string, digest: unknown, code?: string): Promise<{
1645
+ ns: string;
1646
+ id: string;
1647
+ exists: boolean;
1648
+ equals?: undefined;
1649
+ } | {
1650
+ ns: string;
1651
+ id: string;
1652
+ exists: boolean;
1653
+ equals: {
1654
+ status: string;
1655
+ resolvedDigest: string;
1656
+ updatedAt: unknown;
1657
+ };
1658
+ }>;
1659
+
1660
+ type Row$4 = Record<string, unknown>;
1661
+ type EvidenceGuard = Awaited<ReturnType<typeof commercialEvidenceGuard>>;
1662
+ /** The seat's own standing on a membership dispute receipt, present when the disputed charge paid a named seat. */
1663
+ interface NamedSeatDisputeStanding {
1664
+ seatId: string;
1665
+ status: string;
1666
+ disputeStatus?: string;
1667
+ applied: boolean;
1668
+ }
1669
+ /** True when the disputed charge paid this seat: its own PaymentIntent, or an operator's re-issued one. A seat line on the
1670
+ * primary subscription's invoice is the primary's charge and is handled there. */
1671
+ declare function disputedChargeCoversSeat(charge: DisputedCharge, seat: Row$4): boolean;
1672
+ /** Apply one verified `charge.dispute.*` fact to the named seat whose payment it names. The primary membership is never
1673
+ * touched: the recipient loses access through the seat's status alone, and a won dispute restores exactly the seat
1674
+ * status the dispute interrupted. Idempotent per event. */
1675
+ declare function reconcileNamedSeatDispute(db: ChapterDb, input: MembershipQuoteTarget & {
1676
+ eventId: string;
1677
+ }, now: number, charge: DisputedCharge, evidence: {
1678
+ row: Row$4;
1679
+ fact: NetworkCommercialFact;
1680
+ guard: EvidenceGuard;
1681
+ }): Promise<MembershipDisputeReceipt>;
1682
+
1683
+ /** Status a membership or named seat holds while a card-network dispute has its payment pulled back. */
1580
1684
  declare const MEMBERSHIP_DISPUTED_STATUS = "payment_disputed";
1685
+
1581
1686
  /** The charge a dispute names, read from Stripe so a webhook body never chooses which membership it touches. */
1582
1687
  interface DisputedCharge {
1583
1688
  chargeId: string;
@@ -1585,20 +1690,22 @@ interface DisputedCharge {
1585
1690
  invoiceId?: string;
1586
1691
  subscriptionId?: string;
1587
1692
  paymentIntentId?: string;
1588
- /** Present when the charge paid a named seat; the primary membership is then not the disputed purchase. */
1693
+ /** Present when the charge paid a named seat's own PaymentIntent; the dispute is then the seat's, not the primary's. */
1589
1694
  seatId?: string;
1590
1695
  }
1591
1696
  /** Billing receipt plus the dispute's current standing and whether this event changed anything. */
1592
1697
  interface MembershipDisputeReceipt extends MembershipRenewalReceipt {
1593
1698
  disputeStatus?: string;
1594
1699
  applied: boolean;
1700
+ /** The seat's standing when the disputed charge paid a named seat; the membership fields are then unchanged. */
1701
+ seat?: NamedSeatDisputeStanding;
1595
1702
  }
1596
1703
  /** Resolve the disputed charge, and the subscription behind its invoice, with the network's own Stripe credential. */
1597
1704
  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. */
1705
+ /** Apply one verified `charge.dispute.*` fact to the membership it names, or to the named seat when the charge paid a
1706
+ * seat's own PaymentIntent. An open dispute suspends access; a won dispute restores the status it interrupted; a lost
1707
+ * one leaves the record suspended until an operator re-issues the charge. Idempotent per event, a closed dispute
1708
+ * outranks a late opening event, and a charge that is neither this membership's nor its seat's changes nothing. */
1602
1709
  declare function reconcileMembershipDispute(db: ChapterDb, input: MembershipQuoteTarget & {
1603
1710
  eventId: string;
1604
1711
  }, now: number, secretKey: string, resolved?: DisputedCharge): Promise<MembershipDisputeReceipt>;
@@ -1611,6 +1718,8 @@ interface MembershipRechargeReceipt {
1611
1718
  amountCents: number;
1612
1719
  currency: string;
1613
1720
  replayed?: true;
1721
+ /** Present when the re-issued charge paid a named seat; `membershipId` is then the seat's primary membership. */
1722
+ seatId?: string;
1614
1723
  }
1615
1724
  /** Stripe's final answer to a re-issued charge, with the decline code when the card refused it. */
1616
1725
  interface MembershipRechargeError extends Error {
@@ -1618,11 +1727,10 @@ interface MembershipRechargeError extends Error {
1618
1727
  declineCode?: string;
1619
1728
  paymentStatus?: string;
1620
1729
  }
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>;
1730
+ /** Re-issue a membership's lost dispute amount; see {@link rechargeDisputed}. */
1731
+ declare const rechargeDisputedMembership: (db: ChapterDb, membershipId: string, secretKey: string, now: number) => Promise<MembershipRechargeReceipt>;
1732
+ /** Re-issue a named seat's lost dispute amount on the purchaser's saved card; the primary membership is untouched. */
1733
+ declare const rechargeDisputedSeat: (db: ChapterDb, seatId: string, secretKey: string, now: number) => Promise<MembershipRechargeReceipt>;
1626
1734
 
1627
1735
  /** Seat states in which the purchaser may still name someone else: invited or accepted, never active, refunded or unpaid. */
1628
1736
  declare const REGIFTABLE_SEAT_STATUSES: readonly ["pending_acceptance", "pending_approval", "pending_primary"];
@@ -2397,4 +2505,4 @@ declare function chapterWorker(options: ChapterWorkerOptions): {
2397
2505
  }): Promise<Response>;
2398
2506
  };
2399
2507
 
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 };
2508
+ 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 NamedSeatDisputeStanding, 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, disputedChargeCoversSeat, drainMembershipEffects, grantIncludedNamedSeat, liftSeatPurchaseWindow, lowerSeatPrice, namedSeatIncluded, namedSeatInvitationOpen, namedSeatRecipientState, namedSeatRegiftable, readDisputedCharge, readNamedSeatOffer, rechargeDisputedMembership, rechargeDisputedSeat, reconcileMembershipDispute, reconcileNamedSeatDispute, refundNamedSeatByOperator, regiftNamedSeat, releaseNamedSeatRecipientApplications, renderActiveSignupControlHtml, resolveNetworkTargetTransport, resolveSignupEligibility, retermMembershipDiscount, retryChapterApprovalEffects, retryLeaderAdmissionDeliveries, withActiveSignupControlTheme };