v0.3.0 — entitlements catalog in PublicPoliciesResponse
Mirrors keysat 0014 + TS/Rust SDK 0.3.0. PublicPoliciesProduct gains entitlements_catalog: list[EntitlementDef] with slug + name + description. SDK consumers' in-app tier pickers can render display names + tooltip descriptions instead of raw slugs. Empty list on legacy products without a catalog. No breaking change.
This commit is contained in:
@@ -67,6 +67,7 @@ try:
|
||||
ValidateResponse,
|
||||
ValidateOptions,
|
||||
StartPurchaseOptions,
|
||||
EntitlementDef,
|
||||
PublicPolicy,
|
||||
PublicPoliciesProduct,
|
||||
PublicPoliciesResponse,
|
||||
@@ -81,6 +82,7 @@ try:
|
||||
"ValidateResponse",
|
||||
"ValidateOptions",
|
||||
"StartPurchaseOptions",
|
||||
"EntitlementDef",
|
||||
"PublicPolicy",
|
||||
"PublicPoliciesProduct",
|
||||
"PublicPoliciesResponse",
|
||||
@@ -93,4 +95,4 @@ except ImportError:
|
||||
# httpx not installed — that's fine, online client is optional.
|
||||
pass
|
||||
|
||||
__version__ = "0.2.0"
|
||||
__version__ = "0.3.0"
|
||||
|
||||
@@ -89,12 +89,27 @@ class PublicPolicy:
|
||||
trial_days: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class EntitlementDef:
|
||||
"""One entry in a product's entitlements catalog (Keysat
|
||||
migration 0014). Operator declares the closed list once per
|
||||
product; policies pick from this list. Use ``name`` as the
|
||||
human-readable label when rendering an in-app tier picker
|
||||
(e.g. "AI summaries" instead of the raw ``ai_summaries`` slug).
|
||||
"""
|
||||
|
||||
slug: str
|
||||
name: str
|
||||
description: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class PublicPoliciesProduct:
|
||||
slug: str
|
||||
name: str
|
||||
description: str
|
||||
base_price_sats: int
|
||||
entitlements_catalog: list[EntitlementDef]
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -277,12 +292,21 @@ class Client:
|
||||
raw = self._get(f"/v1/products/{product_slug}/policies")
|
||||
product = raw.get("product", {}) or {}
|
||||
policies_raw = raw.get("policies") or []
|
||||
catalog_raw = product.get("entitlements_catalog") or []
|
||||
return PublicPoliciesResponse(
|
||||
product=PublicPoliciesProduct(
|
||||
slug=product.get("slug", ""),
|
||||
name=product.get("name", ""),
|
||||
description=product.get("description", "") or "",
|
||||
base_price_sats=int(product.get("base_price_sats", 0)),
|
||||
entitlements_catalog=[
|
||||
EntitlementDef(
|
||||
slug=c.get("slug", ""),
|
||||
name=c.get("name", "") or c.get("slug", ""),
|
||||
description=c.get("description", "") or "",
|
||||
)
|
||||
for c in catalog_raw
|
||||
],
|
||||
),
|
||||
policies=[
|
||||
PublicPolicy(
|
||||
|
||||
Reference in New Issue
Block a user