@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.
package/README.md CHANGED
@@ -1835,8 +1835,20 @@ These bite silently — a smoke test won't catch them:
1835
1835
  `MembershipDisputes` from `@odla-ai/chapter/ui/admin`: re-charging collects
1836
1836
  the lost amount again on the member's saved card, off-session and only on the
1837
1837
  operator's confirmed click, with one idempotency key kept on the row until
1838
- Stripe answers so a lost response never charges twice. A seat's own charge or
1839
- another customer's never touches the primary membership.
1838
+ Stripe answers so a lost response never charges twice. Another customer's
1839
+ charge never touches the membership.
1840
+
1841
+ A named seat's own PaymentIntent is the seat's dispute (Chapter 0.59.1): the
1842
+ same facts suspend only the `networkSeat` (`payment_disputed`, the prior
1843
+ seat status remembered, recipient state `disputed`), so the recipient loses
1844
+ access while the purchaser's membership stays as it was; won restores the
1845
+ seat, lost waits for the operator. The disputes list tags each row with
1846
+ `kind` (`membership` or `seat`, with the recipient's name), and a `seat_…`
1847
+ id on the re-charge route collects the seat amount again on the purchaser's
1848
+ saved card. A seat line billed on the primary subscription's invoice is the
1849
+ primary's charge and follows the membership rules above. Re-provision the
1850
+ authority schema: the seat row gains the same optional `dispute*` and
1851
+ `recharge*` attributes.
1840
1852
 
1841
1853
  Starting with Chapter 0.55.0, a named-seat-enabled `JoinIsland` also offers the
1842
1854
  additional member in the initial payment step. Both journeys read
@@ -3602,12 +3602,17 @@ var DISPUTE_STATUS_WORDS = {
3602
3602
  recharged: "re-charged"
3603
3603
  };
3604
3604
  var columns3 = (begin, busy) => [
3605
- { key: "member", header: "Member", cell: (row) => /* @__PURE__ */ jsxs34("span", { children: [
3605
+ { key: "member", header: "Member", cell: (row) => row.kind === "seat" ? /* @__PURE__ */ jsxs34("span", { children: [
3606
+ "Seat for ",
3607
+ row.recipientName ?? "the named recipient",
3608
+ " \xB7 ",
3609
+ /* @__PURE__ */ jsx38("code", { children: row.applicationId })
3610
+ ] }) : /* @__PURE__ */ jsxs34("span", { children: [
3606
3611
  row.memberNumber ? `#${row.memberNumber} \xB7 ` : "",
3607
3612
  /* @__PURE__ */ jsx38("code", { children: row.applicationId })
3608
3613
  ] }) },
3609
3614
  { key: "chapter", header: "Chapter / runtime", cell: (row) => `${row.chapterId} / ${row.runtime}` },
3610
- { key: "status", header: "Membership", cell: (row) => row.status === "payment_disputed" ? "suspended by dispute" : row.status },
3615
+ { key: "status", header: "Record", cell: (row) => row.status === "payment_disputed" ? `${row.kind === "seat" ? "seat" : "membership"} suspended by dispute` : row.status },
3611
3616
  { key: "dispute", header: "Dispute", cell: (row) => /* @__PURE__ */ jsxs34("span", { children: [
3612
3617
  DISPUTE_STATUS_WORDS[row.disputeStatus] ?? row.disputeStatus,
3613
3618
  row.disputeReason ? ` \xB7 ${row.disputeReason}` : ""
@@ -3636,7 +3641,8 @@ function MembershipDisputes(props) {
3636
3641
  `/api/admin/membership-disputes/${encodeURIComponent(row.id)}/recharge`,
3637
3642
  { method: "POST" }
3638
3643
  );
3639
- setNote(receipt.replayed ? `Membership ${row.applicationId} was already re-charged (${receipt.paymentIntentId}).` : `Collected ${money4(row, receipt.amountCents)} again for ${row.applicationId}; the membership is ${receipt.status}.`);
3644
+ const what = row.kind === "seat" ? `the seat for ${row.recipientName ?? "the recipient"}` : `membership ${row.applicationId}`;
3645
+ setNote(receipt.replayed ? `${what} was already re-charged (${receipt.paymentIntentId}).` : `Collected ${money4(row, receipt.amountCents)} again for ${what}; it is ${receipt.status}.`);
3640
3646
  refresh();
3641
3647
  } catch (failure) {
3642
3648
  setNote(failure instanceof Error ? failure.message : "The charge could not be re-issued.");
@@ -3657,7 +3663,7 @@ function MembershipDisputes(props) {
3657
3663
  "Charge ",
3658
3664
  money4(confirming, confirming.disputeAmountCents ?? confirming.amountCents),
3659
3665
  " again to the card on file for ",
3660
- confirming.applicationId,
3666
+ confirming.kind === "seat" ? `the seat for ${confirming.recipientName ?? "the recipient"}` : confirming.applicationId,
3661
3667
  "?"
3662
3668
  ] }),
3663
3669
  /* @__PURE__ */ jsx38(Button20, { mini: true, onClick: () => void recharge(confirming), children: "Yes, charge the card" }),
@@ -3869,4 +3875,4 @@ export {
3869
3875
  MembershipDisputes,
3870
3876
  MembershipPolicyVersions
3871
3877
  };
3872
- //# sourceMappingURL=chunk-WFTWT3V7.js.map
3878
+ //# sourceMappingURL=chunk-P6X3W2XP.js.map