@revturbine/cli 0.16.2 → 0.16.4
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/dist/cli.js +628 -375
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -18,8 +18,8 @@ import { z as z5 } from "zod";
|
|
|
18
18
|
import { z as z4 } from "zod";
|
|
19
19
|
import { z as z6 } from "zod";
|
|
20
20
|
import { z as z7 } from "zod";
|
|
21
|
-
import { z as z8 } from "zod";
|
|
22
21
|
import { z as z9 } from "zod";
|
|
22
|
+
import { z as z8 } from "zod";
|
|
23
23
|
import { z as z10 } from "zod";
|
|
24
24
|
import { z as z11 } from "zod";
|
|
25
25
|
import { z as z12 } from "zod";
|
|
@@ -51,7 +51,12 @@ var DataClassification = {
|
|
|
51
51
|
Financial: { "x-revturbine-data-classification": "financial" },
|
|
52
52
|
Unrestricted: { "x-revturbine-data-classification": "unrestricted" }
|
|
53
53
|
};
|
|
54
|
+
var SCHEMA_EXPOSURE_META_KEY = "x-revturbine-schema-exposure";
|
|
54
55
|
var READ_ONLY_META_KEY = "readOnly";
|
|
56
|
+
var DECISION_ONLY_META_KEY = "x-revturbine-decision-only";
|
|
57
|
+
var DecisionOnly = { [DECISION_ONLY_META_KEY]: true };
|
|
58
|
+
var ClientSafe = { [SCHEMA_EXPOSURE_META_KEY]: SchemaExposure.External };
|
|
59
|
+
var ServerOnly = { [SCHEMA_EXPOSURE_META_KEY]: SchemaExposure.Internal };
|
|
55
60
|
function toWritableSchema(schema) {
|
|
56
61
|
const writableShape = {};
|
|
57
62
|
for (const [fieldName, fieldSchema] of Object.entries(schema.shape)) {
|
|
@@ -1334,6 +1339,9 @@ var PlacementPayloadSchema = IdField.merge(TimestampFields).merge(TenantIdField)
|
|
|
1334
1339
|
max_per_period: z7.number().int().min(0).nullable().default(null).meta(Unrestricted4),
|
|
1335
1340
|
max_period_unit: CapPeriodSchema.default("session").meta(Unrestricted4),
|
|
1336
1341
|
cooldown_after_dismiss_days: z7.number().int().min(0).default(7).meta(Unrestricted4),
|
|
1342
|
+
// Per-payload remind-me-later (defer) window override, in minutes. Null =
|
|
1343
|
+
// inherit the tenant default (`remindLaterMinutes`, 60). Plan 167 REQ-6 / Q-3.
|
|
1344
|
+
remind_later_minutes: z7.number().int().min(0).nullable().default(null).meta(Unrestricted4),
|
|
1337
1345
|
recommendation_strategy: z7.enum(["next_tier_up", "best_value", "custom"]).optional().default("next_tier_up").meta(Unrestricted4),
|
|
1338
1346
|
recommendation_plan_override: z7.string().optional().meta(Unrestricted4)
|
|
1339
1347
|
}).meta(
|
|
@@ -1532,256 +1540,72 @@ var placementPaths = {
|
|
|
1532
1540
|
};
|
|
1533
1541
|
var { Unrestricted: Unrestricted5, Pii } = DataClassification;
|
|
1534
1542
|
var { Persisted: Persisted5, Transient: Transient5 } = SchemaPersistence;
|
|
1535
|
-
var { External: External5 } = SchemaExposure;
|
|
1536
|
-
var UserTrialStatusSchema = z8.object({
|
|
1537
|
-
in_trial: z8.boolean().meta(Unrestricted5),
|
|
1538
|
-
trial_type: z8.string().optional().meta(Unrestricted5),
|
|
1539
|
-
plan_handle: z8.string().optional().meta(Unrestricted5),
|
|
1540
|
-
// 'converted' reflects a server-side analytic-event transition
|
|
1541
|
-
// (typically a Stripe webhook like `customer.subscription.created`
|
|
1542
|
-
// or `invoice.payment_succeeded` against a trialing subscription)
|
|
1543
|
-
// that the control plane processes to flip TrialInstance.status.
|
|
1544
|
-
// The SDK reads this state from the decision-API response — it does
|
|
1545
|
-
// NOT derive 'converted' client-side. trial_lifecycle.v1 rules
|
|
1546
|
-
// matching on 'trial_converted' fire while the user's status carries
|
|
1547
|
-
// this value, enabling conversion-celebration / receipt placements.
|
|
1548
|
-
state: z8.enum(["active", "running_out", "expired", "converted", "none"]).optional().meta(Unrestricted5),
|
|
1549
|
-
/**
|
|
1550
|
-
* Trial limit model — mirrors the rule's `trial_limit_type`. The
|
|
1551
|
-
* SDK uses this to decide which numeric fields below to surface;
|
|
1552
|
-
* the placement-resolver gates `trial_ending(days_before_end)`
|
|
1553
|
-
* only when `trial_limit_type === 'time'`.
|
|
1554
|
-
*/
|
|
1555
|
-
trial_limit_type: z8.enum(["time", "usage"]).optional().meta(Unrestricted5),
|
|
1556
|
-
/**
|
|
1557
|
-
* Universal progress metric, 0..100. Computed by
|
|
1558
|
-
* `deriveLocalTrialStatusFromInstance` from elapsed days
|
|
1559
|
-
* (time-based) or consumed/limit (usage-based). Trial rule
|
|
1560
|
-
* modules + placement-resolver supersession consume this field
|
|
1561
|
-
* so they don't have to branch on the limit type.
|
|
1562
|
-
*/
|
|
1563
|
-
progress_percent: z8.number().min(0).max(100).optional().meta(Unrestricted5),
|
|
1564
|
-
// Time-based numeric fields. Populated when trial_limit_type='time'.
|
|
1565
|
-
day_number: z8.number().int().min(0).optional().meta(Unrestricted5),
|
|
1566
|
-
days_remaining: z8.number().int().min(0).optional().meta(Unrestricted5),
|
|
1567
|
-
// Usage-based numeric fields. Populated when trial_limit_type='usage'.
|
|
1568
|
-
usage_entitlement_handle: z8.string().optional().meta(Unrestricted5),
|
|
1569
|
-
usage_consumed: z8.number().int().min(0).optional().meta(Unrestricted5),
|
|
1570
|
-
usage_remaining: z8.number().int().min(0).optional().meta(Unrestricted5),
|
|
1571
|
-
usage_limit: z8.number().int().min(0).optional().meta(Unrestricted5)
|
|
1572
|
-
}).meta(
|
|
1573
|
-
{ id: "UserTrialStatus", "x-revturbine-schema-persistence": Transient5, "x-revturbine-schema-exposure": External5 }
|
|
1574
|
-
);
|
|
1575
|
-
var UserUsageEntrySchema = z8.object({
|
|
1576
|
-
entitlement_handle: z8.string().min(1).meta(Unrestricted5),
|
|
1577
|
-
unit: z8.string().min(1).meta(Unrestricted5),
|
|
1578
|
-
amount: z8.number().min(0).meta(Unrestricted5),
|
|
1579
|
-
limit: z8.number().min(0).optional().meta(Unrestricted5),
|
|
1580
|
-
reset_date: z8.string().optional().meta(Unrestricted5)
|
|
1581
|
-
}).meta(
|
|
1582
|
-
{ id: "UserUsageEntry", "x-revturbine-schema-persistence": Transient5, "x-revturbine-schema-exposure": External5 }
|
|
1583
|
-
);
|
|
1584
|
-
var UserPlanContextSchema = z8.object({
|
|
1585
|
-
id: z8.string().min(1).meta(Unrestricted5),
|
|
1586
|
-
name: z8.string().min(1).meta(Unrestricted5),
|
|
1587
|
-
price: z8.string().optional().meta(Unrestricted5),
|
|
1588
|
-
billing_period: z8.enum(["monthly", "annual", "none"]).optional().meta(Unrestricted5)
|
|
1589
|
-
}).meta(
|
|
1590
|
-
{ id: "UserPlanContext", "x-revturbine-schema-persistence": Transient5, "x-revturbine-schema-exposure": External5 }
|
|
1591
|
-
);
|
|
1592
|
-
var UserInstanceContextSchema = z8.object({
|
|
1593
|
-
product_instance_id: z8.string().min(1).meta(Unrestricted5),
|
|
1594
|
-
user_id: z8.string().min(1).meta(Pii),
|
|
1595
|
-
plan: UserPlanContextSchema.optional().meta(Unrestricted5),
|
|
1596
|
-
/** Usage entries for this instance, keyed by entitlement handle. */
|
|
1597
|
-
usage: z8.record(z8.string(), UserUsageEntrySchema).default({}).meta(Unrestricted5),
|
|
1598
|
-
trial: UserTrialStatusSchema.optional().meta(Unrestricted5),
|
|
1599
|
-
/** Entitlements resolved at this instance level, keyed by handle. */
|
|
1600
|
-
entitlements: z8.record(z8.string(), z8.union([z8.boolean(), EntitlementGrantSchema])).default({}).meta(Unrestricted5)
|
|
1601
|
-
}).meta(
|
|
1602
|
-
{
|
|
1603
|
-
id: "UserInstanceContext",
|
|
1604
|
-
"x-revturbine-schema-persistence": Persisted5,
|
|
1605
|
-
"x-revturbine-schema-exposure": External5
|
|
1606
|
-
}
|
|
1607
|
-
);
|
|
1608
|
-
var UserContextSchema = IdField.merge(TenantIdField).merge(TimestampFields).extend({
|
|
1609
|
-
user_id: z8.string().min(1).meta(Pii),
|
|
1610
|
-
account_id: z8.string().min(1).nullable().optional().meta(Pii),
|
|
1611
|
-
email: z8.string().email().nullable().optional().meta(Pii),
|
|
1612
|
-
/** Optional email classification (e.g. `business`, `personal`). */
|
|
1613
|
-
email_type: z8.string().optional().meta(Unrestricted5),
|
|
1614
|
-
plan: UserPlanContextSchema.optional().meta(Unrestricted5),
|
|
1615
|
-
/** Aggregate usage entries across all instances, keyed by handle. */
|
|
1616
|
-
usage: z8.record(z8.string(), UserUsageEntrySchema).default({}).meta(Unrestricted5),
|
|
1617
|
-
trial: UserTrialStatusSchema.optional().meta(Unrestricted5),
|
|
1618
|
-
/**
|
|
1619
|
-
* Billing-recovery signals (account-level). `payment_failed` reflects a
|
|
1620
|
-
* hard payment failure (e.g. Stripe `invoice.payment_failed`);
|
|
1621
|
-
* `payment_at_risk` an expiring / missing-backup payment method. They
|
|
1622
|
-
* drive the Retention `qualifier` placement triggers
|
|
1623
|
-
* (placement-studio-ui.md §3.7) — the SDK surfaces them onto the
|
|
1624
|
-
* PlanProvider state the placement resolver reads. Omitted for users in
|
|
1625
|
-
* good standing; a qualifier gate reads `=== true`, so an absent signal
|
|
1626
|
-
* never fires the recovery placement.
|
|
1627
|
-
*/
|
|
1628
|
-
payment_failed: z8.boolean().optional().meta(Unrestricted5),
|
|
1629
|
-
payment_at_risk: z8.boolean().optional().meta(Unrestricted5),
|
|
1630
|
-
/**
|
|
1631
|
-
* The user's current tier per `capability_tier` entitlement, keyed by
|
|
1632
|
-
* entitlement handle → tier handle (plan 138 TASK-4). Drives the
|
|
1633
|
-
* `entitlement_gate.tier_threshold` placement trigger: the SDK surfaces
|
|
1634
|
-
* this onto the EntitlementProvider state, and the resolver ranks the
|
|
1635
|
-
* current tier against the entitlement's ordered ladder. Omitted for a
|
|
1636
|
-
* user holding no tier (ranks below every threshold).
|
|
1637
|
-
*/
|
|
1638
|
-
tiers: z8.record(z8.string(), z8.string()).optional().meta(Unrestricted5),
|
|
1639
|
-
/** Account-level entitlements, keyed by handle. */
|
|
1640
|
-
entitlements: z8.record(z8.string(), z8.union([z8.boolean(), EntitlementGrantSchema])).default({}).meta(Unrestricted5),
|
|
1641
|
-
/** Per-instance breakdowns when the account has multiple product instances. */
|
|
1642
|
-
instances: z8.array(UserInstanceContextSchema).optional().meta(Unrestricted5),
|
|
1643
|
-
/** Customer-defined fields: role, app-level permissions, display prefs. */
|
|
1644
|
-
custom: z8.record(z8.string(), z8.union([z8.string(), z8.number(), z8.boolean(), z8.null()])).default({}).meta(Pii),
|
|
1645
|
-
/**
|
|
1646
|
-
* Transient personalization token map.
|
|
1647
|
-
*
|
|
1648
|
-
* Holds SDK-derived tokens (plan_name, usage_current, etc.) merged with
|
|
1649
|
-
* app-provided tokens. Not persisted to the backend — rebuilt on each
|
|
1650
|
-
* SDK session from context + exported config.
|
|
1651
|
-
*/
|
|
1652
|
-
personalization: z8.record(z8.string(), z8.union([z8.string(), z8.number()])).default({}).meta({ ...Unrestricted5, "x-revturbine-schema-persistence": Transient5 }),
|
|
1653
|
-
// ── Derived-entitlement cache (plan 74 REQ-12/REQ-13) ──────────────
|
|
1654
|
-
// `entitlements` above is the rule-evaluated projection — a CACHE, not
|
|
1655
|
-
// source of truth. These stamps record what it was computed against so a
|
|
1656
|
-
// read can detect staleness: recompute when the active config version
|
|
1657
|
-
// moved on OR the context hash changed.
|
|
1658
|
-
/** Active config version (activated change-set id / compiled-bundle stamp) the cache was computed against. */
|
|
1659
|
-
derived_config_version: z8.string().nullable().optional().meta(Unrestricted5),
|
|
1660
|
-
/** Deterministic `computeUserContextHash` of the inputs the cache was computed from (REQ-13 ETag value). */
|
|
1661
|
-
context_hash: z8.string().nullable().optional().meta(Unrestricted5),
|
|
1662
|
-
/** When the cached entitlements were last (re)computed. */
|
|
1663
|
-
derived_computed_at: NullableDatetimeField.meta(Unrestricted5)
|
|
1664
|
-
}).meta(
|
|
1665
|
-
{ id: "UserContext", "x-revturbine-schema-persistence": Persisted5, "x-revturbine-schema-exposure": External5 }
|
|
1666
|
-
);
|
|
1667
|
-
var userContextPaths = {
|
|
1668
|
-
"/api/user-contexts": {
|
|
1669
|
-
get: operation({
|
|
1670
|
-
operationId: "listUserContexts",
|
|
1671
|
-
requestParams: { query: ListQueryParamsSchema },
|
|
1672
|
-
summary: "List user contexts",
|
|
1673
|
-
tags: ["users"],
|
|
1674
|
-
responses: { "200": { description: "User context list", content: { "application/json": { schema: ListEnvelope(UserContextSchema) } } } },
|
|
1675
|
-
"x-revturbine-operation": { exposure: "internal", resource: "user-contexts", persistence: { table: "userContexts", mode: "list" } }
|
|
1676
|
-
}),
|
|
1677
|
-
// Upsert by (tenant_id, user_id): the SDK identify/setUserContext path
|
|
1678
|
-
// writes the persisted context. The collection POST is the create-or-update
|
|
1679
|
-
// entry point — the route resolves the existing row by (tenant_id, user_id)
|
|
1680
|
-
// and applies an idempotent upsert (server-side, plan 74 TASK-4).
|
|
1681
|
-
post: operation({
|
|
1682
|
-
operationId: "createUserContext",
|
|
1683
|
-
summary: "Create or upsert a user context",
|
|
1684
|
-
tags: ["users"],
|
|
1685
|
-
requestBody: { required: true, content: { "application/json": { schema: UserContextSchema } } },
|
|
1686
|
-
responses: { "201": { description: "Created", content: { "application/json": { schema: UserContextSchema } } } },
|
|
1687
|
-
"x-revturbine-operation": { exposure: "internal", resource: "user-contexts", persistence: { table: "userContexts", mode: "create" } }
|
|
1688
|
-
})
|
|
1689
|
-
},
|
|
1690
|
-
"/api/user-contexts/{userContextId}": {
|
|
1691
|
-
get: operation({
|
|
1692
|
-
operationId: "getUserContext",
|
|
1693
|
-
requestParams: { path: z8.object({ userContextId: z8.string() }) },
|
|
1694
|
-
summary: "Get user context",
|
|
1695
|
-
tags: ["users"],
|
|
1696
|
-
responses: { "200": { description: "User context", content: { "application/json": { schema: UserContextSchema } } } },
|
|
1697
|
-
"x-revturbine-operation": { exposure: "internal", resource: "user-contexts", persistence: { table: "userContexts", mode: "get" } }
|
|
1698
|
-
}),
|
|
1699
|
-
patch: operation({
|
|
1700
|
-
operationId: "updateUserContext",
|
|
1701
|
-
requestParams: { path: z8.object({ userContextId: z8.string() }) },
|
|
1702
|
-
summary: "Update a user context",
|
|
1703
|
-
tags: ["users"],
|
|
1704
|
-
requestBody: { required: true, content: { "application/json": { schema: UserContextSchema.partial() } } },
|
|
1705
|
-
responses: { "200": { description: "Updated", content: { "application/json": { schema: UserContextSchema } } } },
|
|
1706
|
-
"x-revturbine-operation": { exposure: "internal", resource: "user-contexts", persistence: { table: "userContexts", mode: "update" } }
|
|
1707
|
-
}),
|
|
1708
|
-
// Delete path ships in v1 (plan 74 Q-1): a user context can be removed on
|
|
1709
|
-
// request now; full by-email DSR tooling remains deferred (sdk.md §8).
|
|
1710
|
-
delete: operation({
|
|
1711
|
-
operationId: "deleteUserContext",
|
|
1712
|
-
requestParams: { path: z8.object({ userContextId: z8.string() }) },
|
|
1713
|
-
summary: "Delete a user context",
|
|
1714
|
-
tags: ["users"],
|
|
1715
|
-
responses: { "204": { description: "Deleted" } },
|
|
1716
|
-
"x-revturbine-operation": { exposure: "internal", resource: "user-contexts", persistence: { table: "userContexts", mode: "delete" } }
|
|
1717
|
-
})
|
|
1718
|
-
}
|
|
1719
|
-
};
|
|
1720
|
-
var { Unrestricted: Unrestricted6, Pii: Pii2 } = DataClassification;
|
|
1721
|
-
var { Persisted: Persisted6, Transient: Transient6 } = SchemaPersistence;
|
|
1722
1543
|
var { Internal: Internal4 } = SchemaExposure;
|
|
1723
1544
|
var CUSTOMER_OPERATIONS_FACETS = schemaFacets(SchemaContext.CustomerOperations, {
|
|
1724
1545
|
sdkInput: false
|
|
1725
1546
|
});
|
|
1726
|
-
var IdentitySchema =
|
|
1727
|
-
external_id:
|
|
1728
|
-
traits:
|
|
1729
|
-
plan_id:
|
|
1547
|
+
var IdentitySchema = z8.object({
|
|
1548
|
+
external_id: z8.string().min(1).meta(Pii),
|
|
1549
|
+
traits: z8.record(z8.string(), z8.unknown()).default({}).meta(Pii),
|
|
1550
|
+
plan_id: z8.string().optional().meta(Unrestricted5)
|
|
1730
1551
|
}).meta(
|
|
1731
1552
|
{
|
|
1732
1553
|
id: "Identity",
|
|
1733
|
-
"x-revturbine-schema-persistence":
|
|
1554
|
+
"x-revturbine-schema-persistence": Persisted5,
|
|
1734
1555
|
"x-revturbine-schema-exposure": Internal4
|
|
1735
1556
|
}
|
|
1736
1557
|
);
|
|
1558
|
+
var BillingHealthStatusSchema = z8.enum(["payment_failed", "payment_method_missing"]);
|
|
1737
1559
|
var CustomerSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
1738
|
-
external_id:
|
|
1739
|
-
identity: IdentitySchema.meta(
|
|
1740
|
-
stripe_customer_id:
|
|
1741
|
-
current_plan_id:
|
|
1742
|
-
subscription_status:
|
|
1743
|
-
status:
|
|
1744
|
-
|
|
1560
|
+
external_id: z8.string().min(1).meta(Pii),
|
|
1561
|
+
identity: IdentitySchema.meta(Pii),
|
|
1562
|
+
stripe_customer_id: z8.string().optional().meta(Unrestricted5),
|
|
1563
|
+
current_plan_id: z8.string().optional().meta(Unrestricted5),
|
|
1564
|
+
subscription_status: z8.enum(["active", "past_due", "canceled", "trialing", "unpaid", "none"]).default("none").meta(Unrestricted5),
|
|
1565
|
+
status: z8.enum(["active", "churned", "trial", "suspended"]).default("active").meta(Unrestricted5),
|
|
1566
|
+
/** Active billing-health problems (plan 156); empty array = healthy. */
|
|
1567
|
+
billing_health_issues: z8.array(BillingHealthStatusSchema).default([]).meta(Unrestricted5),
|
|
1568
|
+
metadata: MetadataField.meta(Unrestricted5)
|
|
1745
1569
|
}).meta(
|
|
1746
1570
|
{
|
|
1747
1571
|
id: "Customer",
|
|
1748
|
-
"x-revturbine-schema-persistence":
|
|
1572
|
+
"x-revturbine-schema-persistence": Persisted5,
|
|
1749
1573
|
"x-revturbine-schema-exposure": Internal4
|
|
1750
1574
|
}
|
|
1751
1575
|
);
|
|
1752
|
-
var CustomerOverrideDurationSchema =
|
|
1576
|
+
var CustomerOverrideDurationSchema = z8.enum([
|
|
1753
1577
|
"permanent",
|
|
1754
1578
|
"for_duration"
|
|
1755
1579
|
]).meta(
|
|
1756
1580
|
{
|
|
1757
1581
|
id: "CustomerOverrideDuration",
|
|
1758
|
-
"x-revturbine-schema-persistence":
|
|
1582
|
+
"x-revturbine-schema-persistence": Transient5,
|
|
1759
1583
|
"x-revturbine-schema-exposure": Internal4
|
|
1760
1584
|
}
|
|
1761
1585
|
);
|
|
1762
|
-
var CustomerOverrideTypeSchema =
|
|
1763
|
-
{ id: "CustomerOverrideType", "x-revturbine-schema-persistence":
|
|
1586
|
+
var CustomerOverrideTypeSchema = z8.enum(["grant_plan", "grant_addon", "grant_entitlement"]).meta(
|
|
1587
|
+
{ id: "CustomerOverrideType", "x-revturbine-schema-persistence": Transient5, "x-revturbine-schema-exposure": Internal4 }
|
|
1764
1588
|
);
|
|
1765
|
-
var CustomerOverrideStatusSchema =
|
|
1766
|
-
{ id: "CustomerOverrideStatus", "x-revturbine-schema-persistence":
|
|
1589
|
+
var CustomerOverrideStatusSchema = z8.enum(["active", "expired", "revoked"]).meta(
|
|
1590
|
+
{ id: "CustomerOverrideStatus", "x-revturbine-schema-persistence": Transient5, "x-revturbine-schema-exposure": Internal4 }
|
|
1767
1591
|
);
|
|
1768
1592
|
var CustomerOverrideSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(AnchorFields).merge(VersionFields).extend({
|
|
1769
|
-
handle: HandleField.meta({ ...
|
|
1770
|
-
customer_id:
|
|
1771
|
-
customer_id_list:
|
|
1772
|
-
override_type: CustomerOverrideTypeSchema.meta(
|
|
1773
|
-
target_id:
|
|
1774
|
-
value:
|
|
1775
|
-
duration_type: CustomerOverrideDurationSchema.default("permanent").meta(
|
|
1776
|
-
duration_value:
|
|
1777
|
-
expiry_date: NullableDatetimeField.meta(
|
|
1778
|
-
status: CustomerOverrideStatusSchema.default("active").meta(
|
|
1779
|
-
reason:
|
|
1780
|
-
created_by:
|
|
1593
|
+
handle: HandleField.meta({ ...Unrestricted5, readOnly: true }),
|
|
1594
|
+
customer_id: z8.string().min(1).meta(Pii),
|
|
1595
|
+
customer_id_list: z8.array(z8.string()).optional().meta(Pii),
|
|
1596
|
+
override_type: CustomerOverrideTypeSchema.meta(Unrestricted5),
|
|
1597
|
+
target_id: z8.string().min(1).meta(Unrestricted5),
|
|
1598
|
+
value: z8.record(z8.string(), z8.unknown()).default({}).meta(Unrestricted5),
|
|
1599
|
+
duration_type: CustomerOverrideDurationSchema.default("permanent").meta(Unrestricted5),
|
|
1600
|
+
duration_value: z8.string().optional().meta(Unrestricted5),
|
|
1601
|
+
expiry_date: NullableDatetimeField.meta(Unrestricted5),
|
|
1602
|
+
status: CustomerOverrideStatusSchema.default("active").meta(Unrestricted5),
|
|
1603
|
+
reason: z8.string().max(500).optional().meta(Unrestricted5),
|
|
1604
|
+
created_by: z8.string().optional().meta(Unrestricted5)
|
|
1781
1605
|
}).meta(
|
|
1782
1606
|
{
|
|
1783
1607
|
id: "CustomerOverride",
|
|
1784
|
-
"x-revturbine-schema-persistence":
|
|
1608
|
+
"x-revturbine-schema-persistence": Persisted5,
|
|
1785
1609
|
"x-revturbine-schema-exposure": Internal4,
|
|
1786
1610
|
...CUSTOMER_OPERATIONS_FACETS,
|
|
1787
1611
|
// KENT-REVIEW (plan 121): defaulted to Bucket 2 on (customer_id, override_type,
|
|
@@ -1805,7 +1629,7 @@ var customerPaths = {
|
|
|
1805
1629
|
"/api/customers/{customerId}": {
|
|
1806
1630
|
get: operation({
|
|
1807
1631
|
operationId: "getCustomer",
|
|
1808
|
-
requestParams: { path:
|
|
1632
|
+
requestParams: { path: z8.object({ customerId: z8.string() }) },
|
|
1809
1633
|
summary: "Get customer by ID",
|
|
1810
1634
|
tags: ["customers"],
|
|
1811
1635
|
responses: { "200": { description: "Customer", content: { "application/json": { schema: CustomerSchema } } } },
|
|
@@ -1833,7 +1657,7 @@ var customerPaths = {
|
|
|
1833
1657
|
"/api/customer-overrides/{overrideId}": {
|
|
1834
1658
|
get: operation({
|
|
1835
1659
|
operationId: "getCustomerOverride",
|
|
1836
|
-
requestParams: { path:
|
|
1660
|
+
requestParams: { path: z8.object({ overrideId: z8.string() }) },
|
|
1837
1661
|
summary: "Get customer override",
|
|
1838
1662
|
tags: ["customers"],
|
|
1839
1663
|
responses: { "200": { description: "Override", content: { "application/json": { schema: CustomerOverrideSchema } } } },
|
|
@@ -1841,7 +1665,7 @@ var customerPaths = {
|
|
|
1841
1665
|
}),
|
|
1842
1666
|
patch: operation({
|
|
1843
1667
|
operationId: "updateCustomerOverride",
|
|
1844
|
-
requestParams: { path:
|
|
1668
|
+
requestParams: { path: z8.object({ overrideId: z8.string() }) },
|
|
1845
1669
|
summary: "Update customer override",
|
|
1846
1670
|
tags: ["customers"],
|
|
1847
1671
|
requestBody: { required: true, content: { "application/json": { schema: CustomerOverrideSchema.partial() } } },
|
|
@@ -1850,7 +1674,7 @@ var customerPaths = {
|
|
|
1850
1674
|
}),
|
|
1851
1675
|
delete: operation({
|
|
1852
1676
|
operationId: "deleteCustomerOverride",
|
|
1853
|
-
requestParams: { path:
|
|
1677
|
+
requestParams: { path: z8.object({ overrideId: z8.string() }) },
|
|
1854
1678
|
summary: "Delete customer override",
|
|
1855
1679
|
tags: ["customers"],
|
|
1856
1680
|
responses: { "204": { description: "Deleted" } },
|
|
@@ -1860,7 +1684,7 @@ var customerPaths = {
|
|
|
1860
1684
|
"/api/customer-overrides/{overrideId}/revoke": {
|
|
1861
1685
|
post: operation({
|
|
1862
1686
|
operationId: "revokeCustomerOverride",
|
|
1863
|
-
requestParams: { path:
|
|
1687
|
+
requestParams: { path: z8.object({ overrideId: z8.string() }) },
|
|
1864
1688
|
summary: "Revoke an active customer override",
|
|
1865
1689
|
tags: ["customers"],
|
|
1866
1690
|
responses: { "200": { description: "Revoked", content: { "application/json": { schema: CustomerOverrideSchema } } } },
|
|
@@ -1870,28 +1694,270 @@ var customerPaths = {
|
|
|
1870
1694
|
"/api/customer-overrides/{overrideId}/duplicate": {
|
|
1871
1695
|
post: operation({
|
|
1872
1696
|
operationId: "duplicateCustomerOverride",
|
|
1873
|
-
requestParams: { path:
|
|
1697
|
+
requestParams: { path: z8.object({ overrideId: z8.string() }) },
|
|
1874
1698
|
summary: "Duplicate customer override for another customer",
|
|
1875
1699
|
tags: ["customers"],
|
|
1876
|
-
requestBody: { required: true, content: { "application/json": { schema:
|
|
1700
|
+
requestBody: { required: true, content: { "application/json": { schema: z8.object({ customer_id: z8.string() }) } } },
|
|
1877
1701
|
responses: { "201": { description: "Duplicated", content: { "application/json": { schema: CustomerOverrideSchema } } } },
|
|
1878
1702
|
"x-revturbine-operation": { exposure: "internal", resource: "customer-overrides", persistence: { table: "customerOverrides", mode: "create" } }
|
|
1879
1703
|
})
|
|
1880
1704
|
}
|
|
1881
1705
|
};
|
|
1706
|
+
var { Unrestricted: Unrestricted6, Pii: Pii2, Financial: Financial2 } = DataClassification;
|
|
1707
|
+
var { Persisted: Persisted6, Transient: Transient6 } = SchemaPersistence;
|
|
1708
|
+
var { External: External5, Internal: Internal5 } = SchemaExposure;
|
|
1709
|
+
var UserTrialStatusSchema = z9.object({
|
|
1710
|
+
in_trial: z9.boolean().meta(Unrestricted6),
|
|
1711
|
+
trial_type: z9.string().optional().meta(Unrestricted6),
|
|
1712
|
+
plan_handle: z9.string().optional().meta(Unrestricted6),
|
|
1713
|
+
// 'converted' reflects a server-side analytic-event transition
|
|
1714
|
+
// (typically a Stripe webhook like `customer.subscription.created`
|
|
1715
|
+
// or `invoice.payment_succeeded` against a trialing subscription)
|
|
1716
|
+
// that the control plane processes to flip TrialInstance.status.
|
|
1717
|
+
// The SDK reads this state from the decision-API response — it does
|
|
1718
|
+
// NOT derive 'converted' client-side. trial_lifecycle.v1 rules
|
|
1719
|
+
// matching on 'trial_converted' fire while the user's status carries
|
|
1720
|
+
// this value, enabling conversion-celebration / receipt placements.
|
|
1721
|
+
state: z9.enum(["active", "running_out", "expired", "converted", "none"]).optional().meta(Unrestricted6),
|
|
1722
|
+
/**
|
|
1723
|
+
* Trial limit model — mirrors the rule's `trial_limit_type`. The
|
|
1724
|
+
* SDK uses this to decide which numeric fields below to surface;
|
|
1725
|
+
* the placement-resolver gates `trial_ending(days_before_end)`
|
|
1726
|
+
* only when `trial_limit_type === 'time'`.
|
|
1727
|
+
*/
|
|
1728
|
+
trial_limit_type: z9.enum(["time", "usage"]).optional().meta(Unrestricted6),
|
|
1729
|
+
/**
|
|
1730
|
+
* Universal progress metric, 0..100. Computed by
|
|
1731
|
+
* `deriveLocalTrialStatusFromInstance` from elapsed days
|
|
1732
|
+
* (time-based) or consumed/limit (usage-based). Trial rule
|
|
1733
|
+
* modules + placement-resolver supersession consume this field
|
|
1734
|
+
* so they don't have to branch on the limit type.
|
|
1735
|
+
*/
|
|
1736
|
+
progress_percent: z9.number().min(0).max(100).optional().meta(Unrestricted6),
|
|
1737
|
+
// Time-based numeric fields. Populated when trial_limit_type='time'.
|
|
1738
|
+
day_number: z9.number().int().min(0).optional().meta(Unrestricted6),
|
|
1739
|
+
days_remaining: z9.number().int().min(0).optional().meta(Unrestricted6),
|
|
1740
|
+
// Usage-based numeric fields. Populated when trial_limit_type='usage'.
|
|
1741
|
+
usage_entitlement_handle: z9.string().optional().meta(Unrestricted6),
|
|
1742
|
+
usage_consumed: z9.number().int().min(0).optional().meta(Unrestricted6),
|
|
1743
|
+
usage_remaining: z9.number().int().min(0).optional().meta(Unrestricted6),
|
|
1744
|
+
usage_limit: z9.number().int().min(0).optional().meta(Unrestricted6)
|
|
1745
|
+
}).meta(
|
|
1746
|
+
{ id: "UserTrialStatus", "x-revturbine-schema-persistence": Transient6, "x-revturbine-schema-exposure": External5 }
|
|
1747
|
+
);
|
|
1748
|
+
var UserUsageEntrySchema = z9.object({
|
|
1749
|
+
entitlement_handle: z9.string().min(1).meta(Unrestricted6),
|
|
1750
|
+
unit: z9.string().min(1).meta(Unrestricted6),
|
|
1751
|
+
amount: z9.number().min(0).meta(Unrestricted6),
|
|
1752
|
+
limit: z9.number().min(0).optional().meta(Unrestricted6),
|
|
1753
|
+
reset_date: z9.string().optional().meta(Unrestricted6)
|
|
1754
|
+
}).meta(
|
|
1755
|
+
{ id: "UserUsageEntry", "x-revturbine-schema-persistence": Transient6, "x-revturbine-schema-exposure": External5 }
|
|
1756
|
+
);
|
|
1757
|
+
var UserPlanContextSchema = z9.object({
|
|
1758
|
+
id: z9.string().min(1).meta(Unrestricted6),
|
|
1759
|
+
name: z9.string().min(1).meta(Unrestricted6),
|
|
1760
|
+
price: z9.string().optional().meta(Unrestricted6),
|
|
1761
|
+
billing_period: z9.enum(["monthly", "annual", "none"]).optional().meta(Unrestricted6)
|
|
1762
|
+
}).meta(
|
|
1763
|
+
{ id: "UserPlanContext", "x-revturbine-schema-persistence": Transient6, "x-revturbine-schema-exposure": External5 }
|
|
1764
|
+
);
|
|
1765
|
+
var UserInstanceContextSchema = z9.object({
|
|
1766
|
+
product_instance_id: z9.string().min(1).meta(Unrestricted6),
|
|
1767
|
+
user_id: z9.string().min(1).meta(Pii2),
|
|
1768
|
+
plan: UserPlanContextSchema.optional().meta(Unrestricted6),
|
|
1769
|
+
/** Usage entries for this instance, keyed by entitlement handle. */
|
|
1770
|
+
usage: z9.record(z9.string(), UserUsageEntrySchema).default({}).meta(Unrestricted6),
|
|
1771
|
+
trial: UserTrialStatusSchema.optional().meta(Unrestricted6),
|
|
1772
|
+
/** Entitlements resolved at this instance level, keyed by handle. */
|
|
1773
|
+
entitlements: z9.record(z9.string(), z9.union([z9.boolean(), EntitlementGrantSchema])).default({}).meta(Unrestricted6)
|
|
1774
|
+
}).meta(
|
|
1775
|
+
{
|
|
1776
|
+
id: "UserInstanceContext",
|
|
1777
|
+
"x-revturbine-schema-persistence": Persisted6,
|
|
1778
|
+
"x-revturbine-schema-exposure": External5
|
|
1779
|
+
}
|
|
1780
|
+
);
|
|
1781
|
+
var UserContextSchema = IdField.merge(TenantIdField).merge(TimestampFields).extend({
|
|
1782
|
+
user_id: z9.string().min(1).meta(Pii2),
|
|
1783
|
+
account_id: z9.string().min(1).nullable().optional().meta(Pii2),
|
|
1784
|
+
email: z9.string().email().nullable().optional().meta(Pii2),
|
|
1785
|
+
/** Optional email classification (e.g. `business`, `personal`). */
|
|
1786
|
+
email_type: z9.string().optional().meta(Unrestricted6),
|
|
1787
|
+
plan: UserPlanContextSchema.optional().meta(Unrestricted6),
|
|
1788
|
+
/** Aggregate usage entries across all instances, keyed by handle. */
|
|
1789
|
+
usage: z9.record(z9.string(), UserUsageEntrySchema).default({}).meta(Unrestricted6),
|
|
1790
|
+
trial: UserTrialStatusSchema.optional().meta(Unrestricted6),
|
|
1791
|
+
/**
|
|
1792
|
+
* Billing-recovery signals (account-level). `payment_failed` reflects a
|
|
1793
|
+
* hard payment failure (e.g. Stripe `invoice.payment_failed`);
|
|
1794
|
+
* `payment_at_risk` an expiring / missing-backup payment method. They
|
|
1795
|
+
* drive the Retention `qualifier` placement triggers
|
|
1796
|
+
* (placement-studio-ui.md §3.7) — the SDK surfaces them onto the
|
|
1797
|
+
* PlanProvider state the placement resolver reads. Omitted for users in
|
|
1798
|
+
* good standing; a qualifier gate reads `=== true`, so an absent signal
|
|
1799
|
+
* never fires the recovery placement.
|
|
1800
|
+
*/
|
|
1801
|
+
payment_failed: z9.boolean().optional().meta(Unrestricted6),
|
|
1802
|
+
payment_at_risk: z9.boolean().optional().meta(Unrestricted6),
|
|
1803
|
+
/**
|
|
1804
|
+
* The user's current tier per `capability_tier` entitlement, keyed by
|
|
1805
|
+
* entitlement handle → tier handle (plan 138 TASK-4). Drives the
|
|
1806
|
+
* `entitlement_gate.tier_threshold` placement trigger: the SDK surfaces
|
|
1807
|
+
* this onto the EntitlementProvider state, and the resolver ranks the
|
|
1808
|
+
* current tier against the entitlement's ordered ladder. Omitted for a
|
|
1809
|
+
* user holding no tier (ranks below every threshold).
|
|
1810
|
+
*/
|
|
1811
|
+
tiers: z9.record(z9.string(), z9.string()).optional().meta(Unrestricted6),
|
|
1812
|
+
/** Account-level entitlements, keyed by handle. */
|
|
1813
|
+
entitlements: z9.record(z9.string(), z9.union([z9.boolean(), EntitlementGrantSchema])).default({}).meta(Unrestricted6),
|
|
1814
|
+
/** Per-instance breakdowns when the account has multiple product instances. */
|
|
1815
|
+
instances: z9.array(UserInstanceContextSchema).optional().meta(Unrestricted6),
|
|
1816
|
+
/** Customer-defined fields: role, app-level permissions, display prefs. */
|
|
1817
|
+
custom: z9.record(z9.string(), z9.union([z9.string(), z9.number(), z9.boolean(), z9.null()])).default({}).meta(Pii2),
|
|
1818
|
+
/**
|
|
1819
|
+
* Transient personalization token map.
|
|
1820
|
+
*
|
|
1821
|
+
* Holds SDK-derived tokens (plan_name, usage_current, etc.) merged with
|
|
1822
|
+
* app-provided tokens. Not persisted to the backend — rebuilt on each
|
|
1823
|
+
* SDK session from context + exported config.
|
|
1824
|
+
*/
|
|
1825
|
+
personalization: z9.record(z9.string(), z9.union([z9.string(), z9.number()])).default({}).meta({ ...Unrestricted6, "x-revturbine-schema-persistence": Transient6 }),
|
|
1826
|
+
// ── Derived-entitlement cache (plan 74 REQ-12/REQ-13) ──────────────
|
|
1827
|
+
// `entitlements` above is the rule-evaluated projection — a CACHE, not
|
|
1828
|
+
// source of truth. These stamps record what it was computed against so a
|
|
1829
|
+
// read can detect staleness: recompute when the active config version
|
|
1830
|
+
// moved on OR the context hash changed.
|
|
1831
|
+
/** Active config version (activated change-set id / compiled-bundle stamp) the cache was computed against. */
|
|
1832
|
+
derived_config_version: z9.string().nullable().optional().meta(Unrestricted6),
|
|
1833
|
+
/** Deterministic `computeUserContextHash` of the inputs the cache was computed from (REQ-13 ETag value). */
|
|
1834
|
+
context_hash: z9.string().nullable().optional().meta(Unrestricted6),
|
|
1835
|
+
/** When the cached entitlements were last (re)computed. */
|
|
1836
|
+
derived_computed_at: NullableDatetimeField.meta(Unrestricted6)
|
|
1837
|
+
}).meta(
|
|
1838
|
+
{ id: "UserContext", "x-revturbine-schema-persistence": Persisted6, "x-revturbine-schema-exposure": External5 }
|
|
1839
|
+
);
|
|
1840
|
+
var ClientContextTrialSchema = z9.object({
|
|
1841
|
+
status: z9.enum(["active", "running_out", "expired", "converted", "none"]).meta({ ...Unrestricted6, ...ClientSafe }),
|
|
1842
|
+
days_remaining: z9.number().int().min(0).optional().meta({ ...Unrestricted6, ...ClientSafe }),
|
|
1843
|
+
ends_at: z9.string().optional().meta({ ...Unrestricted6, ...ClientSafe })
|
|
1844
|
+
}).meta(
|
|
1845
|
+
{ id: "ClientContextTrial", "x-revturbine-schema-persistence": Transient6, "x-revturbine-schema-exposure": Internal5 }
|
|
1846
|
+
);
|
|
1847
|
+
var ClientContextBillingSchema = z9.object({
|
|
1848
|
+
/** Coarse, browser-safe billing-health signal (the only billing field exposed). */
|
|
1849
|
+
health: z9.enum(["ok", "attention_required"]).optional().meta({ ...Unrestricted6, ...ClientSafe }),
|
|
1850
|
+
/** decision_only — drives retention placements server-side; never returned to the browser. */
|
|
1851
|
+
failed_payment_reason: z9.string().optional().meta({ ...Financial2, ...DecisionOnly }),
|
|
1852
|
+
/**
|
|
1853
|
+
* decision_only — the raw billing-health issue codes (plan 156). The coarse
|
|
1854
|
+
* `health` above is derived from whether this is non-empty; these raw codes
|
|
1855
|
+
* may drive server-side Playbook decisions but are stripped by the exposure
|
|
1856
|
+
* filter and never returned to the browser.
|
|
1857
|
+
*/
|
|
1858
|
+
issues: z9.array(BillingHealthStatusSchema).optional().meta({ ...Financial2, ...DecisionOnly }),
|
|
1859
|
+
/** server_only — raw provider identifier; never exposed. */
|
|
1860
|
+
provider_subscription_id: z9.string().optional().meta({ ...Financial2, ...ServerOnly })
|
|
1861
|
+
}).meta(
|
|
1862
|
+
{ id: "ClientContextBilling", "x-revturbine-schema-persistence": Transient6, "x-revturbine-schema-exposure": Internal5 }
|
|
1863
|
+
);
|
|
1864
|
+
var ClientContextCapabilitiesSchema = z9.object({
|
|
1865
|
+
can_upgrade: z9.boolean().optional().meta({ ...Unrestricted6, ...ClientSafe }),
|
|
1866
|
+
can_manage_billing: z9.boolean().optional().meta({ ...Unrestricted6, ...ClientSafe })
|
|
1867
|
+
}).meta(
|
|
1868
|
+
{ id: "ClientContextCapabilities", "x-revturbine-schema-persistence": Transient6, "x-revturbine-schema-exposure": Internal5 }
|
|
1869
|
+
);
|
|
1870
|
+
var ClientContextPlanSchema = z9.object({
|
|
1871
|
+
/** The customer's current plan handle (`plans.unique_handle`). */
|
|
1872
|
+
handle: z9.string().min(1).optional().meta({ ...Unrestricted6, ...ClientSafe }),
|
|
1873
|
+
/**
|
|
1874
|
+
* The plan's display name, resolved server-side from the plan record so
|
|
1875
|
+
* client UI can render it without a Playbook lookup (plan 179 TASK-1 —
|
|
1876
|
+
* Q-2 ruling: `{ handle, name }`). Plan names are already client-visible
|
|
1877
|
+
* in every Playbook; no new exposure.
|
|
1878
|
+
*/
|
|
1879
|
+
name: z9.string().min(1).optional().meta({ ...Unrestricted6, ...ClientSafe })
|
|
1880
|
+
}).meta(
|
|
1881
|
+
{ id: "ClientContextPlan", "x-revturbine-schema-persistence": Transient6, "x-revturbine-schema-exposure": Internal5 }
|
|
1882
|
+
);
|
|
1883
|
+
var ClientContextSchema = z9.object({
|
|
1884
|
+
/** The end-user subject the client token was minted for (carried by the token, not the request). */
|
|
1885
|
+
subject: z9.string().min(1).meta({ ...Unrestricted6, ...ClientSafe }),
|
|
1886
|
+
/** Opaque version stamp of the underlying context snapshot. */
|
|
1887
|
+
context_version: z9.string().optional().meta({ ...Unrestricted6, ...ClientSafe }),
|
|
1888
|
+
trial: ClientContextTrialSchema.optional().meta({ ...Unrestricted6, ...ClientSafe }),
|
|
1889
|
+
billing: ClientContextBillingSchema.optional().meta({ ...Unrestricted6, ...ClientSafe }),
|
|
1890
|
+
plan: ClientContextPlanSchema.optional().meta({ ...Unrestricted6, ...ClientSafe }),
|
|
1891
|
+
capabilities: ClientContextCapabilitiesSchema.optional().meta({ ...Unrestricted6, ...ClientSafe })
|
|
1892
|
+
}).meta(
|
|
1893
|
+
{ id: "ClientContext", "x-revturbine-schema-persistence": Transient6, "x-revturbine-schema-exposure": Internal5 }
|
|
1894
|
+
);
|
|
1895
|
+
var userContextPaths = {
|
|
1896
|
+
"/api/user-contexts": {
|
|
1897
|
+
get: operation({
|
|
1898
|
+
operationId: "listUserContexts",
|
|
1899
|
+
requestParams: { query: ListQueryParamsSchema },
|
|
1900
|
+
summary: "List user contexts",
|
|
1901
|
+
tags: ["users"],
|
|
1902
|
+
responses: { "200": { description: "User context list", content: { "application/json": { schema: ListEnvelope(UserContextSchema) } } } },
|
|
1903
|
+
"x-revturbine-operation": { exposure: "internal", resource: "user-contexts", persistence: { table: "userContexts", mode: "list" } }
|
|
1904
|
+
}),
|
|
1905
|
+
// Upsert by (tenant_id, user_id): the SDK identify/setUserContext path
|
|
1906
|
+
// writes the persisted context. The collection POST is the create-or-update
|
|
1907
|
+
// entry point — the route resolves the existing row by (tenant_id, user_id)
|
|
1908
|
+
// and applies an idempotent upsert (server-side, plan 74 TASK-4).
|
|
1909
|
+
post: operation({
|
|
1910
|
+
operationId: "createUserContext",
|
|
1911
|
+
summary: "Create or upsert a user context",
|
|
1912
|
+
tags: ["users"],
|
|
1913
|
+
requestBody: { required: true, content: { "application/json": { schema: UserContextSchema } } },
|
|
1914
|
+
responses: { "201": { description: "Created", content: { "application/json": { schema: UserContextSchema } } } },
|
|
1915
|
+
"x-revturbine-operation": { exposure: "internal", resource: "user-contexts", persistence: { table: "userContexts", mode: "create", uniqueBy: ["tenant_id", "user_id"] } }
|
|
1916
|
+
})
|
|
1917
|
+
},
|
|
1918
|
+
"/api/user-contexts/{userContextId}": {
|
|
1919
|
+
get: operation({
|
|
1920
|
+
operationId: "getUserContext",
|
|
1921
|
+
requestParams: { path: z9.object({ userContextId: z9.string() }) },
|
|
1922
|
+
summary: "Get user context",
|
|
1923
|
+
tags: ["users"],
|
|
1924
|
+
responses: { "200": { description: "User context", content: { "application/json": { schema: UserContextSchema } } } },
|
|
1925
|
+
"x-revturbine-operation": { exposure: "internal", resource: "user-contexts", persistence: { table: "userContexts", mode: "get" } }
|
|
1926
|
+
}),
|
|
1927
|
+
patch: operation({
|
|
1928
|
+
operationId: "updateUserContext",
|
|
1929
|
+
requestParams: { path: z9.object({ userContextId: z9.string() }) },
|
|
1930
|
+
summary: "Update a user context",
|
|
1931
|
+
tags: ["users"],
|
|
1932
|
+
requestBody: { required: true, content: { "application/json": { schema: UserContextSchema.partial() } } },
|
|
1933
|
+
responses: { "200": { description: "Updated", content: { "application/json": { schema: UserContextSchema } } } },
|
|
1934
|
+
"x-revturbine-operation": { exposure: "internal", resource: "user-contexts", persistence: { table: "userContexts", mode: "update" } }
|
|
1935
|
+
}),
|
|
1936
|
+
// Delete path ships in v1 (plan 74 Q-1): a user context can be removed on
|
|
1937
|
+
// request now; full by-email DSR tooling remains deferred (sdk.md §8).
|
|
1938
|
+
delete: operation({
|
|
1939
|
+
operationId: "deleteUserContext",
|
|
1940
|
+
requestParams: { path: z9.object({ userContextId: z9.string() }) },
|
|
1941
|
+
summary: "Delete a user context",
|
|
1942
|
+
tags: ["users"],
|
|
1943
|
+
responses: { "204": { description: "Deleted" } },
|
|
1944
|
+
"x-revturbine-operation": { exposure: "internal", resource: "user-contexts", persistence: { table: "userContexts", mode: "delete" } }
|
|
1945
|
+
})
|
|
1946
|
+
}
|
|
1947
|
+
};
|
|
1882
1948
|
var { Unrestricted: Unrestricted7 } = DataClassification;
|
|
1883
1949
|
var { Persisted: Persisted7, Transient: Transient7 } = SchemaPersistence;
|
|
1884
|
-
var { Internal:
|
|
1950
|
+
var { Internal: Internal6 } = SchemaExposure;
|
|
1885
1951
|
var PLAYBOOK_SDK_FACETS4 = schemaFacets(SchemaContext.Playbook, { sdkInput: true });
|
|
1886
1952
|
var PENDING_PLAYBOOK_SDK_FACETS = schemaFacets(SchemaContext.Playbook, {
|
|
1887
1953
|
inConfig: false,
|
|
1888
1954
|
sdkInput: true
|
|
1889
1955
|
});
|
|
1890
1956
|
var DimensionCategorySchema = z10.enum(["default", "custom"]).meta(
|
|
1891
|
-
{ id: "DimensionCategory", "x-revturbine-schema-persistence": Transient7, "x-revturbine-schema-exposure":
|
|
1957
|
+
{ id: "DimensionCategory", "x-revturbine-schema-persistence": Transient7, "x-revturbine-schema-exposure": Internal6 }
|
|
1892
1958
|
);
|
|
1893
1959
|
var DimensionSourceTypeSchema = z10.enum(["system", "sdk_trait", "sdk_trait_enum", "cdp_property", "manual_list"]).meta(
|
|
1894
|
-
{ id: "DimensionSourceType", "x-revturbine-schema-persistence": Transient7, "x-revturbine-schema-exposure":
|
|
1960
|
+
{ id: "DimensionSourceType", "x-revturbine-schema-persistence": Transient7, "x-revturbine-schema-exposure": Internal6 }
|
|
1895
1961
|
);
|
|
1896
1962
|
var SegmentDimensionSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(AnchorFields).merge(VersionFields).extend({
|
|
1897
1963
|
anchor_id: z10.string().min(1).meta({ ...Unrestricted7, readOnly: true }),
|
|
@@ -1909,7 +1975,7 @@ var SegmentDimensionSchema = IdField.merge(TimestampFields).merge(TenantIdField)
|
|
|
1909
1975
|
{
|
|
1910
1976
|
id: "SegmentDimension",
|
|
1911
1977
|
"x-revturbine-schema-persistence": Persisted7,
|
|
1912
|
-
"x-revturbine-schema-exposure":
|
|
1978
|
+
"x-revturbine-schema-exposure": Internal6,
|
|
1913
1979
|
...PENDING_PLAYBOOK_SDK_FACETS,
|
|
1914
1980
|
...namedIdentity()
|
|
1915
1981
|
}
|
|
@@ -1927,7 +1993,7 @@ var SegmentValueSchema = IdField.merge(TimestampFields).merge(TenantIdField).mer
|
|
|
1927
1993
|
{
|
|
1928
1994
|
id: "SegmentValue",
|
|
1929
1995
|
"x-revturbine-schema-persistence": Persisted7,
|
|
1930
|
-
"x-revturbine-schema-exposure":
|
|
1996
|
+
"x-revturbine-schema-exposure": Internal6,
|
|
1931
1997
|
...PENDING_PLAYBOOK_SDK_FACETS,
|
|
1932
1998
|
...namedIdentity()
|
|
1933
1999
|
}
|
|
@@ -1946,7 +2012,7 @@ var SegmentSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(An
|
|
|
1946
2012
|
{
|
|
1947
2013
|
id: "Segment",
|
|
1948
2014
|
"x-revturbine-schema-persistence": Persisted7,
|
|
1949
|
-
"x-revturbine-schema-exposure":
|
|
2015
|
+
"x-revturbine-schema-exposure": Internal6,
|
|
1950
2016
|
...PLAYBOOK_SDK_FACETS4,
|
|
1951
2017
|
...namedIdentity()
|
|
1952
2018
|
}
|
|
@@ -2280,7 +2346,7 @@ var contentPaths = {
|
|
|
2280
2346
|
};
|
|
2281
2347
|
var { Unrestricted: Unrestricted9, Pii: Pii3 } = DataClassification;
|
|
2282
2348
|
var { Persisted: Persisted9, Transient: Transient9 } = SchemaPersistence;
|
|
2283
|
-
var { Internal:
|
|
2349
|
+
var { Internal: Internal7, External: External7 } = SchemaExposure;
|
|
2284
2350
|
var BRANDING_FACETS = schemaFacets(SchemaContext.Branding, { sdkInput: false });
|
|
2285
2351
|
var ThemeSchema = z12.object({
|
|
2286
2352
|
id: z12.string().min(1).meta({ ...Unrestricted9, readOnly: true }),
|
|
@@ -2303,7 +2369,7 @@ var UiPreferenceSchema = IdField.merge(TimestampFields).extend({
|
|
|
2303
2369
|
{
|
|
2304
2370
|
id: "UiPreference",
|
|
2305
2371
|
"x-revturbine-schema-persistence": Persisted9,
|
|
2306
|
-
"x-revturbine-schema-exposure":
|
|
2372
|
+
"x-revturbine-schema-exposure": Internal7
|
|
2307
2373
|
}
|
|
2308
2374
|
);
|
|
2309
2375
|
var uiPreferencePaths = {
|
|
@@ -2347,15 +2413,15 @@ var uiPreferencePaths = {
|
|
|
2347
2413
|
})
|
|
2348
2414
|
}
|
|
2349
2415
|
};
|
|
2350
|
-
var { Unrestricted: Unrestricted10, Financial:
|
|
2416
|
+
var { Unrestricted: Unrestricted10, Financial: Financial3 } = DataClassification;
|
|
2351
2417
|
var { Persisted: Persisted10, Transient: Transient10 } = SchemaPersistence;
|
|
2352
|
-
var { External: External8, Internal:
|
|
2418
|
+
var { External: External8, Internal: Internal8 } = SchemaExposure;
|
|
2353
2419
|
var CohortMonthSchema = z13.object({
|
|
2354
2420
|
month: z13.string().meta(Unrestricted10),
|
|
2355
2421
|
cohort_size: z13.number().int().min(0).meta(Unrestricted10),
|
|
2356
2422
|
retained: z13.number().int().min(0).meta(Unrestricted10),
|
|
2357
2423
|
retention_rate: z13.number().min(0).max(1).meta(Unrestricted10),
|
|
2358
|
-
revenue_cents: z13.number().int().min(0).meta(
|
|
2424
|
+
revenue_cents: z13.number().int().min(0).meta(Financial3)
|
|
2359
2425
|
}).meta(
|
|
2360
2426
|
{ id: "CohortMonth", "x-revturbine-schema-persistence": Transient10, "x-revturbine-schema-exposure": External8 }
|
|
2361
2427
|
);
|
|
@@ -2376,26 +2442,26 @@ var PlacementPerformanceRowSchema = z13.object({
|
|
|
2376
2442
|
conversions: z13.number().int().min(0).meta(Unrestricted10),
|
|
2377
2443
|
ctr: z13.number().min(0).meta(Unrestricted10),
|
|
2378
2444
|
conversion_rate: z13.number().min(0).meta(Unrestricted10),
|
|
2379
|
-
revenue_cents: z13.number().int().min(0).meta(
|
|
2445
|
+
revenue_cents: z13.number().int().min(0).meta(Financial3)
|
|
2380
2446
|
}).meta(
|
|
2381
2447
|
{ id: "PlacementPerformanceRow", "x-revturbine-schema-persistence": Transient10, "x-revturbine-schema-exposure": External8 }
|
|
2382
2448
|
);
|
|
2383
2449
|
var RevenueMetricSchema = z13.object({
|
|
2384
2450
|
date: z13.string().meta(Unrestricted10),
|
|
2385
|
-
mrr_cents: z13.number().int().min(0).meta(
|
|
2386
|
-
arr_cents: z13.number().int().min(0).meta(
|
|
2387
|
-
new_mrr_cents: z13.number().int().min(0).meta(
|
|
2388
|
-
churned_mrr_cents: z13.number().int().min(0).meta(
|
|
2389
|
-
expansion_mrr_cents: z13.number().int().min(0).meta(
|
|
2390
|
-
net_new_mrr_cents: z13.number().int().meta(
|
|
2451
|
+
mrr_cents: z13.number().int().min(0).meta(Financial3),
|
|
2452
|
+
arr_cents: z13.number().int().min(0).meta(Financial3),
|
|
2453
|
+
new_mrr_cents: z13.number().int().min(0).meta(Financial3),
|
|
2454
|
+
churned_mrr_cents: z13.number().int().min(0).meta(Financial3),
|
|
2455
|
+
expansion_mrr_cents: z13.number().int().min(0).meta(Financial3),
|
|
2456
|
+
net_new_mrr_cents: z13.number().int().meta(Financial3)
|
|
2391
2457
|
}).meta(
|
|
2392
2458
|
{ id: "RevenueMetric", "x-revturbine-schema-persistence": Transient10, "x-revturbine-schema-exposure": External8 }
|
|
2393
2459
|
);
|
|
2394
2460
|
var KpiAggregateSchema = z13.object({
|
|
2395
2461
|
metric_key: z13.string().min(1).meta(Unrestricted10),
|
|
2396
2462
|
label: z13.string().meta(Unrestricted10),
|
|
2397
|
-
current_value: z13.number().meta(
|
|
2398
|
-
previous_value: z13.number().nullable().default(null).meta(
|
|
2463
|
+
current_value: z13.number().meta(Financial3),
|
|
2464
|
+
previous_value: z13.number().nullable().default(null).meta(Financial3),
|
|
2399
2465
|
change_percent: z13.number().nullable().default(null).meta(Unrestricted10),
|
|
2400
2466
|
period: z13.string().meta(Unrestricted10),
|
|
2401
2467
|
unit: z13.enum(["count", "cents", "percent", "ratio", "seconds"]).default("count").meta(Unrestricted10)
|
|
@@ -2415,7 +2481,7 @@ var DriftReportSchema = IdField.merge(TimestampFields).merge(TenantIdField).exte
|
|
|
2415
2481
|
resolved_at: NullableDatetimeField.meta(Unrestricted10),
|
|
2416
2482
|
metadata: MetadataField.meta(Unrestricted10)
|
|
2417
2483
|
}).meta(
|
|
2418
|
-
{ id: "DriftReport", "x-revturbine-schema-persistence": Persisted10, "x-revturbine-schema-exposure":
|
|
2484
|
+
{ id: "DriftReport", "x-revturbine-schema-persistence": Persisted10, "x-revturbine-schema-exposure": Internal8 }
|
|
2419
2485
|
);
|
|
2420
2486
|
var AlertSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
2421
2487
|
alert_type: z13.enum(["usage_threshold", "revenue_drop", "conversion_drop", "experiment_significance", "drift_detected", "custom"]).meta(Unrestricted10),
|
|
@@ -2429,7 +2495,7 @@ var AlertSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
|
2429
2495
|
acknowledged_by: z13.string().nullable().default(null).meta(Unrestricted10),
|
|
2430
2496
|
metadata: MetadataField.meta(Unrestricted10)
|
|
2431
2497
|
}).meta(
|
|
2432
|
-
{ id: "Alert", "x-revturbine-schema-persistence": Persisted10, "x-revturbine-schema-exposure":
|
|
2498
|
+
{ id: "Alert", "x-revturbine-schema-persistence": Persisted10, "x-revturbine-schema-exposure": Internal8 }
|
|
2433
2499
|
);
|
|
2434
2500
|
var analyticsPaths = {
|
|
2435
2501
|
"/api/analytics/kpis": {
|
|
@@ -2525,7 +2591,7 @@ var analyticsPaths = {
|
|
|
2525
2591
|
};
|
|
2526
2592
|
var { Unrestricted: Unrestricted11, Pii: Pii4 } = DataClassification;
|
|
2527
2593
|
var { Persisted: Persisted11, Transient: Transient11 } = SchemaPersistence;
|
|
2528
|
-
var { Internal:
|
|
2594
|
+
var { Internal: Internal9, External: External9 } = SchemaExposure;
|
|
2529
2595
|
var EventSourceSchema = z14.enum(["clickstream", "telemetry", "sdk", "workflow", "system"]).meta(
|
|
2530
2596
|
{
|
|
2531
2597
|
id: "EventSource",
|
|
@@ -2547,7 +2613,7 @@ var EventEnvelopeSchema = IdField.extend({
|
|
|
2547
2613
|
{
|
|
2548
2614
|
id: "EventEnvelope",
|
|
2549
2615
|
"x-revturbine-schema-persistence": Transient11,
|
|
2550
|
-
"x-revturbine-schema-exposure":
|
|
2616
|
+
"x-revturbine-schema-exposure": Internal9
|
|
2551
2617
|
}
|
|
2552
2618
|
);
|
|
2553
2619
|
var IngestedEventSchema = EventEnvelopeSchema.extend({
|
|
@@ -2556,7 +2622,7 @@ var IngestedEventSchema = EventEnvelopeSchema.extend({
|
|
|
2556
2622
|
{
|
|
2557
2623
|
id: "IngestedEvent",
|
|
2558
2624
|
"x-revturbine-schema-persistence": Persisted11,
|
|
2559
|
-
"x-revturbine-schema-exposure":
|
|
2625
|
+
"x-revturbine-schema-exposure": Internal9
|
|
2560
2626
|
}
|
|
2561
2627
|
);
|
|
2562
2628
|
var EventIngestBatchSchema = z14.array(
|
|
@@ -2577,7 +2643,7 @@ var EventIngestBatchSchema = z14.array(
|
|
|
2577
2643
|
{
|
|
2578
2644
|
id: "EventIngestBatch",
|
|
2579
2645
|
"x-revturbine-schema-persistence": Transient11,
|
|
2580
|
-
"x-revturbine-schema-exposure":
|
|
2646
|
+
"x-revturbine-schema-exposure": Internal9
|
|
2581
2647
|
}
|
|
2582
2648
|
);
|
|
2583
2649
|
var TreatmentInteractionTypeSchema = z14.enum([
|
|
@@ -2606,6 +2672,12 @@ var TreatmentInteractionInputSchema = z14.object({
|
|
|
2606
2672
|
payload_id: z14.string().min(1).optional().meta(Unrestricted11),
|
|
2607
2673
|
interaction_type: TreatmentInteractionTypeSchema.meta(Unrestricted11),
|
|
2608
2674
|
interaction_at: z14.string().datetime().optional().meta(Unrestricted11),
|
|
2675
|
+
/**
|
|
2676
|
+
* Caller-declared test traffic (plan 164) — mirrors `TrackEvent.test` so
|
|
2677
|
+
* the presentation/interaction feed (the dashboard denominators) carries
|
|
2678
|
+
* the same default-excluded, `include_test`-toggleable dimension.
|
|
2679
|
+
*/
|
|
2680
|
+
test: z14.boolean().optional().meta(Unrestricted11),
|
|
2609
2681
|
metadata: z14.record(z14.string(), z14.unknown()).optional().meta(Unrestricted11)
|
|
2610
2682
|
}).meta(
|
|
2611
2683
|
{
|
|
@@ -2754,21 +2826,21 @@ var EventSearchParamsSchema = z14.object({
|
|
|
2754
2826
|
{
|
|
2755
2827
|
id: "EventSearchParams",
|
|
2756
2828
|
"x-revturbine-schema-persistence": Transient11,
|
|
2757
|
-
"x-revturbine-schema-exposure":
|
|
2829
|
+
"x-revturbine-schema-exposure": Internal9
|
|
2758
2830
|
}
|
|
2759
2831
|
);
|
|
2760
2832
|
var WebhookEventSourceSchema = z14.enum(["stripe", "apple", "google"]).meta(
|
|
2761
2833
|
{
|
|
2762
2834
|
id: "WebhookEventSource",
|
|
2763
2835
|
"x-revturbine-schema-persistence": Transient11,
|
|
2764
|
-
"x-revturbine-schema-exposure":
|
|
2836
|
+
"x-revturbine-schema-exposure": Internal9
|
|
2765
2837
|
}
|
|
2766
2838
|
);
|
|
2767
2839
|
var WebhookEventStatusSchema = z14.enum(["processed", "failed", "skipped"]).meta(
|
|
2768
2840
|
{
|
|
2769
2841
|
id: "WebhookEventStatus",
|
|
2770
2842
|
"x-revturbine-schema-persistence": Transient11,
|
|
2771
|
-
"x-revturbine-schema-exposure":
|
|
2843
|
+
"x-revturbine-schema-exposure": Internal9
|
|
2772
2844
|
}
|
|
2773
2845
|
);
|
|
2774
2846
|
var WebhookEventLogSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
@@ -2783,7 +2855,7 @@ var WebhookEventLogSchema = IdField.merge(TimestampFields).merge(TenantIdField).
|
|
|
2783
2855
|
{
|
|
2784
2856
|
id: "WebhookEventLog",
|
|
2785
2857
|
"x-revturbine-schema-persistence": Persisted11,
|
|
2786
|
-
"x-revturbine-schema-exposure":
|
|
2858
|
+
"x-revturbine-schema-exposure": Internal9
|
|
2787
2859
|
}
|
|
2788
2860
|
);
|
|
2789
2861
|
var EventIngestResponseSchema = z14.object({
|
|
@@ -2792,7 +2864,7 @@ var EventIngestResponseSchema = z14.object({
|
|
|
2792
2864
|
{
|
|
2793
2865
|
id: "null",
|
|
2794
2866
|
"x-revturbine-schema-persistence": Transient11,
|
|
2795
|
-
"x-revturbine-schema-exposure":
|
|
2867
|
+
"x-revturbine-schema-exposure": Internal9
|
|
2796
2868
|
}
|
|
2797
2869
|
);
|
|
2798
2870
|
var MAX_TRACK_EVENTS_PER_BATCH = 500;
|
|
@@ -2837,7 +2909,16 @@ var TrackEventSchema = z14.object({
|
|
|
2837
2909
|
/** Immutable Playbook version that produced the experience. The field that makes a past decision reproducible. */
|
|
2838
2910
|
playbook_version: z14.string().nullable().optional().meta(Unrestricted11),
|
|
2839
2911
|
/** Correlates every event caused by one decision — a join key, not a group-by. */
|
|
2840
|
-
decision_id: z14.string().nullable().optional().meta(Unrestricted11)
|
|
2912
|
+
decision_id: z14.string().nullable().optional().meta(Unrestricted11),
|
|
2913
|
+
/**
|
|
2914
|
+
* Caller-declared test traffic (plan 164): set from the SDK's `test` init
|
|
2915
|
+
* option, stamped on every emitted event. Analytics pipes exclude
|
|
2916
|
+
* `test = true` rows from denominators/rollups by default, with an
|
|
2917
|
+
* `include_test` pipe parameter as the opt-in toggle. Distinct from the
|
|
2918
|
+
* placement "Test Mode" (plan 08c), which is a server-decided per-user
|
|
2919
|
+
* flag on DECISIONING responses — this one marks EMITTED events.
|
|
2920
|
+
*/
|
|
2921
|
+
test: z14.boolean().optional().meta(Unrestricted11)
|
|
2841
2922
|
}).meta(
|
|
2842
2923
|
{
|
|
2843
2924
|
id: "TrackEvent",
|
|
@@ -2855,7 +2936,7 @@ var TrackIngestBatchSchema = z14.object({
|
|
|
2855
2936
|
}
|
|
2856
2937
|
);
|
|
2857
2938
|
var MAX_SDK_META_EVENTS_PER_BATCH = 10;
|
|
2858
|
-
var SdkMetaEventTypeSchema = z14.enum(["sdk_init", "sdk_error", "sdk_validation_warning"]).meta(
|
|
2939
|
+
var SdkMetaEventTypeSchema = z14.enum(["sdk_init", "sdk_error", "sdk_validation_warning", "resolution_failure"]).meta(
|
|
2859
2940
|
{
|
|
2860
2941
|
id: "SdkMetaEventType",
|
|
2861
2942
|
"x-revturbine-schema-persistence": Transient11,
|
|
@@ -2893,7 +2974,19 @@ var SdkMetaEventSchema = z14.object({
|
|
|
2893
2974
|
// Present for sdk_init; config-shape counts only, no user context (REQ-6).
|
|
2894
2975
|
config_shape: SdkConfigShapeSchema.optional().meta(Unrestricted11),
|
|
2895
2976
|
// Short non-PII diagnostic for sdk_error / sdk_validation_warning.
|
|
2896
|
-
message: z14.string().max(500).optional().meta(Unrestricted11)
|
|
2977
|
+
message: z14.string().max(500).optional().meta(Unrestricted11),
|
|
2978
|
+
// Diagnostic fields for `resolution_failure` (plan 144 TASK-20; absorbed
|
|
2979
|
+
// plan 124 REQ-5/AC-6 — its Q-1 allow-list, append-only). Every value is
|
|
2980
|
+
// an AUTHOR-DEFINED handle or a closed reason code — never user-supplied
|
|
2981
|
+
// free text; `message` above remains the only prose field and stays
|
|
2982
|
+
// length-capped. Emitted from the SDK's fallback/deny sites so a
|
|
2983
|
+
// placement that silently resolves to nothing becomes observable.
|
|
2984
|
+
reason: z14.string().min(1).max(64).optional().meta(Unrestricted11),
|
|
2985
|
+
placement_handle: z14.string().min(1).max(64).optional().meta(Unrestricted11),
|
|
2986
|
+
slot_handle: z14.string().min(1).max(64).optional().meta(Unrestricted11),
|
|
2987
|
+
surface: z14.string().min(1).max(64).optional().meta(Unrestricted11),
|
|
2988
|
+
plan_handle: z14.string().min(1).max(64).optional().meta(Unrestricted11),
|
|
2989
|
+
entitlement_handle: z14.string().min(1).max(64).optional().meta(Unrestricted11)
|
|
2897
2990
|
}).meta(
|
|
2898
2991
|
{
|
|
2899
2992
|
id: "SdkMetaEvent",
|
|
@@ -2985,17 +3078,17 @@ var eventPaths = {
|
|
|
2985
3078
|
};
|
|
2986
3079
|
var { Unrestricted: Unrestricted12 } = DataClassification;
|
|
2987
3080
|
var { Persisted: Persisted12, Transient: Transient12 } = SchemaPersistence;
|
|
2988
|
-
var { Internal:
|
|
3081
|
+
var { Internal: Internal10 } = SchemaExposure;
|
|
2989
3082
|
var PLAYBOOK_SDK_FACETS6 = schemaFacets(SchemaContext.Playbook, { sdkInput: true });
|
|
2990
3083
|
var PENDING_PLAYBOOK_SDK_FACETS2 = schemaFacets(SchemaContext.Playbook, {
|
|
2991
3084
|
inConfig: false,
|
|
2992
3085
|
sdkInput: true
|
|
2993
3086
|
});
|
|
2994
3087
|
var TrialStatusSchema = z15.enum(["not_started", "active", "expired", "converted", "cancelled"]).meta(
|
|
2995
|
-
{ id: "TrialStatus", "x-revturbine-schema-persistence": Transient12, "x-revturbine-schema-exposure":
|
|
3088
|
+
{ id: "TrialStatus", "x-revturbine-schema-persistence": Transient12, "x-revturbine-schema-exposure": Internal10 }
|
|
2996
3089
|
);
|
|
2997
3090
|
var TrialLimitTypeSchema = z15.enum(["time", "usage"]).meta(
|
|
2998
|
-
{ id: "TrialLimitType", "x-revturbine-schema-persistence": Transient12, "x-revturbine-schema-exposure":
|
|
3091
|
+
{ id: "TrialLimitType", "x-revturbine-schema-persistence": Transient12, "x-revturbine-schema-exposure": Internal10 }
|
|
2999
3092
|
);
|
|
3000
3093
|
var FreeTrialRuleCoreFieldsSchema = z15.object({
|
|
3001
3094
|
name: NameField.meta(Unrestricted12),
|
|
@@ -3043,11 +3136,11 @@ var FreeTrialRuleCoreFieldsSchema = z15.object({
|
|
|
3043
3136
|
var FreeTrialRuleSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(AnchorFields).merge(VersionFields).extend({
|
|
3044
3137
|
anchor_id: z15.string().min(1).meta({ ...Unrestricted12, readOnly: true })
|
|
3045
3138
|
}).merge(FreeTrialRuleCoreFieldsSchema).meta(
|
|
3046
|
-
{ id: "FreeTrialRule", "x-revturbine-schema-persistence": Persisted12, "x-revturbine-schema-exposure":
|
|
3139
|
+
{ id: "FreeTrialRule", "x-revturbine-schema-persistence": Persisted12, "x-revturbine-schema-exposure": Internal10, ...PLAYBOOK_SDK_FACETS6, ...namedIdentity() }
|
|
3047
3140
|
);
|
|
3048
3141
|
var FreeTrialRuleAnchorSchema = makeAnchor("FreeTrialRuleAnchor");
|
|
3049
3142
|
var ReverseTrialStartPolicySchema = z15.enum(["signup", "first_premium_access", "manual"]).meta(
|
|
3050
|
-
{ id: "ReverseTrialStartPolicy", "x-revturbine-schema-persistence": Transient12, "x-revturbine-schema-exposure":
|
|
3143
|
+
{ id: "ReverseTrialStartPolicy", "x-revturbine-schema-persistence": Transient12, "x-revturbine-schema-exposure": Internal10 }
|
|
3051
3144
|
);
|
|
3052
3145
|
var ReverseTrialRuleCoreFieldsSchema = z15.object({
|
|
3053
3146
|
name: NameField.meta(Unrestricted12),
|
|
@@ -3068,26 +3161,26 @@ var ReverseTrialRuleCoreFieldsSchema = z15.object({
|
|
|
3068
3161
|
var ReverseTrialRuleSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(AnchorFields).merge(VersionFields).extend({
|
|
3069
3162
|
anchor_id: z15.string().min(1).meta({ ...Unrestricted12, readOnly: true })
|
|
3070
3163
|
}).merge(ReverseTrialRuleCoreFieldsSchema).meta(
|
|
3071
|
-
{ id: "ReverseTrialRule", "x-revturbine-schema-persistence": Persisted12, "x-revturbine-schema-exposure":
|
|
3164
|
+
{ id: "ReverseTrialRule", "x-revturbine-schema-persistence": Persisted12, "x-revturbine-schema-exposure": Internal10, ...PLAYBOOK_SDK_FACETS6, ...namedIdentity() }
|
|
3072
3165
|
);
|
|
3073
3166
|
var ReverseTrialRuleAnchorSchema = makeAnchor("ReverseTrialRuleAnchor");
|
|
3074
3167
|
var TrialLimitPolicySchema = z15.enum(["1_per_lifetime", "1_per_plan", "1_per_year", "unlimited"]).meta(
|
|
3075
|
-
{ id: "TrialLimitPolicy", "x-revturbine-schema-persistence": Transient12, "x-revturbine-schema-exposure":
|
|
3168
|
+
{ id: "TrialLimitPolicy", "x-revturbine-schema-persistence": Transient12, "x-revturbine-schema-exposure": Internal10 }
|
|
3076
3169
|
);
|
|
3077
3170
|
var TrialEligibilityScopeSchema = z15.enum(["per_customer", "per_email_domain"]).meta(
|
|
3078
|
-
{ id: "TrialEligibilityScope", "x-revturbine-schema-persistence": Transient12, "x-revturbine-schema-exposure":
|
|
3171
|
+
{ id: "TrialEligibilityScope", "x-revturbine-schema-persistence": Transient12, "x-revturbine-schema-exposure": Internal10 }
|
|
3079
3172
|
);
|
|
3080
3173
|
var FreeTrialSettingsSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
3081
3174
|
trial_limit_policy: TrialLimitPolicySchema.default("1_per_lifetime").meta(Unrestricted12),
|
|
3082
3175
|
eligibility_scope: TrialEligibilityScopeSchema.default("per_customer").meta(Unrestricted12)
|
|
3083
3176
|
}).meta(
|
|
3084
|
-
{ id: "FreeTrialSettings", "x-revturbine-schema-persistence": Persisted12, "x-revturbine-schema-exposure":
|
|
3177
|
+
{ id: "FreeTrialSettings", "x-revturbine-schema-persistence": Persisted12, "x-revturbine-schema-exposure": Internal10, ...PENDING_PLAYBOOK_SDK_FACETS2 }
|
|
3085
3178
|
);
|
|
3086
3179
|
var ReverseTrialSettingsSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
3087
3180
|
trial_limit_policy: TrialLimitPolicySchema.default("1_per_lifetime").meta(Unrestricted12),
|
|
3088
3181
|
eligibility_scope: TrialEligibilityScopeSchema.default("per_customer").meta(Unrestricted12)
|
|
3089
3182
|
}).meta(
|
|
3090
|
-
{ id: "ReverseTrialSettings", "x-revturbine-schema-persistence": Persisted12, "x-revturbine-schema-exposure":
|
|
3183
|
+
{ id: "ReverseTrialSettings", "x-revturbine-schema-persistence": Persisted12, "x-revturbine-schema-exposure": Internal10, ...PENDING_PLAYBOOK_SDK_FACETS2 }
|
|
3091
3184
|
);
|
|
3092
3185
|
var TrialInstanceSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
3093
3186
|
customer_id: z15.string().min(1).meta(Unrestricted12),
|
|
@@ -3127,7 +3220,7 @@ var TrialInstanceSchema = IdField.merge(TimestampFields).merge(TenantIdField).ex
|
|
|
3127
3220
|
cancelled_at: NullableDatetimeField.meta(Unrestricted12),
|
|
3128
3221
|
metadata: MetadataField.meta(Unrestricted12)
|
|
3129
3222
|
}).meta(
|
|
3130
|
-
{ id: "TrialInstance", "x-revturbine-schema-persistence": Persisted12, "x-revturbine-schema-exposure":
|
|
3223
|
+
{ id: "TrialInstance", "x-revturbine-schema-persistence": Persisted12, "x-revturbine-schema-exposure": Internal10 }
|
|
3131
3224
|
);
|
|
3132
3225
|
var trialPaths = {
|
|
3133
3226
|
"/api/free-trial-rule-anchors": {
|
|
@@ -3364,16 +3457,16 @@ var trialPaths = {
|
|
|
3364
3457
|
};
|
|
3365
3458
|
var { Unrestricted: Unrestricted13 } = DataClassification;
|
|
3366
3459
|
var { Persisted: Persisted13, Transient: Transient13 } = SchemaPersistence;
|
|
3367
|
-
var { Internal:
|
|
3460
|
+
var { Internal: Internal11 } = SchemaExposure;
|
|
3368
3461
|
var PENDING_PLAYBOOK_SDK_FACETS3 = schemaFacets(SchemaContext.Playbook, {
|
|
3369
3462
|
inConfig: false,
|
|
3370
3463
|
sdkInput: true
|
|
3371
3464
|
});
|
|
3372
3465
|
var ExperimentStatusSchema = z16.enum(["draft", "ramping", "winning", "neutral", "needs_attention", "paused", "complete"]).meta(
|
|
3373
|
-
{ id: "ExperimentStatus", "x-revturbine-schema-persistence": Transient13, "x-revturbine-schema-exposure":
|
|
3466
|
+
{ id: "ExperimentStatus", "x-revturbine-schema-persistence": Transient13, "x-revturbine-schema-exposure": Internal11 }
|
|
3374
3467
|
);
|
|
3375
3468
|
var ExperimentTypeSchema = z16.enum(["placement_ab", "entitlement_ab", "plan_ab", "pricing_ab", "custom"]).meta(
|
|
3376
|
-
{ id: "ExperimentType", "x-revturbine-schema-persistence": Transient13, "x-revturbine-schema-exposure":
|
|
3469
|
+
{ id: "ExperimentType", "x-revturbine-schema-persistence": Transient13, "x-revturbine-schema-exposure": Internal11 }
|
|
3377
3470
|
);
|
|
3378
3471
|
var ExperimentVariantSchema = z16.object({
|
|
3379
3472
|
variant_id: z16.string().min(1),
|
|
@@ -3382,7 +3475,7 @@ var ExperimentVariantSchema = z16.object({
|
|
|
3382
3475
|
is_control: z16.boolean().default(false),
|
|
3383
3476
|
config: z16.record(z16.string(), z16.unknown()).default({})
|
|
3384
3477
|
}).meta(
|
|
3385
|
-
{ id: "ExperimentVariant", "x-revturbine-schema-persistence": Persisted13, "x-revturbine-schema-exposure":
|
|
3478
|
+
{ id: "ExperimentVariant", "x-revturbine-schema-persistence": Persisted13, "x-revturbine-schema-exposure": Internal11, ...PENDING_PLAYBOOK_SDK_FACETS3 }
|
|
3386
3479
|
);
|
|
3387
3480
|
var ExperimentSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(AnchorFields).merge(VersionFields).extend({
|
|
3388
3481
|
anchor_id: z16.string().min(1).meta({ ...Unrestricted13, readOnly: true }),
|
|
@@ -3406,7 +3499,7 @@ var ExperimentSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge
|
|
|
3406
3499
|
winning_variant_id: z16.string().nullable().default(null).meta(Unrestricted13),
|
|
3407
3500
|
metadata: MetadataField.meta(Unrestricted13)
|
|
3408
3501
|
}).meta(
|
|
3409
|
-
{ id: "Experiment", "x-revturbine-schema-persistence": Persisted13, "x-revturbine-schema-exposure":
|
|
3502
|
+
{ id: "Experiment", "x-revturbine-schema-persistence": Persisted13, "x-revturbine-schema-exposure": Internal11, ...PENDING_PLAYBOOK_SDK_FACETS3, ...namedIdentity() }
|
|
3410
3503
|
);
|
|
3411
3504
|
var ExperimentAnchorSchema = makeAnchor("ExperimentAnchor");
|
|
3412
3505
|
var SuggestionSeveritySchema = SeveritySchema;
|
|
@@ -3422,7 +3515,7 @@ var OptimizationSuggestionSchema = IdField.merge(TimestampFields).merge(TenantId
|
|
|
3422
3515
|
is_dismissed: z16.boolean().default(false).meta(Unrestricted13),
|
|
3423
3516
|
metadata: MetadataField.meta(Unrestricted13)
|
|
3424
3517
|
}).meta(
|
|
3425
|
-
{ id: "OptimizationSuggestion", "x-revturbine-schema-persistence": Persisted13, "x-revturbine-schema-exposure":
|
|
3518
|
+
{ id: "OptimizationSuggestion", "x-revturbine-schema-persistence": Persisted13, "x-revturbine-schema-exposure": Internal11 }
|
|
3426
3519
|
);
|
|
3427
3520
|
var experimentPaths = {
|
|
3428
3521
|
"/api/experiment-anchors": {
|
|
@@ -3535,15 +3628,15 @@ var experimentPaths = {
|
|
|
3535
3628
|
})
|
|
3536
3629
|
}
|
|
3537
3630
|
};
|
|
3538
|
-
var { Unrestricted: Unrestricted14, Financial:
|
|
3631
|
+
var { Unrestricted: Unrestricted14, Financial: Financial4 } = DataClassification;
|
|
3539
3632
|
var { Persisted: Persisted14, Transient: Transient14 } = SchemaPersistence;
|
|
3540
|
-
var { Internal:
|
|
3633
|
+
var { Internal: Internal12 } = SchemaExposure;
|
|
3541
3634
|
var PLAYBOOK_SDK_FACETS7 = schemaFacets(SchemaContext.Playbook, { sdkInput: true });
|
|
3542
3635
|
var PromotionStatusSchema = z17.enum(["draft", "scheduled", "live", "expired", "archived"]).meta(
|
|
3543
|
-
{ id: "PromotionStatus", "x-revturbine-schema-persistence": Transient14, "x-revturbine-schema-exposure":
|
|
3636
|
+
{ id: "PromotionStatus", "x-revturbine-schema-persistence": Transient14, "x-revturbine-schema-exposure": Internal12 }
|
|
3544
3637
|
);
|
|
3545
3638
|
var DiscountTypeSchema = z17.enum(["percentage", "fixed_amount", "free_months"]).meta(
|
|
3546
|
-
{ id: "DiscountType", "x-revturbine-schema-persistence": Transient14, "x-revturbine-schema-exposure":
|
|
3639
|
+
{ id: "DiscountType", "x-revturbine-schema-persistence": Transient14, "x-revturbine-schema-exposure": Internal12 }
|
|
3547
3640
|
);
|
|
3548
3641
|
var PromotionSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(AnchorFields).merge(VersionFields).extend({
|
|
3549
3642
|
anchor_id: z17.string().min(1).meta({ ...Unrestricted14, readOnly: true }),
|
|
@@ -3552,8 +3645,8 @@ var PromotionSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(
|
|
|
3552
3645
|
description: z17.string().max(1e3).optional().meta(Unrestricted14),
|
|
3553
3646
|
rt_status: PromotionStatusSchema.default("draft").meta(Unrestricted14),
|
|
3554
3647
|
discount_type: DiscountTypeSchema.meta(Unrestricted14),
|
|
3555
|
-
discount_value: z17.number().min(0).meta(
|
|
3556
|
-
currency: z17.string().length(3).default("USD").meta(
|
|
3648
|
+
discount_value: z17.number().min(0).meta(Financial4),
|
|
3649
|
+
currency: z17.string().length(3).default("USD").meta(Financial4),
|
|
3557
3650
|
applicable_plan_ids: z17.array(z17.string()).default([]).meta(Unrestricted14),
|
|
3558
3651
|
applicable_addon_ids: z17.array(z17.string()).default([]).meta(Unrestricted14),
|
|
3559
3652
|
target_segment_ids: z17.array(z17.string()).default([]).meta(Unrestricted14),
|
|
@@ -3568,7 +3661,7 @@ var PromotionSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(
|
|
|
3568
3661
|
auto_sync_stripe: z17.boolean().default(false).meta(Unrestricted14),
|
|
3569
3662
|
metadata: MetadataField.meta(Unrestricted14)
|
|
3570
3663
|
}).meta(
|
|
3571
|
-
{ id: "Promotion", "x-revturbine-schema-persistence": Persisted14, "x-revturbine-schema-exposure":
|
|
3664
|
+
{ id: "Promotion", "x-revturbine-schema-persistence": Persisted14, "x-revturbine-schema-exposure": Internal12, ...PLAYBOOK_SDK_FACETS7, ...namedIdentity() }
|
|
3572
3665
|
);
|
|
3573
3666
|
var PromotionAnchorSchema = makeAnchor("PromotionAnchor");
|
|
3574
3667
|
var promotionPaths = {
|
|
@@ -3653,7 +3746,7 @@ var promotionPaths = {
|
|
|
3653
3746
|
};
|
|
3654
3747
|
var { Unrestricted: Unrestricted15, Pii: Pii5 } = DataClassification;
|
|
3655
3748
|
var { Persisted: Persisted15, Transient: Transient15 } = SchemaPersistence;
|
|
3656
|
-
var { Internal:
|
|
3749
|
+
var { Internal: Internal13, External: External10 } = SchemaExposure;
|
|
3657
3750
|
var PresentationRecordSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
3658
3751
|
customer_id: z18.string().min(1).meta(Pii5),
|
|
3659
3752
|
placement_id: z18.string().min(1).meta(Unrestricted15),
|
|
@@ -3668,7 +3761,7 @@ var PresentationRecordSchema = IdField.merge(TimestampFields).merge(TenantIdFiel
|
|
|
3668
3761
|
session_id: z18.string().optional().meta(Unrestricted15),
|
|
3669
3762
|
metadata: MetadataField.meta(Unrestricted15)
|
|
3670
3763
|
}).meta(
|
|
3671
|
-
{ id: "PresentationRecord", "x-revturbine-schema-persistence": Persisted15, "x-revturbine-schema-exposure":
|
|
3764
|
+
{ id: "PresentationRecord", "x-revturbine-schema-persistence": Persisted15, "x-revturbine-schema-exposure": Internal13 }
|
|
3672
3765
|
);
|
|
3673
3766
|
var DecisionLogSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
3674
3767
|
customer_id: z18.string().min(1).meta(Pii5),
|
|
@@ -3684,7 +3777,7 @@ var DecisionLogSchema = IdField.merge(TimestampFields).merge(TenantIdField).exte
|
|
|
3684
3777
|
variant_id: z18.string().nullable().default(null).meta(Unrestricted15),
|
|
3685
3778
|
latency_ms: z18.number().min(0).optional().meta(Unrestricted15)
|
|
3686
3779
|
}).meta(
|
|
3687
|
-
{ id: "DecisionLog", "x-revturbine-schema-persistence": Persisted15, "x-revturbine-schema-exposure":
|
|
3780
|
+
{ id: "DecisionLog", "x-revturbine-schema-persistence": Persisted15, "x-revturbine-schema-exposure": Internal13 }
|
|
3688
3781
|
);
|
|
3689
3782
|
var EntitlementEvalLogSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
3690
3783
|
customer_id: z18.string().min(1).meta(Pii5),
|
|
@@ -3697,7 +3790,7 @@ var EntitlementEvalLogSchema = IdField.merge(TimestampFields).merge(TenantIdFiel
|
|
|
3697
3790
|
source_id: z18.string().min(1).meta(Unrestricted15),
|
|
3698
3791
|
latency_ms: z18.number().min(0).optional().meta(Unrestricted15)
|
|
3699
3792
|
}).meta(
|
|
3700
|
-
{ id: "EntitlementEvalLog", "x-revturbine-schema-persistence": Persisted15, "x-revturbine-schema-exposure":
|
|
3793
|
+
{ id: "EntitlementEvalLog", "x-revturbine-schema-persistence": Persisted15, "x-revturbine-schema-exposure": Internal13 }
|
|
3701
3794
|
);
|
|
3702
3795
|
var runtimePaths = {
|
|
3703
3796
|
"/api/presentation-records": {
|
|
@@ -3733,7 +3826,7 @@ var runtimePaths = {
|
|
|
3733
3826
|
};
|
|
3734
3827
|
var { Unrestricted: Unrestricted16 } = DataClassification;
|
|
3735
3828
|
var { Persisted: Persisted16, Transient: Transient16 } = SchemaPersistence;
|
|
3736
|
-
var { Internal:
|
|
3829
|
+
var { Internal: Internal14, External: External11 } = SchemaExposure;
|
|
3737
3830
|
var PLAYBOOK_SDK_FACETS8 = schemaFacets(SchemaContext.Playbook, { sdkInput: true });
|
|
3738
3831
|
var PLAYBOOK_AUTHORING_FACETS2 = schemaFacets(SchemaContext.Playbook, { sdkInput: false });
|
|
3739
3832
|
var PENDING_PLAYBOOK_FACETS4 = schemaFacets(SchemaContext.Playbook, {
|
|
@@ -3776,7 +3869,7 @@ var SeatTypeSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(A
|
|
|
3776
3869
|
entitlement_ids: z19.array(z19.string()).default([]).meta(Unrestricted16),
|
|
3777
3870
|
metadata: MetadataField.meta(Unrestricted16)
|
|
3778
3871
|
}).meta(
|
|
3779
|
-
{ id: "SeatType", "x-revturbine-schema-persistence": Persisted16, "x-revturbine-schema-exposure":
|
|
3872
|
+
{ id: "SeatType", "x-revturbine-schema-persistence": Persisted16, "x-revturbine-schema-exposure": Internal14, ...PENDING_PLAYBOOK_FACETS4, ...namedIdentity() }
|
|
3780
3873
|
);
|
|
3781
3874
|
var SeatTypeAnchorSchema = makeAnchor("SeatTypeAnchor");
|
|
3782
3875
|
var PersonalizationTokenSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(AnchorFields).merge(VersionFields).extend({
|
|
@@ -3791,10 +3884,10 @@ var PersonalizationTokenSchema = IdField.merge(TimestampFields).merge(TenantIdFi
|
|
|
3791
3884
|
format: z19.enum(["string", "number", "currency", "percentage", "date"]).nullable().default(null).meta(Unrestricted16),
|
|
3792
3885
|
metadata: MetadataField.meta(Unrestricted16)
|
|
3793
3886
|
}).meta(
|
|
3794
|
-
{ id: "PersonalizationToken", "x-revturbine-schema-persistence": Persisted16, "x-revturbine-schema-exposure":
|
|
3887
|
+
{ id: "PersonalizationToken", "x-revturbine-schema-persistence": Persisted16, "x-revturbine-schema-exposure": Internal14, ...PENDING_PLAYBOOK_FACETS4, ...namedIdentity() }
|
|
3795
3888
|
);
|
|
3796
3889
|
var PersonalizationTokenAnchorSchema = makeAnchor("PersonalizationTokenAnchor");
|
|
3797
|
-
var OnboardingStateSchema = z19.enum(["not_started", "started", "details_submitted", "charges_enabled", "activated", "deauthorized"]).meta({ id: "OnboardingState", "x-revturbine-schema-persistence": Transient16, "x-revturbine-schema-exposure":
|
|
3890
|
+
var OnboardingStateSchema = z19.enum(["not_started", "started", "details_submitted", "charges_enabled", "activated", "deauthorized"]).meta({ id: "OnboardingState", "x-revturbine-schema-persistence": Transient16, "x-revturbine-schema-exposure": Internal14 });
|
|
3798
3891
|
var StripeIntegrationConfigSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(AnchorFields).merge(VersionFields).extend({
|
|
3799
3892
|
handle: HandleField.meta({ ...Unrestricted16, readOnly: true }),
|
|
3800
3893
|
stripe_account_id: z19.string().min(1).meta(Unrestricted16),
|
|
@@ -3820,7 +3913,7 @@ var StripeIntegrationConfigSchema = IdField.merge(TimestampFields).merge(TenantI
|
|
|
3820
3913
|
last_sync_at: z19.string().optional().meta({ ...Unrestricted16, readOnly: true }),
|
|
3821
3914
|
metadata: MetadataField.meta(Unrestricted16)
|
|
3822
3915
|
}).meta(
|
|
3823
|
-
{ id: "StripeIntegrationConfig", "x-revturbine-schema-persistence": Persisted16, "x-revturbine-schema-exposure":
|
|
3916
|
+
{ id: "StripeIntegrationConfig", "x-revturbine-schema-persistence": Persisted16, "x-revturbine-schema-exposure": Internal14, ...BILLING_FACETS2, ...mintedIdentity() }
|
|
3824
3917
|
);
|
|
3825
3918
|
var BrandingConfigSchema = z19.object({
|
|
3826
3919
|
theme: z19.record(z19.string(), z19.unknown()).optional().meta(Unrestricted16),
|
|
@@ -3845,10 +3938,10 @@ var MeteringConfigSchema = IdField.merge(TimestampFields).merge(TenantIdField).m
|
|
|
3845
3938
|
is_active: z19.boolean().default(true).meta(Unrestricted16),
|
|
3846
3939
|
metadata: MetadataField.meta(Unrestricted16)
|
|
3847
3940
|
}).meta(
|
|
3848
|
-
{ id: "MeteringConfig", "x-revturbine-schema-persistence": Persisted16, "x-revturbine-schema-exposure":
|
|
3941
|
+
{ id: "MeteringConfig", "x-revturbine-schema-persistence": Persisted16, "x-revturbine-schema-exposure": Internal14, ...METERING_FACETS, ...mintedIdentity() }
|
|
3849
3942
|
);
|
|
3850
3943
|
var EnforcementActionSchema = z19.enum(["block", "warn", "downgrade", "throttle", "notify_admin", "custom"]).meta(
|
|
3851
|
-
{ id: "EnforcementAction", "x-revturbine-schema-persistence": Transient16, "x-revturbine-schema-exposure":
|
|
3944
|
+
{ id: "EnforcementAction", "x-revturbine-schema-persistence": Transient16, "x-revturbine-schema-exposure": Internal14 }
|
|
3852
3945
|
);
|
|
3853
3946
|
var UsageEnforcementSettingsSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(AnchorFields).merge(VersionFields).extend({
|
|
3854
3947
|
anchor_id: z19.string().min(1).meta({ ...Unrestricted16, readOnly: true }),
|
|
@@ -3862,7 +3955,7 @@ var UsageEnforcementSettingsSchema = IdField.merge(TimestampFields).merge(Tenant
|
|
|
3862
3955
|
notification_channels: z19.array(z19.enum(["email", "in_app", "webhook"])).default(["in_app"]).meta(Unrestricted16),
|
|
3863
3956
|
is_active: z19.boolean().default(true).meta(Unrestricted16)
|
|
3864
3957
|
}).meta(
|
|
3865
|
-
{ id: "UsageEnforcementSettings", "x-revturbine-schema-persistence": Persisted16, "x-revturbine-schema-exposure":
|
|
3958
|
+
{ id: "UsageEnforcementSettings", "x-revturbine-schema-persistence": Persisted16, "x-revturbine-schema-exposure": Internal14, ...PENDING_PLAYBOOK_SDK_FACETS4, ...mintedIdentity() }
|
|
3866
3959
|
);
|
|
3867
3960
|
var UsageEnforcementSettingsAnchorSchema = makeAnchor("UsageEnforcementSettingsAnchor");
|
|
3868
3961
|
var PlacementSettingsCapRuleGroupItemSchema = z19.object({
|
|
@@ -3870,7 +3963,7 @@ var PlacementSettingsCapRuleGroupItemSchema = z19.object({
|
|
|
3870
3963
|
id: z19.string().min(1).meta(Unrestricted16),
|
|
3871
3964
|
label: z19.string().min(1).optional().meta(Unrestricted16)
|
|
3872
3965
|
}).meta(
|
|
3873
|
-
{ id: "PlacementSettingsCapRuleGroupItem", "x-revturbine-schema-persistence": Transient16, "x-revturbine-schema-exposure":
|
|
3966
|
+
{ id: "PlacementSettingsCapRuleGroupItem", "x-revturbine-schema-persistence": Transient16, "x-revturbine-schema-exposure": Internal14 }
|
|
3874
3967
|
);
|
|
3875
3968
|
var PlacementSettingsCapRuleSchema = z19.object({
|
|
3876
3969
|
id: z19.string().min(1).meta(Unrestricted16),
|
|
@@ -3880,17 +3973,21 @@ var PlacementSettingsCapRuleSchema = z19.object({
|
|
|
3880
3973
|
period: z19.enum(["session", "day", "week", "month"]).meta(Unrestricted16)
|
|
3881
3974
|
}).meta(Unrestricted16)
|
|
3882
3975
|
}).meta(
|
|
3883
|
-
{ id: "PlacementSettingsCapRule", "x-revturbine-schema-persistence": Transient16, "x-revturbine-schema-exposure":
|
|
3976
|
+
{ id: "PlacementSettingsCapRule", "x-revturbine-schema-persistence": Transient16, "x-revturbine-schema-exposure": Internal14 }
|
|
3884
3977
|
);
|
|
3885
3978
|
var PlacementTestModeSchema = z19.enum(["off", "test_users", "all_traffic"]).meta(
|
|
3886
|
-
{ id: "PlacementTestMode", "x-revturbine-schema-persistence": Transient16, "x-revturbine-schema-exposure":
|
|
3979
|
+
{ id: "PlacementTestMode", "x-revturbine-schema-persistence": Transient16, "x-revturbine-schema-exposure": Internal14 }
|
|
3887
3980
|
);
|
|
3888
3981
|
var PlacementSettingsCapStateSchema = z19.object({
|
|
3889
3982
|
capRules: z19.array(PlacementSettingsCapRuleSchema).default([]).meta(Unrestricted16),
|
|
3890
3983
|
sessionCooldownMinutes: z19.number().int().min(0).default(30).meta(Unrestricted16),
|
|
3984
|
+
// Tenant-level default remind-me-later (defer) window, in minutes. A
|
|
3985
|
+
// per-payload `remind_later_minutes` overrides it when set (plan 167 REQ-6,
|
|
3986
|
+
// Q-3). Rides in this global_frequency_cap jsonb wrapper — no column/`.fbs`.
|
|
3987
|
+
remindLaterMinutes: z19.number().int().min(0).default(60).meta(Unrestricted16),
|
|
3891
3988
|
testMode: PlacementTestModeSchema.default("off").meta(Unrestricted16)
|
|
3892
3989
|
}).meta(
|
|
3893
|
-
{ id: "PlacementSettingsCapState", "x-revturbine-schema-persistence": Transient16, "x-revturbine-schema-exposure":
|
|
3990
|
+
{ id: "PlacementSettingsCapState", "x-revturbine-schema-persistence": Transient16, "x-revturbine-schema-exposure": Internal14 }
|
|
3894
3991
|
);
|
|
3895
3992
|
var PlacementSettingsSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(AnchorFields).merge(VersionFields).extend({
|
|
3896
3993
|
anchor_id: z19.string().min(1).meta({ ...Unrestricted16, readOnly: true }),
|
|
@@ -3902,11 +3999,12 @@ var PlacementSettingsSchema = IdField.merge(TimestampFields).merge(TenantIdField
|
|
|
3902
3999
|
global_frequency_cap_period: z19.enum(["hour", "day", "week", "month", "session"]).nullable().default(null).meta(Unrestricted16),
|
|
3903
4000
|
suppress_for_paid: z19.boolean().default(false).meta(Unrestricted16),
|
|
3904
4001
|
suppress_for_trial: z19.boolean().default(false).meta(Unrestricted16),
|
|
3905
|
-
default_dismiss_cooldown_hours
|
|
4002
|
+
// `default_dismiss_cooldown_hours` removed (plan 167 Q-2): the dismiss
|
|
4003
|
+
// cooldown is defined per-payload in days (`cooldown_after_dismiss_days`).
|
|
3906
4004
|
allow_stacking: z19.boolean().default(false).meta(Unrestricted16),
|
|
3907
4005
|
priority_collision_strategy: z19.enum(["highest_priority", "most_recent", "random"]).default("highest_priority").meta(Unrestricted16)
|
|
3908
4006
|
}).meta(
|
|
3909
|
-
{ id: "PlacementSettings", "x-revturbine-schema-persistence": Persisted16, "x-revturbine-schema-exposure":
|
|
4007
|
+
{ id: "PlacementSettings", "x-revturbine-schema-persistence": Persisted16, "x-revturbine-schema-exposure": Internal14, ...PENDING_PLAYBOOK_SDK_FACETS4, ...mintedIdentity() }
|
|
3910
4008
|
);
|
|
3911
4009
|
var PlacementSettingsAnchorSchema = makeAnchor("PlacementSettingsAnchor");
|
|
3912
4010
|
var RevTurbineConfigSegmentsItemPredicatesItemSchema = z19.object({
|
|
@@ -4014,7 +4112,7 @@ var RevTurbineConfigPlacementSettingsItemSchema = z19.object({
|
|
|
4014
4112
|
global_frequency_cap_period: z19.enum(["hour", "day", "week", "month", "session"]).nullable().default(null).meta(Unrestricted16),
|
|
4015
4113
|
suppress_for_paid: z19.boolean().default(false).meta(Unrestricted16),
|
|
4016
4114
|
suppress_for_trial: z19.boolean().default(false).meta(Unrestricted16),
|
|
4017
|
-
default_dismiss_cooldown_hours
|
|
4115
|
+
// `default_dismiss_cooldown_hours` removed (plan 167 Q-2).
|
|
4018
4116
|
allow_stacking: z19.boolean().default(false).meta(Unrestricted16),
|
|
4019
4117
|
priority_collision_strategy: z19.string().nullable().default(null).meta(Unrestricted16)
|
|
4020
4118
|
}).meta(
|
|
@@ -4156,7 +4254,11 @@ var RevTurbineConfigUiPathActionTypeSchema = z19.enum([
|
|
|
4156
4254
|
"verify_work_email",
|
|
4157
4255
|
"update_payment_method",
|
|
4158
4256
|
"enable_auto_renewal",
|
|
4159
|
-
"manage_subscription"
|
|
4257
|
+
"manage_subscription",
|
|
4258
|
+
// Authored `snooze` resolves through to the SDK's remind-later path
|
|
4259
|
+
// (plan 167 windows); previously it fell through as an invalid type
|
|
4260
|
+
// (plan 174 TASK-6 / Q-5, spec-check F-65a).
|
|
4261
|
+
"snooze"
|
|
4160
4262
|
]).meta(
|
|
4161
4263
|
{ id: "RevTurbineConfigUiPathActionType", "x-revturbine-schema-persistence": Transient16, "x-revturbine-schema-exposure": External11 }
|
|
4162
4264
|
);
|
|
@@ -4265,6 +4367,8 @@ var RevTurbineConfigStudioPayloadSchema = z19.object({
|
|
|
4265
4367
|
caps: RevTurbineConfigStudioPayloadCapsSchema.optional().meta(Unrestricted16),
|
|
4266
4368
|
// Optional slot targeting (spec §3.1.1): empty/absent = any compatible slot.
|
|
4267
4369
|
surface_slot_ids: z19.array(z19.string()).optional().meta(Unrestricted16),
|
|
4370
|
+
// Per-payload remind-me-later override (minutes); absent = inherit tenant default (plan 167 Q-3).
|
|
4371
|
+
remind_later_minutes: z19.number().int().min(0).nullable().optional().meta(Unrestricted16),
|
|
4268
4372
|
created_at: z19.string().optional().meta({ ...Unrestricted16, readOnly: true }),
|
|
4269
4373
|
recommendation_strategy: z19.enum(["next_tier_up", "best_value", "custom"]).optional().default("next_tier_up").meta(Unrestricted16),
|
|
4270
4374
|
recommendation_plan_override: z19.string().optional().meta(Unrestricted16)
|
|
@@ -4304,6 +4408,8 @@ var RevTurbineConfigPlacementPayloadItemSchema = z19.object({
|
|
|
4304
4408
|
placement_id: z19.string().min(1).meta(Unrestricted16),
|
|
4305
4409
|
target: RevTurbineConfigStudioPayloadTargetSchema.meta(Unrestricted16),
|
|
4306
4410
|
caps: RevTurbineConfigStudioPayloadCapsSchema.optional().meta(Unrestricted16),
|
|
4411
|
+
// Per-payload remind-me-later override (minutes); absent = inherit tenant default (plan 167 Q-3).
|
|
4412
|
+
remind_later_minutes: z19.number().int().min(0).nullable().optional().meta(Unrestricted16),
|
|
4307
4413
|
created_at: z19.string().meta({ ...Unrestricted16, readOnly: true }),
|
|
4308
4414
|
updated_at: z19.string().datetime().optional().meta({ ...Unrestricted16, readOnly: true }),
|
|
4309
4415
|
source_mode: z19.enum(["inline", "content_linked"]).meta(Unrestricted16),
|
|
@@ -4534,6 +4640,12 @@ var PlaybookSchema = z19.preprocess(normalizeConfigHeaderInput, PlaybookObjectSc
|
|
|
4534
4640
|
"x-revturbine-schema-exposure": External11,
|
|
4535
4641
|
...PLAYBOOK_SDK_FACETS8
|
|
4536
4642
|
});
|
|
4643
|
+
var PlaybookStrictSchema = z19.preprocess(normalizeConfigHeaderInput, PlaybookObjectSchema.strict()).meta({
|
|
4644
|
+
id: "PlaybookStrict",
|
|
4645
|
+
"x-revturbine-schema-persistence": Transient16,
|
|
4646
|
+
"x-revturbine-schema-exposure": External11,
|
|
4647
|
+
...PLAYBOOK_SDK_FACETS8
|
|
4648
|
+
});
|
|
4537
4649
|
var RevTurbineConfigSchema = PlaybookSchema;
|
|
4538
4650
|
var configPaths = {
|
|
4539
4651
|
"/api/seat-type-anchors": {
|
|
@@ -4773,9 +4885,9 @@ var configPaths = {
|
|
|
4773
4885
|
};
|
|
4774
4886
|
var { Unrestricted: Unrestricted17 } = DataClassification;
|
|
4775
4887
|
var { Persisted: Persisted17 } = SchemaPersistence;
|
|
4776
|
-
var { Internal:
|
|
4888
|
+
var { Internal: Internal15 } = SchemaExposure;
|
|
4777
4889
|
var ChangeLogActionSchema = z20.enum(["create", "update", "delete", "archive", "restore", "reorder", "duplicate", "sync", "publish"]).meta(
|
|
4778
|
-
{ id: "ChangeLogAction", "x-revturbine-schema-persistence": Persisted17, "x-revturbine-schema-exposure":
|
|
4890
|
+
{ id: "ChangeLogAction", "x-revturbine-schema-persistence": Persisted17, "x-revturbine-schema-exposure": Internal15 }
|
|
4779
4891
|
);
|
|
4780
4892
|
var ChangeLogEntrySchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
4781
4893
|
action: ChangeLogActionSchema.meta(Unrestricted17),
|
|
@@ -4791,7 +4903,7 @@ var ChangeLogEntrySchema = IdField.merge(TimestampFields).merge(TenantIdField).e
|
|
|
4791
4903
|
summary: z20.string().max(1e3).optional().meta(Unrestricted17),
|
|
4792
4904
|
metadata: MetadataField.meta(Unrestricted17)
|
|
4793
4905
|
}).meta(
|
|
4794
|
-
{ id: "ChangeLogEntry", "x-revturbine-schema-persistence": Persisted17, "x-revturbine-schema-exposure":
|
|
4906
|
+
{ id: "ChangeLogEntry", "x-revturbine-schema-persistence": Persisted17, "x-revturbine-schema-exposure": Internal15 }
|
|
4795
4907
|
);
|
|
4796
4908
|
var changelogPaths = {
|
|
4797
4909
|
"/api/changelog": {
|
|
@@ -4817,9 +4929,9 @@ var changelogPaths = {
|
|
|
4817
4929
|
};
|
|
4818
4930
|
var { Unrestricted: Unrestricted18 } = DataClassification;
|
|
4819
4931
|
var { Persisted: Persisted18, Transient: Transient17 } = SchemaPersistence;
|
|
4820
|
-
var { Internal:
|
|
4932
|
+
var { Internal: Internal16 } = SchemaExposure;
|
|
4821
4933
|
var TenantStatusSchema = z21.enum(["active", "suspended", "archived"]).meta(
|
|
4822
|
-
{ id: "TenantStatus", "x-revturbine-schema-persistence": Transient17, "x-revturbine-schema-exposure":
|
|
4934
|
+
{ id: "TenantStatus", "x-revturbine-schema-persistence": Transient17, "x-revturbine-schema-exposure": Internal16 }
|
|
4823
4935
|
);
|
|
4824
4936
|
var TenantSchema = IdField.merge(TimestampFields).extend({
|
|
4825
4937
|
name: NameField.meta(Unrestricted18),
|
|
@@ -4827,7 +4939,7 @@ var TenantSchema = IdField.merge(TimestampFields).extend({
|
|
|
4827
4939
|
status: TenantStatusSchema.default("active").meta(Unrestricted18),
|
|
4828
4940
|
metadata: MetadataField.meta(Unrestricted18)
|
|
4829
4941
|
}).meta(
|
|
4830
|
-
{ id: "Tenant", "x-revturbine-schema-persistence": Persisted18, "x-revturbine-schema-exposure":
|
|
4942
|
+
{ id: "Tenant", "x-revturbine-schema-persistence": Persisted18, "x-revturbine-schema-exposure": Internal16 }
|
|
4831
4943
|
);
|
|
4832
4944
|
var tenantPaths = {
|
|
4833
4945
|
"/api/tenants": {
|
|
@@ -4893,9 +5005,9 @@ var tenantPaths = {
|
|
|
4893
5005
|
};
|
|
4894
5006
|
var { Unrestricted: Unrestricted19 } = DataClassification;
|
|
4895
5007
|
var { Persisted: Persisted19, Transient: Transient18 } = SchemaPersistence;
|
|
4896
|
-
var { Internal:
|
|
5008
|
+
var { Internal: Internal17 } = SchemaExposure;
|
|
4897
5009
|
var EnvironmentStatusSchema = z22.enum(["active", "archived", "locked"]).meta(
|
|
4898
|
-
{ id: "EnvironmentStatus", "x-revturbine-schema-persistence": Transient18, "x-revturbine-schema-exposure":
|
|
5010
|
+
{ id: "EnvironmentStatus", "x-revturbine-schema-persistence": Transient18, "x-revturbine-schema-exposure": Internal17 }
|
|
4899
5011
|
);
|
|
4900
5012
|
var EnvironmentSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
4901
5013
|
name: NameField.meta(Unrestricted19),
|
|
@@ -4914,7 +5026,7 @@ var EnvironmentSchema = IdField.merge(TimestampFields).merge(TenantIdField).exte
|
|
|
4914
5026
|
created_by: z22.string().optional().meta(Unrestricted19),
|
|
4915
5027
|
metadata: MetadataField.meta(Unrestricted19)
|
|
4916
5028
|
}).meta(
|
|
4917
|
-
{ id: "Environment", "x-revturbine-schema-persistence": Persisted19, "x-revturbine-schema-exposure":
|
|
5029
|
+
{ id: "Environment", "x-revturbine-schema-persistence": Persisted19, "x-revturbine-schema-exposure": Internal17 }
|
|
4918
5030
|
);
|
|
4919
5031
|
var EnvironmentPromotionRequestSchema = z22.object({
|
|
4920
5032
|
source_environment_id: z22.string().min(1),
|
|
@@ -4922,7 +5034,7 @@ var EnvironmentPromotionRequestSchema = z22.object({
|
|
|
4922
5034
|
playbook_version_ids: z22.array(z22.string()).optional(),
|
|
4923
5035
|
strategy: z22.enum(["all_current", "selected_playbook_versions"]).default("all_current")
|
|
4924
5036
|
}).meta(
|
|
4925
|
-
{ id: "EnvironmentPromotionRequest", "x-revturbine-schema-persistence": Transient18, "x-revturbine-schema-exposure":
|
|
5037
|
+
{ id: "EnvironmentPromotionRequest", "x-revturbine-schema-persistence": Transient18, "x-revturbine-schema-exposure": Internal17 }
|
|
4926
5038
|
);
|
|
4927
5039
|
var environmentPaths = {
|
|
4928
5040
|
"/api/environments": {
|
|
@@ -5101,7 +5213,7 @@ var ServerEvaluationPayloadSchema = z23.object({
|
|
|
5101
5213
|
}).meta({ id: "ServerEvaluationPayload", "x-revturbine-schema-persistence": Transient19, "x-revturbine-schema-exposure": External12 });
|
|
5102
5214
|
var { Unrestricted: Unrestricted21 } = DataClassification;
|
|
5103
5215
|
var { Persisted: Persisted21, Transient: Transient20 } = SchemaPersistence;
|
|
5104
|
-
var { Internal:
|
|
5216
|
+
var { Internal: Internal18 } = SchemaExposure;
|
|
5105
5217
|
var PlaybookVersionStatusSchema = z24.enum([
|
|
5106
5218
|
"draft",
|
|
5107
5219
|
"awaiting_approval",
|
|
@@ -5111,7 +5223,7 @@ var PlaybookVersionStatusSchema = z24.enum([
|
|
|
5111
5223
|
"rejected",
|
|
5112
5224
|
"archived"
|
|
5113
5225
|
]).meta(
|
|
5114
|
-
{ id: "PlaybookVersionStatus", "x-revturbine-schema-persistence": Transient20, "x-revturbine-schema-exposure":
|
|
5226
|
+
{ id: "PlaybookVersionStatus", "x-revturbine-schema-persistence": Transient20, "x-revturbine-schema-exposure": Internal18 }
|
|
5115
5227
|
);
|
|
5116
5228
|
var PlaybookVersionSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
5117
5229
|
environment_id: z24.string().min(1).meta(Unrestricted21),
|
|
@@ -5148,7 +5260,7 @@ var PlaybookVersionSchema = IdField.merge(TimestampFields).merge(TenantIdField).
|
|
|
5148
5260
|
bundle: z24.string().nullable().default(null).meta({ ...Unrestricted21, readOnly: true }),
|
|
5149
5261
|
metadata: MetadataField.meta(Unrestricted21)
|
|
5150
5262
|
}).meta(
|
|
5151
|
-
{ id: "PlaybookVersion", "x-revturbine-schema-persistence": Persisted21, "x-revturbine-schema-exposure":
|
|
5263
|
+
{ id: "PlaybookVersion", "x-revturbine-schema-persistence": Persisted21, "x-revturbine-schema-exposure": Internal18 }
|
|
5152
5264
|
);
|
|
5153
5265
|
var PlaybookVersionEntrySummarySchema = z24.object({
|
|
5154
5266
|
handle: z24.string().meta(Unrestricted21),
|
|
@@ -5157,7 +5269,7 @@ var PlaybookVersionEntrySummarySchema = z24.object({
|
|
|
5157
5269
|
action: z24.enum(["create", "update", "delete"]).meta(Unrestricted21),
|
|
5158
5270
|
has_conflict: z24.boolean().meta(Unrestricted21)
|
|
5159
5271
|
}).meta(
|
|
5160
|
-
{ id: "PlaybookVersionEntrySummary", "x-revturbine-schema-persistence": Transient20, "x-revturbine-schema-exposure":
|
|
5272
|
+
{ id: "PlaybookVersionEntrySummary", "x-revturbine-schema-persistence": Transient20, "x-revturbine-schema-exposure": Internal18 }
|
|
5161
5273
|
);
|
|
5162
5274
|
var PlaybookVersionDiffSchema = z24.object({
|
|
5163
5275
|
playbook_version_id: z24.string().meta(Unrestricted21),
|
|
@@ -5166,7 +5278,7 @@ var PlaybookVersionDiffSchema = z24.object({
|
|
|
5166
5278
|
total_conflicts: z24.number().int().min(0).meta(Unrestricted21),
|
|
5167
5279
|
deployable: z24.boolean().meta(Unrestricted21)
|
|
5168
5280
|
}).meta(
|
|
5169
|
-
{ id: "PlaybookVersionDiff", "x-revturbine-schema-persistence": Transient20, "x-revturbine-schema-exposure":
|
|
5281
|
+
{ id: "PlaybookVersionDiff", "x-revturbine-schema-persistence": Transient20, "x-revturbine-schema-exposure": Internal18 }
|
|
5170
5282
|
);
|
|
5171
5283
|
var PlaybookVersionDeployResultSchema = z24.object({
|
|
5172
5284
|
playbook_version_id: z24.string().meta(Unrestricted21),
|
|
@@ -5175,7 +5287,7 @@ var PlaybookVersionDeployResultSchema = z24.object({
|
|
|
5175
5287
|
skipped_conflicts: z24.number().int().min(0).meta(Unrestricted21),
|
|
5176
5288
|
deployed_at: z24.string().datetime().meta(Unrestricted21)
|
|
5177
5289
|
}).meta(
|
|
5178
|
-
{ id: "PlaybookVersionDeployResult", "x-revturbine-schema-persistence": Transient20, "x-revturbine-schema-exposure":
|
|
5290
|
+
{ id: "PlaybookVersionDeployResult", "x-revturbine-schema-persistence": Transient20, "x-revturbine-schema-exposure": Internal18 }
|
|
5179
5291
|
);
|
|
5180
5292
|
var playbookVersionPaths = {
|
|
5181
5293
|
// ── Lifecycle transitions ────────────────────────────────────────────────
|
|
@@ -5302,8 +5414,8 @@ var playbookVersionPaths = {
|
|
|
5302
5414
|
};
|
|
5303
5415
|
var { Unrestricted: Unrestricted22, Pii: Pii7 } = DataClassification;
|
|
5304
5416
|
var { Persisted: Persisted22 } = SchemaPersistence;
|
|
5305
|
-
var { Internal:
|
|
5306
|
-
var ApiKeyStatusSchema = z25.enum(["active", "revoked", "rotating"]).meta({ id: "ApiKeyStatus", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure":
|
|
5417
|
+
var { Internal: Internal19 } = SchemaExposure;
|
|
5418
|
+
var ApiKeyStatusSchema = z25.enum(["active", "revoked", "rotating"]).meta({ id: "ApiKeyStatus", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure": Internal19 });
|
|
5307
5419
|
var ApiKeySchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
5308
5420
|
name: NameField.meta(Unrestricted22),
|
|
5309
5421
|
key_hash: z25.string().min(1).meta({ ...Pii7, readOnly: true }),
|
|
@@ -5312,22 +5424,22 @@ var ApiKeySchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
|
5312
5424
|
status: ApiKeyStatusSchema.default("active").meta(Unrestricted22),
|
|
5313
5425
|
last_used_at: NullableDatetimeField.meta({ ...Unrestricted22, readOnly: true }),
|
|
5314
5426
|
expires_at: NullableDatetimeField.meta(Unrestricted22)
|
|
5315
|
-
}).meta({ id: "ApiKey", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure":
|
|
5316
|
-
var FlagValueTypeSchema = z25.enum(["boolean", "string", "number", "json"]).meta({ id: "FlagValueType", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure":
|
|
5427
|
+
}).meta({ id: "ApiKey", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure": Internal19 });
|
|
5428
|
+
var FlagValueTypeSchema = z25.enum(["boolean", "string", "number", "json"]).meta({ id: "FlagValueType", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure": Internal19 });
|
|
5317
5429
|
var FeatureFlagSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
5318
5430
|
key: z25.string().min(1).max(100).meta(Unrestricted22),
|
|
5319
5431
|
value_type: FlagValueTypeSchema.default("boolean").meta(Unrestricted22),
|
|
5320
5432
|
value: z25.string().max(4e3).default("false").meta(Unrestricted22),
|
|
5321
5433
|
description: DescriptionField.meta(Unrestricted22),
|
|
5322
5434
|
enabled: z25.boolean().default(true).meta(Unrestricted22)
|
|
5323
|
-
}).meta({ id: "FeatureFlag", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure":
|
|
5435
|
+
}).meta({ id: "FeatureFlag", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure": Internal19 });
|
|
5324
5436
|
var TenantConfigSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
5325
5437
|
workspace_name: z25.string().min(1).max(200).meta(Unrestricted22),
|
|
5326
5438
|
support_email: z25.string().email().nullable().default(null).meta(Unrestricted22),
|
|
5327
5439
|
timezone: z25.string().max(50).default("UTC").meta(Unrestricted22),
|
|
5328
5440
|
default_currency: z25.string().length(3).default("USD").meta(Unrestricted22),
|
|
5329
5441
|
logo_url: z25.string().url().nullable().default(null).meta(Unrestricted22)
|
|
5330
|
-
}).meta({ id: "TenantConfig", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure":
|
|
5442
|
+
}).meta({ id: "TenantConfig", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure": Internal19 });
|
|
5331
5443
|
var McpConfigSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
5332
5444
|
/** @deprecated Plan 28 ships a hosted MCP server at `/api/mcp/streamable-http`; no outbound server URL is needed. Column remains for backward compatibility. */
|
|
5333
5445
|
server_url: z25.string().url().max(500).meta(Unrestricted22),
|
|
@@ -5336,14 +5448,14 @@ var McpConfigSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend
|
|
|
5336
5448
|
allow_write_actions: z25.boolean().default(false).meta(Unrestricted22),
|
|
5337
5449
|
enabled_tools: z25.array(z25.string().max(100)).default([]).meta(Unrestricted22),
|
|
5338
5450
|
enabled: z25.boolean().default(false).meta(Unrestricted22)
|
|
5339
|
-
}).meta({ id: "McpConfig", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure":
|
|
5451
|
+
}).meta({ id: "McpConfig", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure": Internal19 });
|
|
5340
5452
|
var OnboardingChecklistSchema = IdField.merge(TimestampFields).merge(TenantIdField).extend({
|
|
5341
5453
|
step_key: z25.string().min(1).max(100).meta(Unrestricted22),
|
|
5342
5454
|
label: z25.string().min(1).max(200).meta(Unrestricted22),
|
|
5343
5455
|
done: z25.boolean().default(false).meta(Unrestricted22),
|
|
5344
5456
|
completed_at: NullableDatetimeField.meta({ ...Unrestricted22, readOnly: true })
|
|
5345
|
-
}).meta({ id: "OnboardingChecklist", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure":
|
|
5346
|
-
var AuditActorTypeSchema = z25.enum(["user", "agent", "system", "webhook"]).meta({ id: "AuditActorType", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure":
|
|
5457
|
+
}).meta({ id: "OnboardingChecklist", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure": Internal19 });
|
|
5458
|
+
var AuditActorTypeSchema = z25.enum(["user", "agent", "system", "webhook"]).meta({ id: "AuditActorType", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure": Internal19 });
|
|
5347
5459
|
var AuditEventSchema = IdField.merge(TenantIdField).extend({
|
|
5348
5460
|
environment_id: z25.string().min(1).default("production").meta(Unrestricted22),
|
|
5349
5461
|
actor_type: AuditActorTypeSchema.meta(Unrestricted22),
|
|
@@ -5353,15 +5465,15 @@ var AuditEventSchema = IdField.merge(TenantIdField).extend({
|
|
|
5353
5465
|
object_id: z25.string().max(200).nullable().default(null).meta(Unrestricted22),
|
|
5354
5466
|
payload: z25.record(z25.string(), z25.unknown()).nullable().default(null).meta(Unrestricted22),
|
|
5355
5467
|
occurred_at: z25.string().datetime().meta({ ...Unrestricted22, readOnly: true })
|
|
5356
|
-
}).meta({ id: "AuditEvent", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure":
|
|
5357
|
-
var PlacementTestUserIdentifierTypeSchema = z25.enum(["user_id", "account_id", "email"]).meta({ id: "PlacementTestUserIdentifierType", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure":
|
|
5468
|
+
}).meta({ id: "AuditEvent", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure": Internal19 });
|
|
5469
|
+
var PlacementTestUserIdentifierTypeSchema = z25.enum(["user_id", "account_id", "email"]).meta({ id: "PlacementTestUserIdentifierType", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure": Internal19 });
|
|
5358
5470
|
var PlacementTestUserSchema = IdField.merge(TimestampFields).merge(TenantIdField).merge(AnchorFields).merge(VersionFields).extend({
|
|
5359
5471
|
handle: HandleField.meta({ ...Unrestricted22, readOnly: true }),
|
|
5360
5472
|
identifier: z25.string().min(1).max(200).meta(Unrestricted22),
|
|
5361
5473
|
identifier_type: PlacementTestUserIdentifierTypeSchema.default("user_id").meta(Unrestricted22),
|
|
5362
5474
|
note: z25.string().max(500).nullable().default(null).meta(Unrestricted22),
|
|
5363
5475
|
added_by: z25.string().meta(Unrestricted22)
|
|
5364
|
-
}).meta({ id: "PlacementTestUser", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure":
|
|
5476
|
+
}).meta({ id: "PlacementTestUser", "x-revturbine-schema-persistence": Persisted22, "x-revturbine-schema-exposure": Internal19, ...mintedIdentity() });
|
|
5365
5477
|
var settingsPaths = {
|
|
5366
5478
|
// ── API Keys ─────────────────────────────────────────────────────────────
|
|
5367
5479
|
"/api/settings/api-keys": {
|
|
@@ -5547,8 +5659,8 @@ var settingsPaths = {
|
|
|
5547
5659
|
};
|
|
5548
5660
|
var { Unrestricted: Unrestricted23, Pii: Pii8 } = DataClassification;
|
|
5549
5661
|
var { Persisted: Persisted23, Transient: Transient21 } = SchemaPersistence;
|
|
5550
|
-
var { Internal:
|
|
5551
|
-
var UserRoleSchema = z26.enum(["user", "admin"]).meta({ id: "UserRole", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5662
|
+
var { Internal: Internal20 } = SchemaExposure;
|
|
5663
|
+
var UserRoleSchema = z26.enum(["user", "admin"]).meta({ id: "UserRole", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5552
5664
|
var AuthUserSchema = IdField.merge(TimestampFields).extend({
|
|
5553
5665
|
name: NameField.meta(Unrestricted23),
|
|
5554
5666
|
email: z26.string().email().meta(Pii8),
|
|
@@ -5559,7 +5671,7 @@ var AuthUserSchema = IdField.merge(TimestampFields).extend({
|
|
|
5559
5671
|
ban_reason: z26.string().nullable().default(null).meta({ ...Unrestricted23, readOnly: true }),
|
|
5560
5672
|
ban_expires: NullableDatetimeField.meta({ ...Unrestricted23, readOnly: true }),
|
|
5561
5673
|
two_factor_enabled: z26.boolean().default(false).meta({ ...Unrestricted23, readOnly: true })
|
|
5562
|
-
}).meta({ id: "AuthUser", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5674
|
+
}).meta({ id: "AuthUser", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5563
5675
|
var AuthSessionSchema = IdField.merge(TimestampFields).extend({
|
|
5564
5676
|
expires_at: z26.string().datetime().meta(Unrestricted23),
|
|
5565
5677
|
token: z26.string().min(1).meta({ ...Pii8, readOnly: true }),
|
|
@@ -5568,7 +5680,7 @@ var AuthSessionSchema = IdField.merge(TimestampFields).extend({
|
|
|
5568
5680
|
user_id: z26.string().min(1).meta({ ...Unrestricted23, readOnly: true }),
|
|
5569
5681
|
active_organization_id: z26.string().nullable().default(null).meta(Unrestricted23),
|
|
5570
5682
|
impersonated_by: z26.string().nullable().default(null).meta({ ...Unrestricted23, readOnly: true })
|
|
5571
|
-
}).meta({ id: "AuthSession", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5683
|
+
}).meta({ id: "AuthSession", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5572
5684
|
var AuthAccountSchema = IdField.merge(TimestampFields).extend({
|
|
5573
5685
|
account_id: z26.string().min(1).meta(Unrestricted23),
|
|
5574
5686
|
provider_id: z26.string().min(1).meta(Unrestricted23),
|
|
@@ -5580,26 +5692,26 @@ var AuthAccountSchema = IdField.merge(TimestampFields).extend({
|
|
|
5580
5692
|
refresh_token_expires_at: NullableDatetimeField.meta({ ...Unrestricted23, readOnly: true }),
|
|
5581
5693
|
scope: z26.string().nullable().default(null).meta(Unrestricted23),
|
|
5582
5694
|
password: z26.string().nullable().default(null).meta({ ...Pii8, readOnly: true })
|
|
5583
|
-
}).meta({ id: "AuthAccount", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5695
|
+
}).meta({ id: "AuthAccount", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5584
5696
|
var AuthVerificationSchema = IdField.merge(TimestampFields).extend({
|
|
5585
5697
|
identifier: z26.string().min(1).meta(Pii8),
|
|
5586
5698
|
value: z26.string().min(1).meta({ ...Pii8, readOnly: true }),
|
|
5587
5699
|
expires_at: z26.string().datetime().meta(Unrestricted23)
|
|
5588
|
-
}).meta({ id: "AuthVerification", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5700
|
+
}).meta({ id: "AuthVerification", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5589
5701
|
var AuthTwoFactorSchema = IdField.extend({
|
|
5590
5702
|
secret: z26.string().min(1).meta({ ...Pii8, readOnly: true }),
|
|
5591
5703
|
backup_codes: z26.string().min(1).meta({ ...Pii8, readOnly: true }),
|
|
5592
5704
|
user_id: z26.string().min(1).meta({ ...Unrestricted23, readOnly: true }),
|
|
5593
5705
|
verified: z26.boolean().default(false).meta({ ...Unrestricted23, readOnly: true })
|
|
5594
|
-
}).meta({ id: "AuthTwoFactor", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5706
|
+
}).meta({ id: "AuthTwoFactor", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5595
5707
|
var AuthOrganizationSchema = IdField.extend({
|
|
5596
5708
|
name: NameField.meta(Unrestricted23),
|
|
5597
5709
|
slug: z26.string().min(1).max(100).nullable().default(null).meta(Unrestricted23),
|
|
5598
5710
|
logo: z26.string().url().nullable().default(null).meta(Unrestricted23),
|
|
5599
5711
|
created_at: z26.string().datetime().meta({ ...Unrestricted23, readOnly: true }),
|
|
5600
5712
|
metadata: z26.string().nullable().default(null).meta(Unrestricted23)
|
|
5601
|
-
}).meta({ id: "AuthOrganization", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5602
|
-
var RoleSchema = z26.enum(["viewer", "collaborator", "approver", "admin"]).meta({ id: "Role", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5713
|
+
}).meta({ id: "AuthOrganization", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5714
|
+
var RoleSchema = z26.enum(["viewer", "collaborator", "approver", "admin"]).meta({ id: "Role", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5603
5715
|
var PermissionResourceSchema = z26.enum([
|
|
5604
5716
|
"tenant",
|
|
5605
5717
|
"users",
|
|
@@ -5614,7 +5726,7 @@ var PermissionResourceSchema = z26.enum([
|
|
|
5614
5726
|
"mcp",
|
|
5615
5727
|
"api_tokens",
|
|
5616
5728
|
"settings"
|
|
5617
|
-
]).meta({ id: "PermissionResource", "x-revturbine-schema-persistence": Transient21, "x-revturbine-schema-exposure":
|
|
5729
|
+
]).meta({ id: "PermissionResource", "x-revturbine-schema-persistence": Transient21, "x-revturbine-schema-exposure": Internal20 });
|
|
5618
5730
|
var PermissionActionSchema = z26.enum([
|
|
5619
5731
|
"read",
|
|
5620
5732
|
"create",
|
|
@@ -5624,11 +5736,11 @@ var PermissionActionSchema = z26.enum([
|
|
|
5624
5736
|
"approve",
|
|
5625
5737
|
"invite",
|
|
5626
5738
|
"manage_roles"
|
|
5627
|
-
]).meta({ id: "PermissionAction", "x-revturbine-schema-persistence": Transient21, "x-revturbine-schema-exposure":
|
|
5739
|
+
]).meta({ id: "PermissionAction", "x-revturbine-schema-persistence": Transient21, "x-revturbine-schema-exposure": Internal20 });
|
|
5628
5740
|
var PermissionSchema = z26.object({
|
|
5629
5741
|
resource: PermissionResourceSchema,
|
|
5630
5742
|
action: PermissionActionSchema
|
|
5631
|
-
}).meta({ id: "Permission", "x-revturbine-schema-persistence": Transient21, "x-revturbine-schema-exposure":
|
|
5743
|
+
}).meta({ id: "Permission", "x-revturbine-schema-persistence": Transient21, "x-revturbine-schema-exposure": Internal20 });
|
|
5632
5744
|
var VIEWER_RESOURCES = [
|
|
5633
5745
|
"tenant",
|
|
5634
5746
|
"plans",
|
|
@@ -5697,14 +5809,14 @@ var ADMIN_PERMS = expand(ADMIN_FULL, ADMIN_ACTIONS);
|
|
|
5697
5809
|
var SCOPE_VALUES = PermissionResourceSchema.options.flatMap(
|
|
5698
5810
|
(resource) => PermissionActionSchema.options.map((action) => `${resource}:${action}`)
|
|
5699
5811
|
);
|
|
5700
|
-
var McpTokenScopeSchema = z26.enum(SCOPE_VALUES).meta({ id: "McpTokenScope", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5812
|
+
var McpTokenScopeSchema = z26.enum(SCOPE_VALUES).meta({ id: "McpTokenScope", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5701
5813
|
var AuthMemberSchema = IdField.extend({
|
|
5702
5814
|
organization_id: z26.string().min(1).meta({ ...Unrestricted23, readOnly: true }),
|
|
5703
5815
|
user_id: z26.string().min(1).meta({ ...Unrestricted23, readOnly: true }),
|
|
5704
5816
|
role: RoleSchema.default("viewer").meta(Unrestricted23),
|
|
5705
5817
|
created_at: z26.string().datetime().meta({ ...Unrestricted23, readOnly: true })
|
|
5706
|
-
}).meta({ id: "AuthMember", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5707
|
-
var InvitationStatusSchema = z26.enum(["pending", "accepted", "rejected", "canceled", "expired"]).meta({ id: "InvitationStatus", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5818
|
+
}).meta({ id: "AuthMember", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5819
|
+
var InvitationStatusSchema = z26.enum(["pending", "accepted", "rejected", "canceled", "expired"]).meta({ id: "InvitationStatus", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5708
5820
|
var AuthInvitationSchema = IdField.extend({
|
|
5709
5821
|
organization_id: z26.string().min(1).meta({ ...Unrestricted23, readOnly: true }),
|
|
5710
5822
|
email: z26.string().email().meta(Pii8),
|
|
@@ -5713,7 +5825,7 @@ var AuthInvitationSchema = IdField.extend({
|
|
|
5713
5825
|
expires_at: z26.string().datetime().meta(Unrestricted23),
|
|
5714
5826
|
created_at: z26.string().datetime().meta({ ...Unrestricted23, readOnly: true }),
|
|
5715
5827
|
inviter_id: z26.string().min(1).meta({ ...Unrestricted23, readOnly: true })
|
|
5716
|
-
}).meta({ id: "AuthInvitation", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5828
|
+
}).meta({ id: "AuthInvitation", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5717
5829
|
var AuthPasskeySchema = IdField.extend({
|
|
5718
5830
|
name: z26.string().max(200).nullable().default(null).meta(Unrestricted23),
|
|
5719
5831
|
public_key: z26.string().min(1).meta({ ...Pii8, readOnly: true }),
|
|
@@ -5725,7 +5837,7 @@ var AuthPasskeySchema = IdField.extend({
|
|
|
5725
5837
|
transports: z26.string().nullable().default(null).meta(Unrestricted23),
|
|
5726
5838
|
created_at: z26.string().datetime().meta({ ...Unrestricted23, readOnly: true }),
|
|
5727
5839
|
aaguid: z26.string().nullable().default(null).meta(Unrestricted23)
|
|
5728
|
-
}).meta({ id: "AuthPasskey", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5840
|
+
}).meta({ id: "AuthPasskey", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5729
5841
|
var AuthApiKeySchema = IdField.merge(TimestampFields).extend({
|
|
5730
5842
|
config_id: z26.string().min(1).meta(Unrestricted23),
|
|
5731
5843
|
name: z26.string().max(200).nullable().default(null).meta(Unrestricted23),
|
|
@@ -5746,7 +5858,7 @@ var AuthApiKeySchema = IdField.merge(TimestampFields).extend({
|
|
|
5746
5858
|
expires_at: NullableDatetimeField.meta(Unrestricted23),
|
|
5747
5859
|
permissions: z26.string().nullable().default(null).meta(Unrestricted23),
|
|
5748
5860
|
metadata: z26.string().nullable().default(null).meta(Unrestricted23)
|
|
5749
|
-
}).meta({ id: "AuthApiKey", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5861
|
+
}).meta({ id: "AuthApiKey", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5750
5862
|
var AuthSsoProviderSchema = IdField.extend({
|
|
5751
5863
|
issuer: z26.string().min(1).meta(Unrestricted23),
|
|
5752
5864
|
oidc_config: z26.string().nullable().default(null).meta(Unrestricted23),
|
|
@@ -5755,7 +5867,7 @@ var AuthSsoProviderSchema = IdField.extend({
|
|
|
5755
5867
|
provider_id: z26.string().min(1).meta(Unrestricted23),
|
|
5756
5868
|
organization_id: z26.string().nullable().default(null).meta(Unrestricted23),
|
|
5757
5869
|
domain: z26.string().min(1).meta(Unrestricted23)
|
|
5758
|
-
}).meta({ id: "AuthSsoProvider", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure":
|
|
5870
|
+
}).meta({ id: "AuthSsoProvider", "x-revturbine-schema-persistence": Persisted23, "x-revturbine-schema-exposure": Internal20 });
|
|
5759
5871
|
|
|
5760
5872
|
// src/schema/validators.snapshot.mjs
|
|
5761
5873
|
import { z as z27 } from "zod";
|
|
@@ -5827,19 +5939,53 @@ var CATALOG = {
|
|
|
5827
5939
|
message: "Plan '{plan}' has no Stripe price linked.",
|
|
5828
5940
|
specRef: "optimization-studio-ui.md \xA73.1; plans-entitlements-studio-ui.md \xA72.2"
|
|
5829
5941
|
},
|
|
5830
|
-
// entitlement-rule overlap. Origin: the `rule.overlap` check (plan 40)
|
|
5942
|
+
// entitlement-rule overlap. Origin: the `rule.overlap` check (plan 40);
|
|
5943
|
+
// scoped to same-entitlement pairs per §5.8 (plan 179 / devkit #597).
|
|
5831
5944
|
"VAL-PLN-05": {
|
|
5832
5945
|
id: "VAL-PLN-05",
|
|
5833
5946
|
severity: "warning",
|
|
5834
|
-
message: "These entitlement
|
|
5947
|
+
message: "These rules for the same entitlement target the same plan and segment \u2014 only one will apply.",
|
|
5835
5948
|
specRef: "config-validation.md \xA75.3 (provisional \u2014 plan 73 Q-1)"
|
|
5836
5949
|
},
|
|
5950
|
+
// limit rule with unset enforcement. Promoted from §5.8 (plan 179 Q-6,
|
|
5951
|
+
// Kent 2026-08-12): unset enforcement silently means "hard-block at the
|
|
5952
|
+
// cap" (evaluator default since plan 34) — an author who wanted degrade or
|
|
5953
|
+
// allow_overage gets a hard stop without being told. Explicitness warn on
|
|
5954
|
+
// the corrected premise (the old "never blocks" mechanism was the SDK
|
|
5955
|
+
// ignoring allowed:false, fixed in sdk 0.2.75).
|
|
5956
|
+
"VAL-PLN-07": {
|
|
5957
|
+
id: "VAL-PLN-07",
|
|
5958
|
+
severity: "warning",
|
|
5959
|
+
message: "This limit rule sets no enforcement \u2014 at the cap it blocks by default. Set enforcement explicitly (hard_block, soft_block, degrade, allow_overage) if that isn't the intent.",
|
|
5960
|
+
specRef: "config-validation.md \xA75.8 (promoted \u2014 plan 179 Q-6)"
|
|
5961
|
+
},
|
|
5837
5962
|
// multiple public variations. Origin: `*_variation.multiple_public`.
|
|
5838
5963
|
"VAL-PLN-06": {
|
|
5839
5964
|
id: "VAL-PLN-06",
|
|
5840
5965
|
severity: "error_draft",
|
|
5841
5966
|
message: "Only one public variation is allowed per billing period and segment.",
|
|
5842
5967
|
specRef: "config-validation.md \xA75.3 (provisional \u2014 plan 73 Q-1)"
|
|
5968
|
+
},
|
|
5969
|
+
// more-than-two CTAs on a payload surface. Promoted from §5.8 (plan 174
|
|
5970
|
+
// TASK-7 / devkit #584): the decision output carries ONE cta_path (from
|
|
5971
|
+
// ctas[0]); ctas[1] contributes secondary_cta_label only; ctas[2..] are
|
|
5972
|
+
// dropped at resolution with no finding.
|
|
5973
|
+
"VAL-PLC-05": {
|
|
5974
|
+
id: "VAL-PLC-05",
|
|
5975
|
+
severity: "warning",
|
|
5976
|
+
message: "Payload '{payload}' authors {count} CTAs, but the decision output carries one primary path and one secondary label \u2014 the third and later CTAs are dropped at resolution.",
|
|
5977
|
+
specRef: "config-validation.md \xA75.8 (promoted \u2014 plan 174 TASK-7)"
|
|
5978
|
+
},
|
|
5979
|
+
// widest-possible-audience trial rule. Promoted from §5.8 (plan 174 TASK-7 /
|
|
5980
|
+
// devkit #584): plan and segment on a free trial rule NARROW, so null on
|
|
5981
|
+
// both means every user on every plan — legal and occasionally intended,
|
|
5982
|
+
// but indistinguishable from an unfinished rule after authoring. Reverse
|
|
5983
|
+
// trial rules can't hit this (premium_plan_id is required).
|
|
5984
|
+
"VAL-TRL-04": {
|
|
5985
|
+
id: "VAL-TRL-04",
|
|
5986
|
+
severity: "warning",
|
|
5987
|
+
message: "Trial rule '{rule}' targets every user on every plan (no plan, no segment). Confirm the widest possible audience is intended.",
|
|
5988
|
+
specRef: "config-validation.md \xA75.8 (promoted \u2014 plan 174 TASK-7)"
|
|
5843
5989
|
}
|
|
5844
5990
|
};
|
|
5845
5991
|
function getCatalogEntry(id) {
|
|
@@ -5849,9 +5995,85 @@ function runSemanticRules(graph) {
|
|
|
5849
5995
|
return [
|
|
5850
5996
|
...checkPlansHaveStripePrice(graph),
|
|
5851
5997
|
...checkRuleOverlaps(graph),
|
|
5852
|
-
...
|
|
5998
|
+
...checkLimitRuleEnforcement(graph),
|
|
5999
|
+
...checkPublicVariationCollisions(graph),
|
|
6000
|
+
...checkPayloadCtaOverflow(graph),
|
|
6001
|
+
...checkTrialRuleWidestAudience(graph)
|
|
5853
6002
|
];
|
|
5854
6003
|
}
|
|
6004
|
+
function checkLimitRuleEnforcement(graph) {
|
|
6005
|
+
const findings = [];
|
|
6006
|
+
const CAP_FIELDS = ["limit_value", "allowance_value", "included_count"];
|
|
6007
|
+
for (const rule of graph.entitlement_rules ?? []) {
|
|
6008
|
+
if (rule.enforcement !== void 0 && rule.enforcement !== null) continue;
|
|
6009
|
+
const cappedField = CAP_FIELDS.find((f) => typeof rule[f] === "number" && Number.isFinite(rule[f]));
|
|
6010
|
+
if (!cappedField) continue;
|
|
6011
|
+
const id = String(rule.handle ?? rule.id ?? "");
|
|
6012
|
+
const name = String(rule.name ?? id);
|
|
6013
|
+
findings.push(
|
|
6014
|
+
finding(
|
|
6015
|
+
"VAL-PLN-07",
|
|
6016
|
+
{ object_type: "entitlement_rule", object_id: id, field: "enforcement", studio: "plans-entitlements" },
|
|
6017
|
+
{
|
|
6018
|
+
message: `Limit rule '${name}' sets no enforcement \u2014 at the cap it blocks by default. Set enforcement explicitly (hard_block, soft_block, degrade, allow_overage) if that isn't the intent.`
|
|
6019
|
+
}
|
|
6020
|
+
)
|
|
6021
|
+
);
|
|
6022
|
+
}
|
|
6023
|
+
return findings;
|
|
6024
|
+
}
|
|
6025
|
+
function surfaceCtas(surface) {
|
|
6026
|
+
if (!surface || typeof surface !== "object") return 0;
|
|
6027
|
+
const ctas = surface.ctas;
|
|
6028
|
+
return Array.isArray(ctas) ? ctas.length : 0;
|
|
6029
|
+
}
|
|
6030
|
+
function checkPayloadCtaOverflow(graph) {
|
|
6031
|
+
const findings = [];
|
|
6032
|
+
const flag = (payloadId, count, objectType) => {
|
|
6033
|
+
findings.push(
|
|
6034
|
+
finding("VAL-PLC-05", { object_type: objectType, object_id: payloadId, field: "ctas", studio: "placements" }, {
|
|
6035
|
+
message: `Payload '${payloadId}' authors ${count} CTAs, but the decision output carries one primary path and one secondary label \u2014 the third and later CTAs are dropped at resolution.`
|
|
6036
|
+
})
|
|
6037
|
+
);
|
|
6038
|
+
};
|
|
6039
|
+
for (const placement of graph.placements ?? []) {
|
|
6040
|
+
const payloads = Array.isArray(placement.payloads) ? placement.payloads : [];
|
|
6041
|
+
for (const payload of payloads) {
|
|
6042
|
+
const payloadId = String(payload.id ?? placement.id ?? "");
|
|
6043
|
+
const surfaces = Array.isArray(payload.surfaces) ? payload.surfaces : [];
|
|
6044
|
+
for (const surface of surfaces) {
|
|
6045
|
+
const count = surfaceCtas(surface);
|
|
6046
|
+
if (count > 2) flag(payloadId, count, "placement_payload");
|
|
6047
|
+
}
|
|
6048
|
+
}
|
|
6049
|
+
}
|
|
6050
|
+
for (const payload of graph.placement_payloads ?? []) {
|
|
6051
|
+
const payloadId = String(payload.payload_id ?? payload.id ?? "");
|
|
6052
|
+
const surfaces = Array.isArray(payload.surfaces) ? payload.surfaces : [];
|
|
6053
|
+
for (const surface of surfaces) {
|
|
6054
|
+
const count = surfaceCtas(surface);
|
|
6055
|
+
if (count > 2) flag(payloadId, count, "placement_payload");
|
|
6056
|
+
}
|
|
6057
|
+
}
|
|
6058
|
+
return findings;
|
|
6059
|
+
}
|
|
6060
|
+
function checkTrialRuleWidestAudience(graph) {
|
|
6061
|
+
const findings = [];
|
|
6062
|
+
for (const rule of graph.free_trial_rules ?? []) {
|
|
6063
|
+
const planId = rule.plan_id;
|
|
6064
|
+
const segmentId = rule.segment_id;
|
|
6065
|
+
const planUnset = planId === null || planId === void 0 || planId === "";
|
|
6066
|
+
const segmentUnset = segmentId === null || segmentId === void 0 || segmentId === "";
|
|
6067
|
+
if (!planUnset || !segmentUnset) continue;
|
|
6068
|
+
const ruleId = String(rule.handle ?? rule.id ?? "");
|
|
6069
|
+
findings.push(
|
|
6070
|
+
finding("VAL-TRL-04", { object_type: "free_trial_rule", object_id: ruleId, studio: "trials" }, {
|
|
6071
|
+
message: `Trial rule '${ruleId || "unnamed"}' targets every user on every plan (no plan, no segment). Confirm the widest possible audience is intended.`
|
|
6072
|
+
})
|
|
6073
|
+
);
|
|
6074
|
+
}
|
|
6075
|
+
return findings;
|
|
6076
|
+
}
|
|
5855
6077
|
function finding(catalogId, target, opts = {}) {
|
|
5856
6078
|
const entry = getCatalogEntry(catalogId);
|
|
5857
6079
|
const severity = entry?.severity ?? "warning";
|
|
@@ -5915,6 +6137,7 @@ function checkRuleOverlaps(graph) {
|
|
|
5915
6137
|
const sigs = [];
|
|
5916
6138
|
for (const rule of rules) {
|
|
5917
6139
|
const id = String(rule.handle ?? rule.id ?? "");
|
|
6140
|
+
const entitlementId = typeof rule.entitlement_id === "string" ? rule.entitlement_id : "";
|
|
5918
6141
|
const targetIds = /* @__PURE__ */ new Set();
|
|
5919
6142
|
if (Array.isArray(rule.targets)) {
|
|
5920
6143
|
for (const t of rule.targets) {
|
|
@@ -5942,6 +6165,7 @@ function checkRuleOverlaps(graph) {
|
|
|
5942
6165
|
sigs.push({
|
|
5943
6166
|
rule,
|
|
5944
6167
|
id,
|
|
6168
|
+
entitlementId,
|
|
5945
6169
|
targetIds,
|
|
5946
6170
|
segmentPairs,
|
|
5947
6171
|
matchesAllSegments: segmentIds.length === 0
|
|
@@ -5952,6 +6176,7 @@ function checkRuleOverlaps(graph) {
|
|
|
5952
6176
|
for (let j = i + 1; j < sigs.length; j++) {
|
|
5953
6177
|
const a = sigs[i];
|
|
5954
6178
|
const b = sigs[j];
|
|
6179
|
+
if (!a.entitlementId || a.entitlementId !== b.entitlementId) continue;
|
|
5955
6180
|
let sharedTarget = false;
|
|
5956
6181
|
for (const t of a.targetIds) {
|
|
5957
6182
|
if (b.targetIds.has(t)) {
|
|
@@ -5990,7 +6215,7 @@ function checkRuleOverlaps(graph) {
|
|
|
5990
6215
|
studio: "plans-entitlements"
|
|
5991
6216
|
},
|
|
5992
6217
|
{
|
|
5993
|
-
message: `Entitlement rule '${name}' overlaps another rule on a shared target and segment \u2014 only one will apply.`,
|
|
6218
|
+
message: `Entitlement rule '${name}' overlaps another rule for the same entitlement on a shared target and segment \u2014 only one will apply.`,
|
|
5994
6219
|
detail: "Where rules overlap, the most permissive value applies (plans-entitlements-studio-ui.md \xA72.3.2). Adjust the segment selection if this is unintended."
|
|
5995
6220
|
}
|
|
5996
6221
|
)
|
|
@@ -6055,8 +6280,12 @@ function messageForZodIssue(issue) {
|
|
|
6055
6280
|
switch (issue.code) {
|
|
6056
6281
|
case "invalid_type":
|
|
6057
6282
|
return issue.input === void 0 ? `${field} is required.` : `${field} must be a ${issue.expected ?? "valid value"}.`;
|
|
6058
|
-
case "invalid_value":
|
|
6059
|
-
|
|
6283
|
+
case "invalid_value": {
|
|
6284
|
+
const values = (issue.values ?? []).filter(
|
|
6285
|
+
(v) => ["string", "number", "boolean"].includes(typeof v)
|
|
6286
|
+
);
|
|
6287
|
+
return values.length > 0 ? `${field} must be one of: ${values.map((v) => `'${String(v)}'`).join(", ")}.` : `${field} must be one of the allowed values.`;
|
|
6288
|
+
}
|
|
6060
6289
|
case "invalid_format":
|
|
6061
6290
|
return `${field} isn't in a valid format.`;
|
|
6062
6291
|
case "too_small":
|
|
@@ -6116,7 +6345,12 @@ var DataClassification2 = {
|
|
|
6116
6345
|
Financial: { "x-revturbine-data-classification": "financial" },
|
|
6117
6346
|
Unrestricted: { "x-revturbine-data-classification": "unrestricted" }
|
|
6118
6347
|
};
|
|
6348
|
+
var SCHEMA_EXPOSURE_META_KEY2 = "x-revturbine-schema-exposure";
|
|
6119
6349
|
var READ_ONLY_META_KEY2 = "readOnly";
|
|
6350
|
+
var DECISION_ONLY_META_KEY2 = "x-revturbine-decision-only";
|
|
6351
|
+
var DecisionOnly2 = { [DECISION_ONLY_META_KEY2]: true };
|
|
6352
|
+
var ClientSafe2 = { [SCHEMA_EXPOSURE_META_KEY2]: SchemaExposure2.External };
|
|
6353
|
+
var ServerOnly2 = { [SCHEMA_EXPOSURE_META_KEY2]: SchemaExposure2.Internal };
|
|
6120
6354
|
function toWritableSchema2(schema) {
|
|
6121
6355
|
const writableShape = {};
|
|
6122
6356
|
for (const [fieldName, fieldSchema] of Object.entries(schema.shape)) {
|
|
@@ -6140,7 +6374,7 @@ function toCreateSchema2(schema) {
|
|
|
6140
6374
|
}
|
|
6141
6375
|
var { Unrestricted: Unrestricted24 } = DataClassification2;
|
|
6142
6376
|
var { Transient: Transient22, Persisted: Persisted24 } = SchemaPersistence2;
|
|
6143
|
-
var { Internal:
|
|
6377
|
+
var { Internal: Internal21, External: External13 } = SchemaExposure2;
|
|
6144
6378
|
var PaginationParamsSchema2 = z32.object({
|
|
6145
6379
|
page: z32.coerce.number().int().min(1).default(1).meta(Unrestricted24),
|
|
6146
6380
|
per_page: z32.coerce.number().int().min(1).max(100).default(25).meta(Unrestricted24)
|
|
@@ -6176,7 +6410,7 @@ var TenantIdField2 = z32.object({
|
|
|
6176
6410
|
{
|
|
6177
6411
|
id: "null",
|
|
6178
6412
|
"x-revturbine-schema-persistence": Transient22,
|
|
6179
|
-
"x-revturbine-schema-exposure":
|
|
6413
|
+
"x-revturbine-schema-exposure": Internal21
|
|
6180
6414
|
}
|
|
6181
6415
|
);
|
|
6182
6416
|
var BillingCadenceSchema2 = z32.enum([
|
|
@@ -6242,7 +6476,7 @@ var FeatureFlagValueSchema2 = z32.union([
|
|
|
6242
6476
|
{
|
|
6243
6477
|
id: "FeatureFlagValue",
|
|
6244
6478
|
"x-revturbine-schema-persistence": Transient22,
|
|
6245
|
-
"x-revturbine-schema-exposure":
|
|
6479
|
+
"x-revturbine-schema-exposure": Internal21
|
|
6246
6480
|
}
|
|
6247
6481
|
);
|
|
6248
6482
|
var NameField2 = z32.string().min(1).max(200);
|
|
@@ -6253,7 +6487,7 @@ var ThresholdPercentField2 = z32.number().int().min(10).max(100).multipleOf(10);
|
|
|
6253
6487
|
var NullableDatetimeField2 = z32.string().datetime().nullable().default(null);
|
|
6254
6488
|
var AnchorFields2 = z32.object({
|
|
6255
6489
|
environment_id: z32.string().min(1).default("production").meta({ ...Unrestricted24, readOnly: true })
|
|
6256
|
-
}).meta({ id: "null", "x-revturbine-schema-persistence": Transient22, "x-revturbine-schema-exposure":
|
|
6490
|
+
}).meta({ id: "null", "x-revturbine-schema-persistence": Transient22, "x-revturbine-schema-exposure": Internal21 });
|
|
6257
6491
|
var VersionFields2 = z32.object({
|
|
6258
6492
|
// Which playbook version (the review/deploy unit — was `change_set_id`) staged
|
|
6259
6493
|
// this ledger row; null once it is the deployed live row.
|
|
@@ -6266,7 +6500,7 @@ var VersionFields2 = z32.object({
|
|
|
6266
6500
|
// so a stale draft is detected when live has moved past it.
|
|
6267
6501
|
sequence: z32.number().int().min(1).default(1).meta({ ...Unrestricted24, readOnly: true }),
|
|
6268
6502
|
base_sequence: z32.number().int().nullable().default(null).meta({ ...Unrestricted24, readOnly: true })
|
|
6269
|
-
}).meta({ id: "null", "x-revturbine-schema-persistence": Transient22, "x-revturbine-schema-exposure":
|
|
6503
|
+
}).meta({ id: "null", "x-revturbine-schema-persistence": Transient22, "x-revturbine-schema-exposure": Internal21 });
|
|
6270
6504
|
var AnchorBaseSchema2 = IdField2.merge(TimestampFields2).merge(TenantIdField2).merge(AnchorFields2).extend({
|
|
6271
6505
|
handle: HandleField2.meta({ ...Unrestricted24, readOnly: true }),
|
|
6272
6506
|
active: z32.boolean().default(true).meta({ ...Unrestricted24, readOnly: true })
|
|
@@ -6275,10 +6509,10 @@ function makeAnchor2(id) {
|
|
|
6275
6509
|
return AnchorBaseSchema2.meta({
|
|
6276
6510
|
id,
|
|
6277
6511
|
"x-revturbine-schema-persistence": Persisted24,
|
|
6278
|
-
"x-revturbine-schema-exposure":
|
|
6512
|
+
"x-revturbine-schema-exposure": Internal21
|
|
6279
6513
|
});
|
|
6280
6514
|
}
|
|
6281
|
-
var SeveritySchema22 = z32.enum(["info", "warning", "critical"]).meta({ id: "Severity", "x-revturbine-schema-persistence": Transient22, "x-revturbine-schema-exposure":
|
|
6515
|
+
var SeveritySchema22 = z32.enum(["info", "warning", "critical"]).meta({ id: "Severity", "x-revturbine-schema-persistence": Transient22, "x-revturbine-schema-exposure": Internal21 });
|
|
6282
6516
|
var StudioSurfaceTypeSchema2 = z32.enum([
|
|
6283
6517
|
"button",
|
|
6284
6518
|
"plans_page_ctas",
|
|
@@ -6299,7 +6533,7 @@ var StudioSurfaceTypeSchema2 = z32.enum([
|
|
|
6299
6533
|
"cli",
|
|
6300
6534
|
"agent_connector",
|
|
6301
6535
|
"custom_in_app"
|
|
6302
|
-
]).meta({ id: "StudioSurfaceType", "x-revturbine-schema-persistence": Transient22, "x-revturbine-schema-exposure":
|
|
6536
|
+
]).meta({ id: "StudioSurfaceType", "x-revturbine-schema-persistence": Transient22, "x-revturbine-schema-exposure": Internal21 });
|
|
6303
6537
|
var CtaActionTypeSchema2 = z32.enum([
|
|
6304
6538
|
"open_checkout",
|
|
6305
6539
|
"view_plans",
|
|
@@ -7179,7 +7413,7 @@ var trialPaths2 = {
|
|
|
7179
7413
|
})
|
|
7180
7414
|
}
|
|
7181
7415
|
};
|
|
7182
|
-
var { Unrestricted: Unrestricted42, Financial:
|
|
7416
|
+
var { Unrestricted: Unrestricted42, Financial: Financial5 } = DataClassification2;
|
|
7183
7417
|
var { Persisted: Persisted42, Transient: Transient42 } = SchemaPersistence2;
|
|
7184
7418
|
var { External: External32 } = SchemaExposure2;
|
|
7185
7419
|
var PLAYBOOK_SDK_FACETS32 = schemaFacets2(SchemaContext2.Playbook, { sdkInput: true });
|
|
@@ -7234,7 +7468,7 @@ var PlanVariationSchema2 = IdField2.merge(TimestampFields2).merge(TenantIdField2
|
|
|
7234
7468
|
plan_id: z82.string().min(1).meta(Unrestricted42),
|
|
7235
7469
|
billing_period: z82.enum(["monthly", "annual", "one_time", "custom"]).meta(Unrestricted42),
|
|
7236
7470
|
segment_id: z82.string().nullable().default(null).meta(Unrestricted42),
|
|
7237
|
-
price_amount: z82.number().min(0).meta(
|
|
7471
|
+
price_amount: z82.number().min(0).meta(Financial5),
|
|
7238
7472
|
pricing_model: PricingModelSchema2.meta(Unrestricted42),
|
|
7239
7473
|
visibility: PlanVisibilitySchema2.default("public").meta(Unrestricted42),
|
|
7240
7474
|
// Soft reference → StripePrice.stripe_price_id (the backend Stripe-price mirror).
|
|
@@ -7279,7 +7513,7 @@ var AddOnVariationSchema2 = IdField2.merge(TimestampFields2).merge(TenantIdField
|
|
|
7279
7513
|
// expansion packages) bind here without coercion to 'custom'.
|
|
7280
7514
|
billing_period: z82.enum(["monthly", "annual", "one_time", "custom"]).meta(Unrestricted42),
|
|
7281
7515
|
segment_id: z82.string().nullable().default(null).meta(Unrestricted42),
|
|
7282
|
-
price_amount: z82.number().min(0).meta(
|
|
7516
|
+
price_amount: z82.number().min(0).meta(Financial5),
|
|
7283
7517
|
pricing_model: PricingModelSchema2.meta(Unrestricted42),
|
|
7284
7518
|
visibility: PlanVisibilitySchema2.default("public").meta(Unrestricted42),
|
|
7285
7519
|
// Soft reference → StripePrice.stripe_price_id (the backend Stripe-price mirror).
|
|
@@ -7306,8 +7540,8 @@ var StripePriceSchema2 = IdField2.merge(TimestampFields2).merge(TenantIdField2).
|
|
|
7306
7540
|
stripe_price_id: z82.string().min(1).meta(Unrestricted42),
|
|
7307
7541
|
stripe_product_id: z82.string().min(1).meta(Unrestricted42),
|
|
7308
7542
|
billing_period: StripePriceBillingPeriodSchema2.meta(Unrestricted42),
|
|
7309
|
-
unit_amount_cents: z82.number().int().min(0).nullable().default(null).meta(
|
|
7310
|
-
currency: CurrencySchema2.meta(
|
|
7543
|
+
unit_amount_cents: z82.number().int().min(0).nullable().default(null).meta(Financial5),
|
|
7544
|
+
currency: CurrencySchema2.meta(Financial5),
|
|
7311
7545
|
pricing_model: PricingModelSchema2.meta(Unrestricted42),
|
|
7312
7546
|
nickname: z82.string().nullable().default(null).meta(Unrestricted42),
|
|
7313
7547
|
// Placeholder/seed price (demo or pre-integration tenants) vs a real
|
|
@@ -7790,6 +8024,10 @@ var PlacementTestModeSchema2 = z92.enum(["off", "test_users", "all_traffic"]).me
|
|
|
7790
8024
|
var PlacementSettingsCapStateSchema2 = z92.object({
|
|
7791
8025
|
capRules: z92.array(PlacementSettingsCapRuleSchema2).default([]).meta(Unrestricted52),
|
|
7792
8026
|
sessionCooldownMinutes: z92.number().int().min(0).default(30).meta(Unrestricted52),
|
|
8027
|
+
// Tenant-level default remind-me-later (defer) window, in minutes. A
|
|
8028
|
+
// per-payload `remind_later_minutes` overrides it when set (plan 167 REQ-6,
|
|
8029
|
+
// Q-3). Rides in this global_frequency_cap jsonb wrapper — no column/`.fbs`.
|
|
8030
|
+
remindLaterMinutes: z92.number().int().min(0).default(60).meta(Unrestricted52),
|
|
7793
8031
|
testMode: PlacementTestModeSchema2.default("off").meta(Unrestricted52)
|
|
7794
8032
|
}).meta(
|
|
7795
8033
|
{ id: "PlacementSettingsCapState", "x-revturbine-schema-persistence": Transient52, "x-revturbine-schema-exposure": Internal42 }
|
|
@@ -7804,7 +8042,8 @@ var PlacementSettingsSchema2 = IdField2.merge(TimestampFields2).merge(TenantIdFi
|
|
|
7804
8042
|
global_frequency_cap_period: z92.enum(["hour", "day", "week", "month", "session"]).nullable().default(null).meta(Unrestricted52),
|
|
7805
8043
|
suppress_for_paid: z92.boolean().default(false).meta(Unrestricted52),
|
|
7806
8044
|
suppress_for_trial: z92.boolean().default(false).meta(Unrestricted52),
|
|
7807
|
-
default_dismiss_cooldown_hours
|
|
8045
|
+
// `default_dismiss_cooldown_hours` removed (plan 167 Q-2): the dismiss
|
|
8046
|
+
// cooldown is defined per-payload in days (`cooldown_after_dismiss_days`).
|
|
7808
8047
|
allow_stacking: z92.boolean().default(false).meta(Unrestricted52),
|
|
7809
8048
|
priority_collision_strategy: z92.enum(["highest_priority", "most_recent", "random"]).default("highest_priority").meta(Unrestricted52)
|
|
7810
8049
|
}).meta(
|
|
@@ -7916,7 +8155,7 @@ var RevTurbineConfigPlacementSettingsItemSchema2 = z92.object({
|
|
|
7916
8155
|
global_frequency_cap_period: z92.enum(["hour", "day", "week", "month", "session"]).nullable().default(null).meta(Unrestricted52),
|
|
7917
8156
|
suppress_for_paid: z92.boolean().default(false).meta(Unrestricted52),
|
|
7918
8157
|
suppress_for_trial: z92.boolean().default(false).meta(Unrestricted52),
|
|
7919
|
-
default_dismiss_cooldown_hours
|
|
8158
|
+
// `default_dismiss_cooldown_hours` removed (plan 167 Q-2).
|
|
7920
8159
|
allow_stacking: z92.boolean().default(false).meta(Unrestricted52),
|
|
7921
8160
|
priority_collision_strategy: z92.string().nullable().default(null).meta(Unrestricted52)
|
|
7922
8161
|
}).meta(
|
|
@@ -8058,7 +8297,11 @@ var RevTurbineConfigUiPathActionTypeSchema2 = z92.enum([
|
|
|
8058
8297
|
"verify_work_email",
|
|
8059
8298
|
"update_payment_method",
|
|
8060
8299
|
"enable_auto_renewal",
|
|
8061
|
-
"manage_subscription"
|
|
8300
|
+
"manage_subscription",
|
|
8301
|
+
// Authored `snooze` resolves through to the SDK's remind-later path
|
|
8302
|
+
// (plan 167 windows); previously it fell through as an invalid type
|
|
8303
|
+
// (plan 174 TASK-6 / Q-5, spec-check F-65a).
|
|
8304
|
+
"snooze"
|
|
8062
8305
|
]).meta(
|
|
8063
8306
|
{ id: "RevTurbineConfigUiPathActionType", "x-revturbine-schema-persistence": Transient52, "x-revturbine-schema-exposure": External42 }
|
|
8064
8307
|
);
|
|
@@ -8167,6 +8410,8 @@ var RevTurbineConfigStudioPayloadSchema2 = z92.object({
|
|
|
8167
8410
|
caps: RevTurbineConfigStudioPayloadCapsSchema2.optional().meta(Unrestricted52),
|
|
8168
8411
|
// Optional slot targeting (spec §3.1.1): empty/absent = any compatible slot.
|
|
8169
8412
|
surface_slot_ids: z92.array(z92.string()).optional().meta(Unrestricted52),
|
|
8413
|
+
// Per-payload remind-me-later override (minutes); absent = inherit tenant default (plan 167 Q-3).
|
|
8414
|
+
remind_later_minutes: z92.number().int().min(0).nullable().optional().meta(Unrestricted52),
|
|
8170
8415
|
created_at: z92.string().optional().meta({ ...Unrestricted52, readOnly: true }),
|
|
8171
8416
|
recommendation_strategy: z92.enum(["next_tier_up", "best_value", "custom"]).optional().default("next_tier_up").meta(Unrestricted52),
|
|
8172
8417
|
recommendation_plan_override: z92.string().optional().meta(Unrestricted52)
|
|
@@ -8206,6 +8451,8 @@ var RevTurbineConfigPlacementPayloadItemSchema2 = z92.object({
|
|
|
8206
8451
|
placement_id: z92.string().min(1).meta(Unrestricted52),
|
|
8207
8452
|
target: RevTurbineConfigStudioPayloadTargetSchema2.meta(Unrestricted52),
|
|
8208
8453
|
caps: RevTurbineConfigStudioPayloadCapsSchema2.optional().meta(Unrestricted52),
|
|
8454
|
+
// Per-payload remind-me-later override (minutes); absent = inherit tenant default (plan 167 Q-3).
|
|
8455
|
+
remind_later_minutes: z92.number().int().min(0).nullable().optional().meta(Unrestricted52),
|
|
8209
8456
|
created_at: z92.string().meta({ ...Unrestricted52, readOnly: true }),
|
|
8210
8457
|
updated_at: z92.string().datetime().optional().meta({ ...Unrestricted52, readOnly: true }),
|
|
8211
8458
|
source_mode: z92.enum(["inline", "content_linked"]).meta(Unrestricted52),
|
|
@@ -8436,6 +8683,12 @@ var PlaybookSchema2 = z92.preprocess(normalizeConfigHeaderInput2, PlaybookObject
|
|
|
8436
8683
|
"x-revturbine-schema-exposure": External42,
|
|
8437
8684
|
...PLAYBOOK_SDK_FACETS42
|
|
8438
8685
|
});
|
|
8686
|
+
var PlaybookStrictSchema2 = z92.preprocess(normalizeConfigHeaderInput2, PlaybookObjectSchema2.strict()).meta({
|
|
8687
|
+
id: "PlaybookStrict",
|
|
8688
|
+
"x-revturbine-schema-persistence": Transient52,
|
|
8689
|
+
"x-revturbine-schema-exposure": External42,
|
|
8690
|
+
...PLAYBOOK_SDK_FACETS42
|
|
8691
|
+
});
|
|
8439
8692
|
var configPaths2 = {
|
|
8440
8693
|
"/api/seat-type-anchors": {
|
|
8441
8694
|
get: operation2({
|
|
@@ -8711,7 +8964,7 @@ function repairDeprecatedFields(config, schema = PlaybookObjectSchema2) {
|
|
|
8711
8964
|
}
|
|
8712
8965
|
|
|
8713
8966
|
// src/schema/version.ts
|
|
8714
|
-
var SCHEMA_VERSION = "0.1.
|
|
8967
|
+
var SCHEMA_VERSION = "0.1.168";
|
|
8715
8968
|
|
|
8716
8969
|
// src/lib/credentials.ts
|
|
8717
8970
|
import { chmodSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
|