Skip to content

feat(customers): surface active entitlements from simulate-purchase - #145

Merged
joshdholtz merged 2 commits into
mainfrom
dx-simulate-purchase-entitlements
Aug 25, 2026
Merged

feat(customers): surface active entitlements from simulate-purchase#145
joshdholtz merged 2 commits into
mainfrom
dx-simulate-purchase-entitlements

Conversation

@joshdholtz

@joshdholtz joshdholtz commented Aug 25, 2026

Copy link
Copy Markdown
Member

simulate-purchase returns the SDK /receipts customer_info — entitlements keyed by identifier — which is a different shape from customers show (v2, active_entitlements.items[] keyed by internal entitlement_id). An agent verifying a simulated purchase had to switch commands to confirm the entitlement was active.

This adds a derived active_entitlements field (list of active entitlement identifiers) to the simulate-purchase output, so the purchase is verifiable from the one command:

rc customers simulate-purchase --app-id app_x --product premium_monthly --app-user-id demo --json \
  | jq '.data.active_entitlements'   # ["premium"]

Active = expiry in the future, or none (lifetime). Best-effort parse of the stable /receipts shape; malformed entries are skipped, never falsely reported active. Raw customer_info is unchanged.

Note: this doesn't make the two commands byte-identical — they use different id systems (SDK lookup key vs v2 entitlement_id). Full cross-command entitlement-shape unification is a separate, larger API question.

🤖 Generated with Claude Code


Note

Low Risk
CLI-only output enrichment and local JSON parsing; no API or purchase flow changes.

Overview
simulate-purchase now includes a derived active_entitlements field (sorted SDK entitlement identifiers) alongside the unchanged raw customer_info, so scripts and agents can confirm a purchase granted access without running customers show.

The new activeEntitlementIDs helper parses the /receipts subscriber.entitlements map: an ID counts as active when expires_date is missing (lifetime) or parses as a future RFC3339 timestamp; expired, unparseable, or malformed payloads are skipped (empty slice, never null). Unit tests cover happy path and malformed JSON.

Reviewed by Cursor Bugbot for commit ca528de. Bugbot is set up for automated code reviews on this repo. Configure here.

simulate-purchase returns the SDK /receipts customer_info (entitlements keyed by
identifier), which differs from customers show's v2 shape — an agent had to
switch commands to verify a purchase granted access. Add a derived
active_entitlements list (active identifiers) to the output so the purchase is
verifiable from the one command. Best-effort parse; malformed entries skipped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 25, 2026 02:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment thread internal/cli/customers.go
A nil slice serialized to `null` under --json, breaking `jq` pipelines that
expect an array. Initialize to an empty slice and return it on the parse-error
path too. Locks it with a marshal assertion.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@joshdholtz
joshdholtz requested review from a team and fire-at-will August 25, 2026 15:02

@fire-at-will fire-at-will left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚢

@joshdholtz

Copy link
Copy Markdown
Member Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit ca528de. Configure here.

@joshdholtz
joshdholtz merged commit 67e32d9 into main Aug 25, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants