From a8e22d05a9fd423822edb7106b42bd17099af461 Mon Sep 17 00:00:00 2001 From: Ayush Rodrigues Date: Fri, 29 May 2026 13:12:12 +0100 Subject: [PATCH] add diffPlanV1 diff/apply test suite with real customer fixtures Round-trip tests against Firecrawl, Runable, RevisionDojo, and OnePREP plan data proving diffPlanV1 + applyDiff reconstructs variants correctly. Co-authored-by: Cursor --- .../diffing/diffPlanV1.firecrawl.fixtures.ts | 55 + .../diffing/diffPlanV1.firecrawl.test.ts | 71 + .../crud/plans/diffing/diffPlanV1.fixtures.ts | 695 ++ .../diffing/diffPlanV1.freeTrial.test.ts | 102 + .../diffing/diffPlanV1.oneprep.fixtures.ts | 15 + .../plans/diffing/diffPlanV1.oneprep.test.ts | 20 + .../diffPlanV1.revisiondojo.fixtures.ts | 70 + .../diffing/diffPlanV1.revisiondojo.test.ts | 32 + .../diffing/diffPlanV1.runable.fixtures.ts | 64 + .../plans/diffing/diffPlanV1.runable.test.ts | 41 + .../crud/plans/diffing/diffPlanV1.test.ts | 53 + .../crud/plans/diffing/firecrawl-plans.json | 2463 +++++++ .../crud/plans/diffing/oneprep-plans.json | 771 +++ .../plans/diffing/revisiondojo-plans.json | 5642 +++++++++++++++++ .../crud/plans/diffing/runable-plans.json | 3518 ++++++++++ .../crud/plans/diffing/utils/findById.ts | 5 + .../crud/plans/diffing/utils/normalizePlan.ts | 72 + 17 files changed, 13689 insertions(+) create mode 100644 server/tests/integration/crud/plans/diffing/diffPlanV1.firecrawl.fixtures.ts create mode 100644 server/tests/integration/crud/plans/diffing/diffPlanV1.firecrawl.test.ts create mode 100644 server/tests/integration/crud/plans/diffing/diffPlanV1.fixtures.ts create mode 100644 server/tests/integration/crud/plans/diffing/diffPlanV1.freeTrial.test.ts create mode 100644 server/tests/integration/crud/plans/diffing/diffPlanV1.oneprep.fixtures.ts create mode 100644 server/tests/integration/crud/plans/diffing/diffPlanV1.oneprep.test.ts create mode 100644 server/tests/integration/crud/plans/diffing/diffPlanV1.revisiondojo.fixtures.ts create mode 100644 server/tests/integration/crud/plans/diffing/diffPlanV1.revisiondojo.test.ts create mode 100644 server/tests/integration/crud/plans/diffing/diffPlanV1.runable.fixtures.ts create mode 100644 server/tests/integration/crud/plans/diffing/diffPlanV1.runable.test.ts create mode 100644 server/tests/integration/crud/plans/diffing/diffPlanV1.test.ts create mode 100644 server/tests/integration/crud/plans/diffing/firecrawl-plans.json create mode 100644 server/tests/integration/crud/plans/diffing/oneprep-plans.json create mode 100644 server/tests/integration/crud/plans/diffing/revisiondojo-plans.json create mode 100644 server/tests/integration/crud/plans/diffing/runable-plans.json create mode 100644 server/tests/integration/crud/plans/diffing/utils/findById.ts create mode 100644 server/tests/integration/crud/plans/diffing/utils/normalizePlan.ts diff --git a/server/tests/integration/crud/plans/diffing/diffPlanV1.firecrawl.fixtures.ts b/server/tests/integration/crud/plans/diffing/diffPlanV1.firecrawl.fixtures.ts new file mode 100644 index 000000000..502c262b8 --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/diffPlanV1.firecrawl.fixtures.ts @@ -0,0 +1,55 @@ +import { type ApiPlanV1 } from "@autumn/shared"; +import { findById } from "./utils/findById.js"; + +// Bun-native JSON import (module: Preserve + bundler resolution). +import firecrawlDump from "./firecrawl-plans.json" with { type: "json" }; + +const items = firecrawlDump.items as ApiPlanV1[]; + +// Group 1 — Scale (base = scale_tier_1) +export const scaleTier1Base = findById(items, "scale_tier_1"); +export const scaleVariants: ApiPlanV1[] = [ + findById(items, "scale_tier_2"), + findById(items, "scale_tier_3"), + findById(items, "scale_tier_4"), + findById(items, "scale_tier_1_quarterly"), + findById(items, "scale_tier_2_quarterly"), + findById(items, "scale_tier_3_quarterly"), + findById(items, "scale_tier_4_quarterly"), + findById(items, "scale_monthly"), +]; + +// Group 2 — Hobby (base = hobby) +export const hobbyBase = findById(items, "hobby"); +export const hobbyVariants: ApiPlanV1[] = [ + findById(items, "hobby_yearly"), + findById(items, "hobby_monthly_5k"), + findById(items, "hobby_monthly_6_5k"), + findById(items, "hobby_monthly_8k"), + findById(items, "hobby_yearly_5k"), + findById(items, "hobby_yearly_6_5k"), + findById(items, "hobby_yearly_8k"), +]; + +// Group 3 — Standard (base = standard) +export const standardBase = findById(items, "standard"); +export const standardVariants: ApiPlanV1[] = [ + findById(items, "standard_yearly"), + findById(items, "standard_monthly_100k"), + findById(items, "standard_monthly_130k"), + findById(items, "standard_monthly_160k"), + findById(items, "standard_yearly_100k"), + findById(items, "standard_yearly_130k"), + findById(items, "standard_yearly_160k"), +]; + +// Group 4 — Growth (base = growth) +export const growthBase = findById(items, "growth"); +export const growthVariants: ApiPlanV1[] = [ + findById(items, "growth_yearly"), + findById(items, "growth_monthly_500k"), + findById(items, "growth_monthly_650k"), + findById(items, "growth_monthly_800k"), + findById(items, "growth_yearly_500k"), + findById(items, "growth_yearly_650k"), +]; diff --git a/server/tests/integration/crud/plans/diffing/diffPlanV1.firecrawl.test.ts b/server/tests/integration/crud/plans/diffing/diffPlanV1.firecrawl.test.ts new file mode 100644 index 000000000..ec3fd3175 --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/diffPlanV1.firecrawl.test.ts @@ -0,0 +1,71 @@ +import { describe, expect, test } from "bun:test"; +import type { ApiPlanV1 } from "@autumn/shared"; +import { + applyDiff, + type ApplyDiffOutput, +} from "@autumn/shared/utils/planV1Utils/diff/applyDiff.js"; +import { + growthBase, + growthVariants, + hobbyBase, + hobbyVariants, + scaleTier1Base, + scaleVariants, + standardBase, + standardVariants, +} from "./diffPlanV1.firecrawl.fixtures.js"; +import { diffPlanV1 } from "@autumn/shared/utils/planV1Utils/diff/diffPlanV1.js"; +import { normalizePlan } from "./utils/normalizePlan.js"; + +// --- test matrix --- +const groups = [ + { name: "scale", base: scaleTier1Base, variants: scaleVariants }, + { name: "hobby", base: hobbyBase, variants: hobbyVariants }, + { name: "standard", base: standardBase, variants: standardVariants }, + { name: "growth", base: growthBase, variants: growthVariants }, +]; + +for (const { name, base, variants } of groups) { + describe(`firecrawl ${name} group — diff/apply round-trip`, () => { + for (const variant of variants) { + test(`${variant.id} reconstructs from ${base.id} + diff`, () => { + const diff = diffPlanV1({ from: base, to: variant }); + const reconstructed = applyDiff({ base, diff }); + expect(normalizePlan(reconstructed)).toEqual(normalizePlan(variant)); + }); + } + }); +} + +describe("filter precision — same-feature-id siblings", () => { + test("mutating the priced CREDITS leaves the price-null CREDITS intact", () => { + const base = growthBase; + const pricedCredits = base.items.find( + (i) => i.feature_id === "CREDITS" && i.price != null, + )!; + const mutated: ApiPlanV1 = { + ...base, + items: base.items.map((item) => + item === pricedCredits + ? { ...item, included: item.included + 1 } + : item, + ), + }; + + const diff = diffPlanV1({ from: base, to: mutated }); + const reconstructed = applyDiff({ base, diff }); + + const stillHasPriceNullCredits = reconstructed.items.some( + (i) => + i.feature_id === "CREDITS" && + i.price == null && + i.reset?.interval === "month", + ); + expect(stillHasPriceNullCredits).toBe(true); + + const mutatedCredits = reconstructed.items.find( + (i) => i.feature_id === "CREDITS" && i.price != null, + ); + expect(mutatedCredits?.included).toBe(pricedCredits.included + 1); + }); +}); diff --git a/server/tests/integration/crud/plans/diffing/diffPlanV1.fixtures.ts b/server/tests/integration/crud/plans/diffing/diffPlanV1.fixtures.ts new file mode 100644 index 000000000..23b869856 --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/diffPlanV1.fixtures.ts @@ -0,0 +1,695 @@ +import type { ApiPlanV1 } from "@autumn/shared"; + +export const popflyStart = { + "id": "start", + "name": "Run", + "description": null, + "group": null, + "version": 8, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 499, + "interval": "month", + "display": { + "primary_text": "$499", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "adventures", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Adventures" + } + }, + { + "feature_id": "adventures_visible", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited adventures visible" + } + }, + { + "feature_id": "affiliate_programs", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited affiliate programs" + } + }, + { + "feature_id": "affiliates_csv_export", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Affiliates CSV Export" + } + }, + { + "feature_id": "affiliates_per_program", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited affiliates per program" + } + }, + { + "feature_id": "affiliates_reporting", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Affiliates Reporting" + } + }, + { + "feature_id": "campaign_progress_management", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Campaign Progress Management" + } + }, + { + "feature_id": "campaigns", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Campaigns" + } + }, + { + "feature_id": "connections_limit_company_with_company", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited company connections limits" + } + }, + { + "feature_id": "company_members", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited company members" + } + }, + { + "feature_id": "content", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Content" + } + }, + { + "feature_id": "content_storage", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited content storages" + } + }, + { + "feature_id": "connections_limit_company_with_creators", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited creator connections limits" + } + }, + { + "feature_id": "creator_discovery_advanced", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Creator Discovery Advanced" + } + }, + { + "feature_id": "gifting_invitations", + "included": 200, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "200 gifting invitations" + } + }, + { + "feature_id": "gifting_products", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited gifting products" + } + }, + { + "feature_id": "invite_through_popfly_advanced", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Invite Through Popfly Advanced" + } + }, + { + "feature_id": "invoice_fee", + "included": 390, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "390 invoice fees" + } + }, + { + "feature_id": "campaigns_private_monthly", + "included": 0, + "unlimited": true, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "Unlimited monthly private campaigns" + } + }, + { + "feature_id": "campaigns_public_monthly", + "included": 0, + "unlimited": true, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "Unlimited monthly public campaigns" + } + }, + { + "feature_id": "campaigns_unlisted_monthly", + "included": 0, + "unlimited": true, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "Unlimited Monthly Unlisted Campaigns" + } + }, + { + "feature_id": "packs", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Packs" + } + }, + { + "feature_id": "playbook", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Playbook" + } + }, + { + "feature_id": "popfly_platform", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Popfly Platform" + } + }, + { + "feature_id": "affiliate_programs_public", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited public affiliate programs" + } + }, + { + "feature_id": "social_listening", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Social Listening" + } + }, + { + "feature_id": "social_listening_mention_results", + "included": 25, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "25 social listening mention results" + } + }, + { + "feature_id": "social_listening_platforms", + "included": 1, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "1 Social Listening Platform" + } + }, + { + "feature_id": "social_listening_refresh_frequency_in_hours", + "included": 168, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "168 social listening refresh frequencies (hours)" + } + }, + { + "feature_id": "social_listening_terms", + "included": 1, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "1 social listening term" + } + }, + { + "feature_id": "social_listening_topics", + "included": 1, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "1 social listening topic" + } + } + ], + "created_at": 1777460151677, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } +} as ApiPlanV1; + +export const popflyStartAnnual = { + "id": "start_annual", + "name": "Run - annual", + "description": null, + "group": null, + "version": 9, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 5988, + "interval": "year", + "display": { + "primary_text": "$5,988", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "adventures", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Adventures" + } + }, + { + "feature_id": "adventures_visible", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited adventures visible" + } + }, + { + "feature_id": "affiliate_programs", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited affiliate programs" + } + }, + { + "feature_id": "affiliates_csv_export", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Affiliates CSV Export" + } + }, + { + "feature_id": "affiliates_per_program", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited affiliates per program" + } + }, + { + "feature_id": "affiliates_reporting", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Affiliates Reporting" + } + }, + { + "feature_id": "campaign_progress_management", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Campaign Progress Management" + } + }, + { + "feature_id": "campaigns", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Campaigns" + } + }, + { + "feature_id": "connections_limit_company_with_company", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited company connections limits" + } + }, + { + "feature_id": "company_members", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited company members" + } + }, + { + "feature_id": "content", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Content" + } + }, + { + "feature_id": "content_storage", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited content storages" + } + }, + { + "feature_id": "connections_limit_company_with_creators", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited creator connections limits" + } + }, + { + "feature_id": "creator_discovery_advanced", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Creator Discovery Advanced" + } + }, + { + "feature_id": "gifting_invitations", + "included": 200, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "200 gifting invitations" + } + }, + { + "feature_id": "gifting_products", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited gifting products" + } + }, + { + "feature_id": "invite_through_popfly_advanced", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Invite Through Popfly Advanced" + } + }, + { + "feature_id": "invoice_fee", + "included": 390, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "390 invoice fees" + } + }, + { + "feature_id": "campaigns_private_monthly", + "included": 0, + "unlimited": true, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "Unlimited monthly private campaigns" + } + }, + { + "feature_id": "campaigns_public_monthly", + "included": 0, + "unlimited": true, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "Unlimited monthly public campaigns" + } + }, + { + "feature_id": "campaigns_unlisted_monthly", + "included": 0, + "unlimited": true, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "Unlimited Monthly Unlisted Campaigns" + } + }, + { + "feature_id": "packs", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Packs" + } + }, + { + "feature_id": "playbook", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Playbook" + } + }, + { + "feature_id": "popfly_platform", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Popfly Platform" + } + }, + { + "feature_id": "affiliate_programs_public", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited public affiliate programs" + } + }, + { + "feature_id": "social_listening", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Social Listening" + } + }, + { + "feature_id": "social_listening_mention_results", + "included": 25, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "25 social listening mention results" + } + }, + { + "feature_id": "social_listening_platforms", + "included": 1, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "1 Social Listening Platform" + } + }, + { + "feature_id": "social_listening_refresh_frequency_in_hours", + "included": 168, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "168 social listening refresh frequencies (hours)" + } + }, + { + "feature_id": "social_listening_terms", + "included": 1, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "1 social listening term" + } + }, + { + "feature_id": "social_listening_topics", + "included": 1, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "1 social listening topic" + } + } + ], + "created_at": 1777460152188, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } +} as ApiPlanV1; diff --git a/server/tests/integration/crud/plans/diffing/diffPlanV1.freeTrial.test.ts b/server/tests/integration/crud/plans/diffing/diffPlanV1.freeTrial.test.ts new file mode 100644 index 000000000..8ce6a0e4a --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/diffPlanV1.freeTrial.test.ts @@ -0,0 +1,102 @@ +import { AppEnv, type ApiPlanV1, FreeTrialDuration } from "@autumn/shared"; +import { describe, expect, test } from "bun:test"; +import { applyDiff } from "@autumn/shared/utils/planV1Utils/diff/applyDiff.js"; +import { diffPlanV1 } from "@autumn/shared/utils/planV1Utils/diff/diffPlanV1.js"; + +const makePlan = (overrides?: Partial): ApiPlanV1 => ({ + id: "test-plan", + name: "Test Plan", + description: null, + group: null, + version: 1, + add_on: false, + auto_enable: false, + price: null, + items: [ + { + feature_id: "messages", + included: 0, + unlimited: false, + reset: null, + price: null, + }, + ], + created_at: 0, + env: AppEnv.Sandbox, + archived: false, + base_variant_id: null, + config: { ignore_past_due: false }, + ...overrides, +}); + +describe("diffPlanV1 + applyDiff — free_trial branch", () => { + test("adding a trial produces a diff and apply reconstructs it", () => { + const trial = { + duration_length: 14, + duration_type: FreeTrialDuration.Day, + card_required: false, + }; + const from = makePlan({ free_trial: undefined }); + const to = makePlan({ free_trial: trial }); + + const diff = diffPlanV1({ from, to }); + expect(diff.free_trial).toEqual(trial); + + const result = applyDiff({ base: from, diff }); + expect(result.free_trial).toEqual(trial); + }); + + test("removing a trial produces a null diff and apply drops it", () => { + const trial = { + duration_length: 7, + duration_type: FreeTrialDuration.Day, + card_required: true, + }; + const from = makePlan({ free_trial: trial }); + const to = makePlan({ free_trial: undefined }); + + const diff = diffPlanV1({ from, to }); + expect(diff.free_trial).toBeNull(); + + const result = applyDiff({ base: from, diff }); + expect(result.free_trial).toBeUndefined(); + }); + + test("changing a trial duration produces a diff and apply updates it", () => { + const fromTrial = { + duration_length: 7, + duration_type: FreeTrialDuration.Day, + card_required: true, + }; + const toTrial = { + duration_length: 30, + duration_type: FreeTrialDuration.Day, + card_required: true, + }; + const from = makePlan({ free_trial: fromTrial }); + const to = makePlan({ free_trial: toTrial }); + + const diff = diffPlanV1({ from, to }); + expect(diff.free_trial).toEqual(toTrial); + + const result = applyDiff({ base: from, diff }); + expect(result.free_trial).toEqual(toTrial); + }); + + test("identical trials produce no diff and apply preserves the base", () => { + const trial = { + duration_length: 14, + duration_type: FreeTrialDuration.Day, + card_required: false, + on_end: "bill" as const, + }; + const from = makePlan({ free_trial: trial }); + const to = makePlan({ free_trial: trial }); + + const diff = diffPlanV1({ from, to }); + expect(diff.free_trial).toBeUndefined(); + + const result = applyDiff({ base: from, diff }); + expect(result.free_trial).toEqual(trial); + }); +}); diff --git a/server/tests/integration/crud/plans/diffing/diffPlanV1.oneprep.fixtures.ts b/server/tests/integration/crud/plans/diffing/diffPlanV1.oneprep.fixtures.ts new file mode 100644 index 000000000..59e6c4f72 --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/diffPlanV1.oneprep.fixtures.ts @@ -0,0 +1,15 @@ +import { type ApiPlanV1 } from "@autumn/shared"; +import { findById } from "./utils/findById.js"; + +import oneprepDump from "./oneprep-plans.json" with { type: "json" }; + +const items = oneprepDump.items as ApiPlanV1[]; + +export const proBase = findById(items, "pro_1m"); +export const proVariants: ApiPlanV1[] = [ + findById(items, "pro_1w"), + findById(items, "pro_3m"), + findById(items, "pro_6m"), + findById(items, "pro_12m"), + findById(items, "pro_june_2026"), +]; diff --git a/server/tests/integration/crud/plans/diffing/diffPlanV1.oneprep.test.ts b/server/tests/integration/crud/plans/diffing/diffPlanV1.oneprep.test.ts new file mode 100644 index 000000000..5970ddf9c --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/diffPlanV1.oneprep.test.ts @@ -0,0 +1,20 @@ +import { type ApiPlanV1 } from "@autumn/shared"; +import { describe, expect, test } from "bun:test"; +import { diffPlanV1 } from "@autumn/shared/utils/planV1Utils/diff/diffPlanV1.js"; +import { applyDiff } from "@autumn/shared/utils/planV1Utils/diff/applyDiff.js"; +import { proBase, proVariants } from "./diffPlanV1.oneprep.fixtures.js"; +import { normalizePlan } from "./utils/normalizePlan.js"; + +const groups = [{ name: "pro", base: proBase, variants: proVariants }]; + +for (const { name, base, variants } of groups) { + describe(`oneprep ${name} group — diff/apply round-trip`, () => { + for (const variant of variants) { + test(`${variant.id} reconstructs from ${base.id} + diff`, () => { + const diff = diffPlanV1({ from: base, to: variant }); + const reconstructed = applyDiff({ base, diff }); + expect(normalizePlan(reconstructed)).toEqual(normalizePlan(variant)); + }); + } + }); +} diff --git a/server/tests/integration/crud/plans/diffing/diffPlanV1.revisiondojo.fixtures.ts b/server/tests/integration/crud/plans/diffing/diffPlanV1.revisiondojo.fixtures.ts new file mode 100644 index 000000000..df4934b38 --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/diffPlanV1.revisiondojo.fixtures.ts @@ -0,0 +1,70 @@ +import { type ApiPlanV1 } from "@autumn/shared"; +import { findById } from "./utils/findById.js"; + +import revisiondojoDump from "./revisiondojo-plans.json" with { type: "json" }; + +const items = revisiondojoDump.items as ApiPlanV1[]; + +// Group 1 — Pro (base = pro_1m) +export const proBase = findById(items, "pro_1m"); +export const proVariants: ApiPlanV1[] = [ + findById(items, "pro_free_grant"), + findById(items, "pro_1m_new"), + findById(items, "pro_1_month_mobile"), + findById(items, "pro_1w"), + findById(items, "pro_2m"), + findById(items, "pro_3m"), + findById(items, "pro_3m_special"), + findById(items, "pro_4m"), + findById(items, "pro_6m"), + findById(items, "pro_6m_oneoff"), + findById(items, "pro_12m"), + findById(items, "pro_15m"), + findById(items, "pro_18m"), + findById(items, "pro_24m"), + findById(items, "pro_m26"), + findById(items, "pro_2m_m26"), + findById(items, "pro_n26"), + findById(items, "pro_8m_n26"), + findById(items, "pro_m27"), + findById(items, "pro_12m_oneoff"), + findById(items, "pro_14m_m27"), + findById(items, "pro_18m_oneoff"), + findById(items, "pro_n27"), + findById(items, "pro_20m_n27"), + findById(items, "pro_24m_oneoff"), + findById(items, "pro_26m_m28"), + findById(items, "pro_m28"), +]; + +// Group 2 — Plus (base = plus_1m) +export const plusBase = findById(items, "plus_1m"); +export const plusVariants: ApiPlanV1[] = [ + findById(items, "plus_free_grant"), + findById(items, "plus_1m_new"), + findById(items, "plus_1w"), + findById(items, "plus_2m"), + findById(items, "plus_3m"), + findById(items, "plus_4m"), + findById(items, "plus_6m"), + findById(items, "plus_12m"), + findById(items, "plus_15m"), + findById(items, "plus_18m"), + findById(items, "plus_24m"), + findById(items, "plus_2m_m26"), + findById(items, "plus_6m_oneoff"), + findById(items, "plus_8m_n26"), + findById(items, "plus_12m_oneoff"), + findById(items, "plus_14m_m27"), + findById(items, "plus_18m_oneoff"), + findById(items, "plus_24m_oneoff"), + findById(items, "plus_26m_m28"), + findById(items, "plus_20m_n27"), +]; + +// Group 3 — Teacher Pro (base = pro_teacher_1m) +export const teacherProBase = findById(items, "pro_teacher_1m"); +export const teacherProVariants: ApiPlanV1[] = [ + findById(items, "pro_teacher"), + findById(items, "pro_teacher_24m"), +]; diff --git a/server/tests/integration/crud/plans/diffing/diffPlanV1.revisiondojo.test.ts b/server/tests/integration/crud/plans/diffing/diffPlanV1.revisiondojo.test.ts new file mode 100644 index 000000000..406648880 --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/diffPlanV1.revisiondojo.test.ts @@ -0,0 +1,32 @@ +import { type ApiPlanV1 } from "@autumn/shared"; +import { describe, expect, test } from "bun:test"; +import { diffPlanV1 } from "@autumn/shared/utils/planV1Utils/diff/diffPlanV1.js"; +import { applyDiff } from "@autumn/shared/utils/planV1Utils/diff/applyDiff.js"; +import { + proBase, + proVariants, + plusBase, + plusVariants, + teacherProBase, + teacherProVariants, +} from "./diffPlanV1.revisiondojo.fixtures.js"; +import { normalizePlan } from "./utils/normalizePlan.js"; + +// --- test matrix --- +const groups = [ + { name: "pro", base: proBase, variants: proVariants }, + { name: "plus", base: plusBase, variants: plusVariants }, + { name: "teacher_pro", base: teacherProBase, variants: teacherProVariants }, +]; + +for (const { name, base, variants } of groups) { + describe(`revisiondojo ${name} group — diff/apply round-trip`, () => { + for (const variant of variants) { + test(`${variant.id} reconstructs from ${base.id} + diff`, () => { + const diff = diffPlanV1({ from: base, to: variant }); + const reconstructed = applyDiff({ base, diff }); + expect(normalizePlan(reconstructed)).toEqual(normalizePlan(variant)); + }); + } + }); +} diff --git a/server/tests/integration/crud/plans/diffing/diffPlanV1.runable.fixtures.ts b/server/tests/integration/crud/plans/diffing/diffPlanV1.runable.fixtures.ts new file mode 100644 index 000000000..d0132d05a --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/diffPlanV1.runable.fixtures.ts @@ -0,0 +1,64 @@ +import { type ApiPlanV1 } from "@autumn/shared"; +import { findById } from "./utils/findById.js"; + +import runableDump from "./runable-plans.json" with { type: "json" }; + +const items = runableDump.items as ApiPlanV1[]; + +// Group 1 — Credit packs (base = runable_pro_25_monthly) +export const creditPackBase = findById(items, "runable_pro_25_monthly"); +export const creditPackVariants: ApiPlanV1[] = [ + findById(items, "runable_pro_50_monthly"), + findById(items, "runable_pro_75_monthly"), + findById(items, "runable_pro_100_monthly"), + findById(items, "runable_pro_200_monthly"), + findById(items, "runable_pro_300_monthly"), + findById(items, "runable_pro_400_monthly"), + findById(items, "runable_pro_500_monthly"), + findById(items, "runable_pro_750_monthly"), + findById(items, "runable_pro_1000_monthly"), + findById(items, "runable_pro_1500_monthly"), + findById(items, "runable_pro_2000_monthly"), + findById(items, "runable_pro_5000_monthly"), + findById(items, "runable_pro_10000_monthly"), + findById(items, "runable_pro_20000_monthly"), + findById(items, "runable_pro_25_yearly"), + findById(items, "runable_pro_50_yearly"), + findById(items, "runable_pro_75_yearly"), + findById(items, "runable_pro_100_yearly"), + findById(items, "runable_pro_200_yearly"), + findById(items, "runable_pro_300_yearly"), + findById(items, "runable_pro_400_yearly"), + findById(items, "runable_pro_500_yearly"), + findById(items, "runable_pro_750_yearly"), + findById(items, "runable_pro_1000_yearly"), + findById(items, "runable_pro_1500_yearly"), + findById(items, "runable_pro_2000_yearly"), + findById(items, "runable_pro_5000_yearly"), + findById(items, "runable_pro_10000_yearly"), + findById(items, "runable_pro_20000_yearly"), +]; + +// Group 2 — Plus tier +export const plusBase = findById(items, "runable_plus_monthly"); +export const plusVariants: ApiPlanV1[] = [findById(items, "runable_plus_yearly")]; + +// Group 3 — Pro tier +export const proBase = findById(items, "runable_pro_monthly"); +export const proVariants: ApiPlanV1[] = [findById(items, "runable_pro_yearly")]; + +// Group 4 — Unlimited tier +export const unlimitedBase = findById(items, "runable_unlimited_monthly"); +export const unlimitedVariants: ApiPlanV1[] = [findById(items, "runable_unlimited_yearly")]; + +// Group 5 — Free/starter +export const freeStarterBase = findById(items, "runable_go"); +export const freeStarterVariants: ApiPlanV1[] = [ + findById(items, "runable_basic"), + findById(items, "runable_starter_monthly"), + findById(items, "runable_starter_yearly"), +]; + +// Group 6 — Max tier +export const maxBase = findById(items, "runable_max_monthly"); +export const maxVariants: ApiPlanV1[] = [findById(items, "runable_max_yearly")]; diff --git a/server/tests/integration/crud/plans/diffing/diffPlanV1.runable.test.ts b/server/tests/integration/crud/plans/diffing/diffPlanV1.runable.test.ts new file mode 100644 index 000000000..b5f7db55b --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/diffPlanV1.runable.test.ts @@ -0,0 +1,41 @@ +import { type ApiPlanV1 } from "@autumn/shared"; +import { describe, expect, test } from "bun:test"; +import { diffPlanV1 } from "@autumn/shared/utils/planV1Utils/diff/diffPlanV1.js"; +import { applyDiff } from "@autumn/shared/utils/planV1Utils/diff/applyDiff.js"; +import { + creditPackBase, + creditPackVariants, + plusBase, + plusVariants, + proBase, + proVariants, + unlimitedBase, + unlimitedVariants, + freeStarterBase, + freeStarterVariants, + maxBase, + maxVariants, +} from "./diffPlanV1.runable.fixtures.js"; +import { normalizePlan } from "./utils/normalizePlan.js"; + +// --- test matrix --- +const groups = [ + { name: "credit_pack", base: creditPackBase, variants: creditPackVariants }, + { name: "plus", base: plusBase, variants: plusVariants }, + { name: "pro", base: proBase, variants: proVariants }, + { name: "unlimited", base: unlimitedBase, variants: unlimitedVariants }, + { name: "free_starter", base: freeStarterBase, variants: freeStarterVariants }, + { name: "max", base: maxBase, variants: maxVariants }, +]; + +for (const { name, base, variants } of groups) { + describe(`runable ${name} group — diff/apply round-trip`, () => { + for (const variant of variants) { + test(`${variant.id} reconstructs from ${base.id} + diff`, () => { + const diff = diffPlanV1({ from: base, to: variant }); + const reconstructed = applyDiff({ base, diff }); + expect(normalizePlan(reconstructed)).toEqual(normalizePlan(variant)); + }); + } + }); +} diff --git a/server/tests/integration/crud/plans/diffing/diffPlanV1.test.ts b/server/tests/integration/crud/plans/diffing/diffPlanV1.test.ts new file mode 100644 index 000000000..5f1f59728 --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/diffPlanV1.test.ts @@ -0,0 +1,53 @@ +import { type ApiPlanV1, BillingInterval } from "@autumn/shared"; +import { describe, expect, test } from "bun:test"; +import { diffPlanV1 } from "@autumn/shared/utils/planV1Utils/diff/diffPlanV1.js"; +import { popflyStart, popflyStartAnnual } from "./diffPlanV1.fixtures.js"; + +describe("diffPlanV1 — popfly start vs start_annual", () => { + test("start → start_annual: only price diffs (annual price)", () => { + const diff = diffPlanV1({ from: popflyStart, to: popflyStartAnnual }); + + expect(diff.price).toEqual({ amount: 5988, interval: BillingInterval.Year }); + expect(diff.add_items).toBeUndefined(); + expect(diff.remove_items).toBeUndefined(); + expect(diff.free_trial).toBeUndefined(); + }); + + test("start → start: empty diff (no fields set)", () => { + const diff = diffPlanV1({ from: popflyStart, to: popflyStart }); + + expect(diff).toEqual({}); + }); + + test("start_annual → start (reverse): price is the monthly price", () => { + const diff = diffPlanV1({ from: popflyStartAnnual, to: popflyStart }); + + expect(diff.price).toEqual({ amount: 499, interval: BillingInterval.Month }); + expect(diff.add_items).toBeUndefined(); + expect(diff.remove_items).toBeUndefined(); + expect(diff.free_trial).toBeUndefined(); + }); + + test("modify-in-place: same feature_id with different included → remove + add", () => { + const modified: ApiPlanV1 = { + ...popflyStart, + items: popflyStart.items.map((item) => + item.feature_id === "social_listening_terms" + ? { ...item, included: 999 } + : item, + ), + }; + + const diff = diffPlanV1({ from: popflyStart, to: modified }); + + expect(diff.remove_items).toEqual([ + { feature_id: "social_listening_terms" }, + ]); + expect(diff.add_items).toHaveLength(1); + expect(diff.add_items?.[0]).toMatchObject({ + feature_id: "social_listening_terms", + included: 999, + }); + expect(diff.price).toBeUndefined(); + }); +}); diff --git a/server/tests/integration/crud/plans/diffing/firecrawl-plans.json b/server/tests/integration/crud/plans/diffing/firecrawl-plans.json new file mode 100644 index 000000000..4961f679d --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/firecrawl-plans.json @@ -0,0 +1,2463 @@ +{ + "items": [ + { + "id": "concurrent_browser", + "name": "Concurrent Browser", + "description": null, + "group": null, + "version": 2, + "add_on": true, + "auto_enable": false, + "price": null, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 0, + "unlimited": false, + "reset": null, + "price": { + "amount": 96, + "interval": "year", + "billing_units": 1, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$96 per concurrency" + } + } + ], + "created_at": 1777978939457, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "credit_pack_1k", + "name": "Credit Pack 1k", + "description": null, + "group": null, + "version": 1, + "add_on": true, + "auto_enable": false, + "price": { + "amount": 9, + "interval": "month", + "display": { + "primary_text": "$9", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "1,000 credits" + } + } + ], + "created_at": 1773854694042, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "enterprise", + "name": "Enterprise", + "description": null, + "group": null, + "version": 2, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 38976, + "interval": "year", + "display": { + "primary_text": "$38,976", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 2137, + "interval": "one_off", + "billing_units": 2450000, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$2,137 per 2,450,000 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 200, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "200 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 7000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "7,000,000 credits" + }, + "rollover": { + "max": null, + "max_percentage": null, + "expiry_duration_type": "month", + "expiry_duration_length": 2 + } + } + ], + "created_at": 1775778953524, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": true + } + }, + { + "id": "enterprise_expansion", + "name": "Enterprise Metered Expansion", + "description": null, + "group": null, + "version": 2, + "add_on": true, + "auto_enable": false, + "price": { + "amount": 5520, + "interval": "year", + "display": { + "primary_text": "$5,520", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 12000000, + "unlimited": false, + "reset": { + "interval": "year" + }, + "price": null, + "display": { + "primary_text": "12,000,000 credits" + } + } + ], + "created_at": 1778251701842, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "enterprise_metered", + "name": "Enterprise Metered", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 27830, + "interval": "year", + "display": { + "primary_text": "$27,830", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 150, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "150 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 5000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "5,000,000 credits" + }, + "rollover": { + "max": 0, + "max_percentage": null, + "expiry_duration_type": "month", + "expiry_duration_length": 2 + } + } + ], + "created_at": 1773854702144, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": true + } + }, + { + "id": "extract_explorer_monthly", + "name": "Extract Explorer", + "description": null, + "group": "extract", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 399, + "interval": "month", + "display": { + "primary_text": "$399", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 466667, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "466,667 credits" + } + } + ], + "created_at": 1773854704525, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "extract_explorer_yearly", + "name": "Extract Explorer (Yearly)", + "description": null, + "group": "extract", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 4308, + "interval": "year", + "display": { + "primary_text": "$4,308", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 5600000, + "unlimited": false, + "reset": { + "interval": "year" + }, + "price": null, + "display": { + "primary_text": "5,600,000 credits" + } + } + ], + "created_at": 1773854706910, + "env": "live", + "archived": false, + "base_variant_id": "extract_explorer_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "extract_pro", + "name": "Extract Pro", + "description": null, + "group": "extract", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 899, + "interval": "month", + "display": { + "primary_text": "$899", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 1333333, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "1,333,333 credits" + } + } + ], + "created_at": 1773854709451, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "extract_pro_yearly", + "name": "Extract Pro (Yearly)", + "description": null, + "group": "extract", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 8628, + "interval": "year", + "display": { + "primary_text": "$8,628", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 8000000, + "unlimited": false, + "reset": { + "interval": "year" + }, + "price": null, + "display": { + "primary_text": "8,000,000 credits" + } + } + ], + "created_at": 1773854833713, + "env": "live", + "archived": false, + "base_variant_id": "extract_pro", + "config": { + "ignore_past_due": false + } + }, + { + "id": "extract_starter", + "name": "Extract Starter", + "description": null, + "group": "extract", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 99, + "interval": "month", + "display": { + "primary_text": "$99", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 100000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "100,000 credits" + } + } + ], + "created_at": 1773854837037, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "extract_starter_yearly", + "name": "Extract Starter (Yearly)", + "description": null, + "group": "extract", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 1068, + "interval": "year", + "display": { + "primary_text": "$1,068", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 1200000, + "unlimited": false, + "reset": { + "interval": "year" + }, + "price": null, + "display": { + "primary_text": "1,200,000 credits" + } + } + ], + "created_at": 1773854839364, + "env": "live", + "archived": false, + "base_variant_id": "extract_starter", + "config": { + "ignore_past_due": false + } + }, + { + "id": "free", + "name": "Free", + "description": null, + "group": null, + "version": 2, + "add_on": false, + "auto_enable": true, + "price": null, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 2, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "2 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "1,000 credits" + } + } + ], + "created_at": 1778072155064, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "growth", + "name": "Growth", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 399, + "interval": "month", + "display": { + "primary_text": "$399", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 217, + "interval": "one_off", + "billing_units": 150000, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$217 per 150,000 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 100, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "100 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 500000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "500,000 credits" + } + } + ], + "created_at": 1773317212882, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "growth_monthly_500k", + "name": "Growth (500k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 399, + "interval": "month", + "display": { + "primary_text": "$399", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 100, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "100 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 500000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "500,000 credits" + } + } + ], + "created_at": 1778644941752, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "growth_monthly_650k", + "name": "Growth (650k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 616, + "interval": "month", + "display": { + "primary_text": "$616", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 100, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "100 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 650000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "650,000 credits" + } + } + ], + "created_at": 1778644945443, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "growth_monthly_800k", + "name": "Growth (800k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 833, + "interval": "month", + "display": { + "primary_text": "$833", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 100, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "100 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 800000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "800,000 credits" + } + } + ], + "created_at": 1778644948949, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "growth_yearly", + "name": "Growth (Yearly)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 3990, + "interval": "year", + "display": { + "primary_text": "$3,990", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 177, + "interval": "one_off", + "billing_units": 175000, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$177 per 175,000 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 100, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "100 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 500000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "500,000 credits" + } + } + ], + "created_at": 1773317215521, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "growth_yearly_500k", + "name": "Growth Yearly (500k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 3990, + "interval": "year", + "display": { + "primary_text": "$3,990", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 100, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "100 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 500000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "500,000 credits" + } + } + ], + "created_at": 1778645211284, + "env": "live", + "archived": false, + "base_variant_id": "growth_monthly_500k", + "config": { + "ignore_past_due": false + } + }, + { + "id": "growth_yearly_650k", + "name": "Growth Yearly (650k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 6160, + "interval": "year", + "display": { + "primary_text": "$6,160", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 100, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "100 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 650000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "650,000 credits" + } + } + ], + "created_at": 1778645212029, + "env": "live", + "archived": false, + "base_variant_id": "growth_monthly_650k", + "config": { + "ignore_past_due": false + } + }, + { + "id": "hobby", + "name": "Hobby", + "description": null, + "group": null, + "version": 2, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 19, + "interval": "month", + "display": { + "primary_text": "$19", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 9, + "interval": "one_off", + "billing_units": 1500, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$9 per 1,500 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 5, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "5 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 5000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "5,000 credits" + } + } + ], + "created_at": 1778072203300, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "hobby_monthly_5k", + "name": "Hobby (5k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 19, + "interval": "month", + "display": { + "primary_text": "$19", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 5, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "5 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 5000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "5,000 credits" + } + } + ], + "created_at": 1778643662039, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "hobby_monthly_6_5k", + "name": "Hobby (6.5k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 28, + "interval": "month", + "display": { + "primary_text": "$28", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 5, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "5 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 6500, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "6,500 credits" + } + } + ], + "created_at": 1778644675386, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "hobby_monthly_8k", + "name": "Hobby (8k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 37, + "interval": "month", + "display": { + "primary_text": "$37", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 5, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "5 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 8000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "8,000 credits" + } + } + ], + "created_at": 1778644679445, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "hobby_yearly", + "name": "Hobby (Yearly)", + "description": null, + "group": null, + "version": 2, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 190, + "interval": "year", + "display": { + "primary_text": "$190", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 9, + "interval": "one_off", + "billing_units": 1500, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$9 per 1,500 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 5, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "5 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 5000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "5,000 credits" + } + } + ], + "created_at": 1778072255911, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "hobby_yearly_5k", + "name": "Hobby Yearly (5k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 190, + "interval": "year", + "display": { + "primary_text": "$190", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 5, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "5 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 5000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "5,000 credits" + } + } + ], + "created_at": 1778645197783, + "env": "live", + "archived": false, + "base_variant_id": "hobby_monthly_5k", + "config": { + "ignore_past_due": false + } + }, + { + "id": "hobby_yearly_6_5k", + "name": "Hobby Yearly (6.5k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 290, + "interval": "year", + "display": { + "primary_text": "$290", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 5, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "5 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 6500, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "6,500 credits" + } + } + ], + "created_at": 1778645199336, + "env": "live", + "archived": false, + "base_variant_id": "hobby_monthly_6_5k", + "config": { + "ignore_past_due": false + } + }, + { + "id": "hobby_yearly_8k", + "name": "Hobby Yearly (8k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 390, + "interval": "year", + "display": { + "primary_text": "$390", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 5, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "5 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 8000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "8,000 credits" + } + } + ], + "created_at": 1778645201202, + "env": "live", + "archived": false, + "base_variant_id": "hobby_monthly_8k", + "config": { + "ignore_past_due": false + } + }, + { + "id": "legacy_scale_enterprise", + "name": "Legacy Scale/Enterprise", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": null, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 150, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "150 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 1000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "1,000,000 credits" + } + } + ], + "created_at": 1774028248100, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "legacy_standard", + "name": "Legacy Standard", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": null, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 50, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "50 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 500000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "500,000 credits" + } + } + ], + "created_at": 1773855640751, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "legacy_starter", + "name": "Legacy Starter", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": null, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 50, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "50 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 50000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "50,000 credits" + } + } + ], + "created_at": 1773855644561, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "scale_monthly", + "name": "Scale (Monthly)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 749, + "interval": "month", + "display": { + "primary_text": "$749", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 397, + "interval": "one_off", + "billing_units": 300000, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$397 per 300,000 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 100, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "100 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 1000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "1,000,000 credits" + } + } + ], + "created_at": 1773317235829, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "scale_tier_1", + "name": "Scale Tier 1", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 7190, + "interval": "year", + "display": { + "primary_text": "$7,190", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 407, + "interval": "one_off", + "billing_units": 350000, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$407 per 350,000 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 150, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "150 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 1000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "1,000,000 credits" + }, + "rollover": { + "max": null, + "max_percentage": null, + "expiry_duration_type": "month", + "expiry_duration_length": 1 + } + } + ], + "created_at": 1773317241022, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "scale_tier_1_quarterly", + "name": "Scale Tier 1 (Quarterly)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 2022, + "interval": "quarter", + "display": { + "primary_text": "$2,022", + "secondary_text": "per quarter" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 407, + "interval": "one_off", + "billing_units": 350000, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$407 per 350,000 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 150, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "150 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 1000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "1,000,000 credits" + } + } + ], + "created_at": 1773855648989, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "scale_tier_2", + "name": "Scale Tier 2", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 13430, + "interval": "year", + "display": { + "primary_text": "$13,430", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 737, + "interval": "one_off", + "billing_units": 700000, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$737 per 700,000 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 150, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "150 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 2000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "2,000,000 credits" + }, + "rollover": { + "max": null, + "max_percentage": null, + "expiry_duration_type": "month", + "expiry_duration_length": 1 + } + } + ], + "created_at": 1773317249023, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": true + } + }, + { + "id": "scale_tier_2_quarterly", + "name": "Scale Tier 2 (Quarterly)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 3777, + "interval": "quarter", + "display": { + "primary_text": "$3,777", + "secondary_text": "per quarter" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 737, + "interval": "one_off", + "billing_units": 700000, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$737 per 700,000 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 150, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "150 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 2000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "2,000,000 credits" + } + } + ], + "created_at": 1773855652530, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": true + } + }, + { + "id": "scale_tier_3", + "name": "Scale Tier 3", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 18710, + "interval": "year", + "display": { + "primary_text": "$18,710", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 977, + "interval": "one_off", + "billing_units": 1000000, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$977 per 1,000,000 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 150, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "150 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 3000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "3,000,000 credits" + }, + "rollover": { + "max": null, + "max_percentage": null, + "expiry_duration_type": "month", + "expiry_duration_length": 1 + } + } + ], + "created_at": 1773317256818, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": true + } + }, + { + "id": "scale_tier_3_quarterly", + "name": "Scale Tier 3 (Quarterly)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 5262, + "interval": "quarter", + "display": { + "primary_text": "$5,262", + "secondary_text": "per quarter" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 977, + "interval": "one_off", + "billing_units": 1000000, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$977 per 1,000,000 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 150, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "150 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 3000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "3,000,000 credits" + } + } + ], + "created_at": 1773855656092, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": true + } + }, + { + "id": "scale_tier_4", + "name": "Scale Tier 4", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 23030, + "interval": "year", + "display": { + "primary_text": "$23,030", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 1257, + "interval": "one_off", + "billing_units": 1400000, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$1,257 per 1,400,000 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 150, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "150 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 4000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "4,000,000 credits" + }, + "rollover": { + "max": null, + "max_percentage": null, + "expiry_duration_type": "month", + "expiry_duration_length": 1 + } + } + ], + "created_at": 1773317267120, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": true + } + }, + { + "id": "scale_tier_4_quarterly", + "name": "Scale Tier 4 (Quarterly)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 6477, + "interval": "quarter", + "display": { + "primary_text": "$6,477", + "secondary_text": "per quarter" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 1257, + "interval": "one_off", + "billing_units": 1400000, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$1,257 per 1,400,000 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 150, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "150 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 4000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "4,000,000 credits" + } + } + ], + "created_at": 1773855659690, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": true + } + }, + { + "id": "standard", + "name": "Standard", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 99, + "interval": "month", + "display": { + "primary_text": "$99", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 57, + "interval": "one_off", + "billing_units": 30000, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$57 per 30,000 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 50, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "50 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 100000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "100,000 credits" + } + } + ], + "created_at": 1773317274820, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "standard_monthly_100k", + "name": "Standard (100k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 99, + "interval": "month", + "display": { + "primary_text": "$99", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 50, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "50 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 100000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "100,000 credits" + } + } + ], + "created_at": 1778644930456, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "standard_monthly_130k", + "name": "Standard (130k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 156, + "interval": "month", + "display": { + "primary_text": "$156", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 50, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "50 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 130000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "130,000 credits" + } + } + ], + "created_at": 1778644934131, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "standard_monthly_160k", + "name": "Standard (160k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 213, + "interval": "month", + "display": { + "primary_text": "$213", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 50, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "50 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 160000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "160,000 credits" + } + } + ], + "created_at": 1778644938206, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "standard_yearly", + "name": "Standard (Yearly)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 990, + "interval": "year", + "display": { + "primary_text": "$990", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CREDITS", + "included": 0, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": { + "amount": 47, + "interval": "one_off", + "billing_units": 35000, + "billing_method": "prepaid", + "max_purchase": null + }, + "display": { + "primary_text": "$47 per 35,000 credits" + } + }, + { + "feature_id": "CONCURRENCY", + "included": 50, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "50 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 100000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "100,000 credits" + } + } + ], + "created_at": 1773317277420, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "standard_yearly_100k", + "name": "Standard Yearly (100k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 990, + "interval": "year", + "display": { + "primary_text": "$990", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 50, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "50 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 100000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "100,000 credits" + } + } + ], + "created_at": 1778645202781, + "env": "live", + "archived": false, + "base_variant_id": "standard_monthly_100k", + "config": { + "ignore_past_due": false + } + }, + { + "id": "standard_yearly_130k", + "name": "Standard Yearly (130k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 1590, + "interval": "year", + "display": { + "primary_text": "$1,590", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 50, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "50 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 130000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "130,000 credits" + } + } + ], + "created_at": 1778645209666, + "env": "live", + "archived": false, + "base_variant_id": "standard_monthly_130k", + "config": { + "ignore_past_due": false + } + }, + { + "id": "standard_yearly_160k", + "name": "Standard Yearly (160k credits/month)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 2190, + "interval": "year", + "display": { + "primary_text": "$2,190", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "CONCURRENCY", + "included": 50, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "50 concurrencies" + } + }, + { + "feature_id": "CREDITS", + "included": 160000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "160,000 credits" + } + } + ], + "created_at": 1778645210511, + "env": "live", + "archived": false, + "base_variant_id": "standard_monthly_160k", + "config": { + "ignore_past_due": false + } + } + ] +} diff --git a/server/tests/integration/crud/plans/diffing/oneprep-plans.json b/server/tests/integration/crud/plans/diffing/oneprep-plans.json new file mode 100644 index 000000000..dbeda6dda --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/oneprep-plans.json @@ -0,0 +1,771 @@ +{ + "items": [ + { + "id": "free", + "name": "Free", + "description": null, + "group": null, + "version": 8, + "add_on": false, + "auto_enable": true, + "price": null, + "items": [ + { + "feature_id": "orbs_credit", + "included": 10, + "unlimited": false, + "reset": { + "interval": "week" + }, + "price": null, + "display": { + "primary_text": "10 orbs credits" + }, + "rollover": { + "max": 20, + "max_percentage": null, + "expiry_duration_type": "forever", + "expiry_duration_length": 1 + } + }, + { + "feature_id": "orbs_credit", + "included": 10, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "10 orbs credits" + } + }, + { + "feature_id": "read_lesson", + "included": 3, + "unlimited": false, + "reset": { + "interval": "week" + }, + "price": null, + "display": { + "primary_text": "3 read lessons" + } + }, + { + "feature_id": "read_note", + "included": 3, + "unlimited": false, + "reset": { + "interval": "week" + }, + "price": null, + "display": { + "primary_text": "3 read notes" + } + }, + { + "feature_id": "remix_question_new", + "included": 1, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "1 remix question" + } + } + ], + "created_at": 1778484988714, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus", + "name": "Plus", + "description": null, + "group": null, + "version": 2, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 29, + "interval": "month", + "display": { + "primary_text": "$29", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "all_diagnostic_tests", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "All diagnostic tests" + } + }, + { + "feature_id": "all_predicted_papers", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "All predicted papers" + } + }, + { + "feature_id": "orbs_credit", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited orbs credits" + } + }, + { + "feature_id": "premium_questions", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Premium Questions" + } + } + ], + "created_at": 1776913987190, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_12m", + "name": "Pro (12 months)", + "description": null, + "group": null, + "version": 4, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 216, + "interval": "month", + "interval_count": 12, + "display": { + "primary_text": "$216", + "secondary_text": "per 12 months" + } + }, + "items": [ + { + "feature_id": "all_diagnostic_tests", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "All diagnostic tests" + } + }, + { + "feature_id": "all_predicted_papers", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "All predicted papers" + } + }, + { + "feature_id": "error_analytics", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Error analytics" + } + }, + { + "feature_id": "orbs_credit", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited orbs credits" + } + }, + { + "feature_id": "premium_cheatsheets", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Premium Cheatsheets" + } + }, + { + "feature_id": "premium_questions", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Premium Questions" + } + }, + { + "feature_id": "remix_question_new", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited remix questions" + } + } + ], + "created_at": 1778656068706, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_1m", + "name": "Pro (1 month)", + "description": null, + "group": null, + "version": 5, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 43.5, + "interval": "month", + "display": { + "primary_text": "$43.5", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "all_diagnostic_tests", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "All diagnostic tests" + } + }, + { + "feature_id": "all_predicted_papers", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "All predicted papers" + } + }, + { + "feature_id": "error_analytics", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Error analytics" + } + }, + { + "feature_id": "orbs_credit", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited orbs credits" + } + }, + { + "feature_id": "premium_cheatsheets", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Premium Cheatsheets" + } + }, + { + "feature_id": "premium_questions", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Premium Questions" + } + }, + { + "feature_id": "remix_question_new", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited remix questions" + } + } + ], + "created_at": 1778656038341, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_1w", + "name": "Pro (1 week)", + "description": null, + "group": null, + "version": 4, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 28.5, + "interval": "week", + "display": { + "primary_text": "$28.5", + "secondary_text": "per week" + } + }, + "items": [ + { + "feature_id": "all_diagnostic_tests", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "All diagnostic tests" + } + }, + { + "feature_id": "all_predicted_papers", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "All predicted papers" + } + }, + { + "feature_id": "error_analytics", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Error analytics" + } + }, + { + "feature_id": "orbs_credit", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited orbs credits" + } + }, + { + "feature_id": "premium_cheatsheets", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Premium Cheatsheets" + } + }, + { + "feature_id": "premium_questions", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Premium Questions" + } + }, + { + "feature_id": "remix_question_new", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited remix questions" + } + } + ], + "created_at": 1778656024331, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_3m", + "name": "Pro (3 months)", + "description": null, + "group": null, + "version": 4, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 103.5, + "interval": "month", + "interval_count": 3, + "display": { + "primary_text": "$103.5", + "secondary_text": "per 3 months" + } + }, + "items": [ + { + "feature_id": "all_diagnostic_tests", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "All diagnostic tests" + } + }, + { + "feature_id": "all_predicted_papers", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "All predicted papers" + } + }, + { + "feature_id": "error_analytics", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Error analytics" + } + }, + { + "feature_id": "orbs_credit", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited orbs credits" + } + }, + { + "feature_id": "premium_cheatsheets", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Premium Cheatsheets" + } + }, + { + "feature_id": "premium_questions", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Premium Questions" + } + }, + { + "feature_id": "remix_question_new", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited remix questions" + } + } + ], + "created_at": 1778655992720, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_6m", + "name": "Pro (6 months)", + "description": null, + "group": null, + "version": 4, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 144, + "interval": "month", + "interval_count": 6, + "display": { + "primary_text": "$144", + "secondary_text": "per 6 months" + } + }, + "items": [ + { + "feature_id": "all_diagnostic_tests", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "All diagnostic tests" + } + }, + { + "feature_id": "all_predicted_papers", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "All predicted papers" + } + }, + { + "feature_id": "error_analytics", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Error analytics" + } + }, + { + "feature_id": "orbs_credit", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited orbs credits" + } + }, + { + "feature_id": "premium_cheatsheets", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Premium Cheatsheets" + } + }, + { + "feature_id": "premium_questions", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Premium Questions" + } + }, + { + "feature_id": "remix_question_new", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited remix questions" + } + } + ], + "created_at": 1778655965941, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_june_2026", + "name": "Pro (June 2026)", + "description": null, + "group": null, + "version": 3, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 35.99, + "interval": "one_off", + "display": { + "primary_text": "$35.99" + } + }, + "items": [ + { + "feature_id": "all_diagnostic_tests", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "All diagnostic tests" + } + }, + { + "feature_id": "all_predicted_papers", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "All predicted papers" + } + }, + { + "feature_id": "error_analytics", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Error analytics" + } + }, + { + "feature_id": "orbs_credit", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited orbs credits" + } + }, + { + "feature_id": "premium_cheatsheets", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Premium Cheatsheets" + } + }, + { + "feature_id": "premium_questions", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Premium Questions" + } + }, + { + "feature_id": "question_remix", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited question remixes" + } + }, + { + "feature_id": "remix_question_new", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited remix questions" + } + } + ], + "created_at": 1779075195611, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + } + ] +} \ No newline at end of file diff --git a/server/tests/integration/crud/plans/diffing/revisiondojo-plans.json b/server/tests/integration/crud/plans/diffing/revisiondojo-plans.json new file mode 100644 index 000000000..09d1149ba --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/revisiondojo-plans.json @@ -0,0 +1,5642 @@ +{ + "items": [ + { + "id": "free", + "name": "Free", + "description": null, + "group": null, + "version": 6, + "add_on": false, + "auto_enable": true, + "price": null, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "1,000 AI checker words" + } + }, + { + "feature_id": "create_lesson", + "included": 3, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "3 create lessons" + } + }, + { + "feature_id": "create_test", + "included": 3, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "3 create tests" + } + }, + { + "feature_id": "energy", + "included": 10, + "unlimited": false, + "reset": { + "interval": "week" + }, + "price": null, + "display": { + "primary_text": "10 energies" + } + }, + { + "feature_id": "energy", + "included": 10, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "10 energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 5, + "unlimited": false, + "reset": { + "interval": "week" + }, + "price": null, + "display": { + "primary_text": "5 read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 3, + "unlimited": false, + "reset": { + "interval": "week" + }, + "price": null, + "display": { + "primary_text": "3 read lessons" + } + }, + { + "feature_id": "read_note", + "included": 3, + "unlimited": false, + "reset": { + "interval": "week" + }, + "price": null, + "display": { + "primary_text": "3 read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 10, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "10 read walkthroughs" + } + }, + { + "feature_id": "teach_jojo_session", + "included": 3, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "3 teach jojo sessions" + } + }, + { + "feature_id": "teacher_coursework_grader", + "included": 3, + "unlimited": false, + "reset": { + "interval": "week" + }, + "price": null, + "display": { + "primary_text": "3 teacher coursework graders" + } + } + ], + "created_at": 1774838343324, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_12m", + "name": "Plus (12 months)", + "description": null, + "group": "personal_sub", + "version": 13, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 732, + "interval": "year", + "display": { + "primary_text": "$732", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770403301468, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_12m_oneoff", + "name": "Plus", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 696, + "interval": "one_off", + "interval_count": 3, + "display": { + "primary_text": "$696" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770740067183, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_14m_m27", + "name": "Plus", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 756, + "interval": "one_off", + "interval_count": 3, + "display": { + "primary_text": "$756" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770740067183, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_15m", + "name": "Plus (15 months)", + "description": null, + "group": "personal_sub", + "version": 2, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 180, + "interval": "month", + "interval_count": 15, + "display": { + "primary_text": "$180", + "secondary_text": "per 15 months" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770402863094, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_18m", + "name": "Plus (18 months)", + "description": null, + "group": "personal_sub", + "version": 6, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 810, + "interval": "month", + "interval_count": 18, + "display": { + "primary_text": "$810", + "secondary_text": "per 18 months" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770389954591, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_18m_oneoff", + "name": "Plus", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 756, + "interval": "one_off", + "interval_count": 3, + "display": { + "primary_text": "$756" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770740067183, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_1m", + "name": "Plus (1 month)", + "description": null, + "group": "personal_sub", + "version": 9, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 129, + "interval": "month", + "display": { + "primary_text": "$129", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1772764131640, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_1m_new", + "name": "Plus (1 month)", + "description": null, + "group": "personal_sub", + "version": 2, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 230, + "interval": "month", + "display": { + "primary_text": "$230", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1776656856472, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_1w", + "name": "Plus (1 week)", + "description": null, + "group": "personal_sub", + "version": 3, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 130, + "interval": "week", + "display": { + "primary_text": "$130", + "secondary_text": "per week" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1776656945134, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_20m_n27", + "name": "Plus", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 840, + "interval": "one_off", + "interval_count": 3, + "display": { + "primary_text": "$840" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770740067183, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_24m", + "name": "Plus (24 months)", + "description": null, + "group": "personal_sub", + "version": 9, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 840, + "interval": "year", + "interval_count": 2, + "display": { + "primary_text": "$840", + "secondary_text": "per 2 years" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770389963914, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_24m_oneoff", + "name": "Plus", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 816, + "interval": "one_off", + "interval_count": 3, + "display": { + "primary_text": "$816" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770740067183, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_26m_m28", + "name": "Plus", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 816, + "interval": "one_off", + "interval_count": 3, + "display": { + "primary_text": "$816" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770740067183, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_2m", + "name": "Plus (2 months)", + "description": null, + "group": "personal_sub", + "version": 2, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 348, + "interval": "month", + "interval_count": 2, + "display": { + "primary_text": "$348", + "secondary_text": "per 2 months" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1772262541789, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_2m_m26", + "name": "Plus", + "description": null, + "group": "personal_oneoff", + "version": 3, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 350, + "interval": "one_off", + "interval_count": 3, + "display": { + "primary_text": "$350" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1776656791638, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_3m", + "name": "Plus (3 months)", + "description": null, + "group": "personal_sub", + "version": 11, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 462, + "interval": "month", + "interval_count": 3, + "display": { + "primary_text": "$462", + "secondary_text": "per 3 months" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770740067183, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_4m", + "name": "Plus (4 months)", + "description": null, + "group": "personal_sub", + "version": 5, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 536, + "interval": "month", + "interval_count": 4, + "display": { + "primary_text": "$536", + "secondary_text": "per 4 months" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770389934153, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_6m", + "name": "Plus (6 months)", + "description": null, + "group": "personal_sub", + "version": 12, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 570, + "interval": "month", + "interval_count": 6, + "display": { + "primary_text": "$570", + "secondary_text": "per 6 months" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770351892772, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_6m_oneoff", + "name": "Plus", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 540, + "interval": "one_off", + "interval_count": 3, + "display": { + "primary_text": "$540" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770740067183, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_8m_n26", + "name": "Plus", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 656, + "interval": "one_off", + "interval_count": 3, + "display": { + "primary_text": "$656" + } + }, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770740067183, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "plus_free_grant", + "name": "Plus (Free Grant)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": null, + "items": [ + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + } + ], + "created_at": 1770452484251, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_12m", + "name": "Pro (12 months)", + "description": null, + "group": "personal_sub", + "version": 9, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 780, + "interval": "year", + "display": { + "primary_text": "$780", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1770389949158, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_12m_oneoff", + "name": "Pro", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 798, + "interval": "one_off", + "display": { + "primary_text": "$798" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1772244766802, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_14m_m27", + "name": "Pro", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 812, + "interval": "one_off", + "display": { + "primary_text": "$812" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1772244766802, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_15m", + "name": "Pro (15 months)", + "description": null, + "group": "personal_sub", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 285, + "interval": "month", + "interval_count": 15, + "display": { + "primary_text": "$285", + "secondary_text": "per 15 months" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1770203599491, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_18m", + "name": "Pro (18 months)", + "description": null, + "group": "personal_sub", + "version": 5, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 882, + "interval": "month", + "interval_count": 18, + "display": { + "primary_text": "$882", + "secondary_text": "per 18 months" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1770389958694, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_18m_oneoff", + "name": "Pro", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 828, + "interval": "one_off", + "display": { + "primary_text": "$828" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1772244766802, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_1_month_mobile", + "name": "Pro (1 month)", + "description": null, + "group": "personal_sub", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 149, + "interval": "month", + "display": { + "primary_text": "$149", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1774951020658, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_1m", + "name": "Pro (1 month)", + "description": null, + "group": "personal_sub", + "version": 7, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 139, + "interval": "month", + "display": { + "primary_text": "$139", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + }, + { + "feature_id": "teacher_coursework_grader", + "included": 5, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "5 teacher coursework graders" + } + } + ], + "created_at": 1773193560245, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_1m_new", + "name": "Pro (1 month)", + "description": null, + "group": "personal_sub", + "version": 2, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 238, + "interval": "month", + "display": { + "primary_text": "$238", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + }, + { + "feature_id": "teacher_coursework_grader", + "included": 5, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "5 teacher coursework graders" + } + } + ], + "created_at": 1776656842190, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_1w", + "name": "Pro (1 week)", + "description": null, + "group": "personal_sub", + "version": 2, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 138, + "interval": "week", + "display": { + "primary_text": "$138", + "secondary_text": "per week" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + }, + { + "feature_id": "teacher_coursework_grader", + "included": 5, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "5 teacher coursework graders" + } + } + ], + "created_at": 1776656898626, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_20m_n27", + "name": "Pro", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 920, + "interval": "one_off", + "display": { + "primary_text": "$920" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1772244766802, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_24m", + "name": "Pro (24 months)", + "description": null, + "group": "personal_sub", + "version": 6, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 936, + "interval": "year", + "interval_count": 2, + "display": { + "primary_text": "$936", + "secondary_text": "per 2 years" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1770389969621, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_24m_oneoff", + "name": "Pro", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 912, + "interval": "one_off", + "display": { + "primary_text": "$912" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1772244766802, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_26m_m28", + "name": "Pro", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 988, + "interval": "one_off", + "display": { + "primary_text": "$988" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1772244766802, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_2m", + "name": "Pro (2 months)", + "description": null, + "group": "personal_sub", + "version": 2, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 356, + "interval": "month", + "interval_count": 2, + "display": { + "primary_text": "$356", + "secondary_text": "per 2 months" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1772262524130, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_2m_m26", + "name": "Pro", + "description": null, + "group": "personal_oneoff", + "version": 5, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 358, + "interval": "one_off", + "display": { + "primary_text": "$358" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1777451713406, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_3m", + "name": "Pro (3 months)", + "description": null, + "group": "personal_sub", + "version": 7, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 474, + "interval": "month", + "interval_count": 3, + "display": { + "primary_text": "$474", + "secondary_text": "per 3 months" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1770740063500, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_3m_special", + "name": "Pro (3 months)", + "description": null, + "group": "personal_sub", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 299, + "interval": "month", + "interval_count": 3, + "display": { + "primary_text": "$299", + "secondary_text": "per 3 months" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1770740063500, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_4m", + "name": "Pro (4 months)", + "description": null, + "group": "personal_sub", + "version": 5, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 552, + "interval": "month", + "interval_count": 4, + "display": { + "primary_text": "$552", + "secondary_text": "per 4 months" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1770389937913, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_6m", + "name": "Pro (6 months)", + "description": null, + "group": "personal_sub", + "version": 8, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 594, + "interval": "month", + "interval_count": 6, + "display": { + "primary_text": "$594", + "secondary_text": "per 6 months" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1770389942710, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_6m_oneoff", + "name": "Pro", + "description": null, + "group": "personal_oneoff", + "version": 2, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 588, + "interval": "one_off", + "display": { + "primary_text": "$588" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1778823513623, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_8m_n26", + "name": "Pro", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 688, + "interval": "one_off", + "display": { + "primary_text": "$688" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1772244766802, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_free_grant", + "name": "Pro (Free Grant)", + "description": null, + "group": null, + "version": 4, + "add_on": false, + "auto_enable": false, + "price": null, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "free_trial": { + "duration_length": 180, + "duration_type": "day", + "card_required": true + }, + "created_at": 1773220491531, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_m26", + "name": "Pro (M26)", + "description": null, + "group": "personal_oneoff", + "version": 2, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 138, + "interval": "one_off", + "display": { + "primary_text": "$138" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1778157609759, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_m27", + "name": "Pro (M27)", + "description": null, + "group": "personal_oneoff", + "version": 3, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 798, + "interval": "one_off", + "display": { + "primary_text": "$798" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1778334816203, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_m28", + "name": "Pro (M28)", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 998, + "interval": "one_off", + "display": { + "primary_text": "$998" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1772244766802, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_n26", + "name": "Pro (N26)", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 498, + "interval": "one_off", + "display": { + "primary_text": "$498" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1772257336344, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_n27", + "name": "Pro (N27)", + "description": null, + "group": "personal_oneoff", + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 898, + "interval": "one_off", + "display": { + "primary_text": "$898" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + } + ], + "created_at": 1772257458795, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_teacher", + "name": "Teacher Pro", + "description": null, + "group": null, + "version": 2, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 399, + "interval": "year", + "display": { + "primary_text": "$399", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "create_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited create lessons" + } + }, + { + "feature_id": "create_test", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited create tests" + } + }, + { + "feature_id": "enabled_subject", + "included": 3, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "3 enabled subjects" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + }, + { + "feature_id": "teacher_coursework_grader", + "included": 150, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "150 teacher coursework graders" + } + } + ], + "created_at": 1773221106920, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_teacher_1m", + "name": "Teacher Pro (1m)", + "description": null, + "group": null, + "version": 2, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 149, + "interval": "month", + "display": { + "primary_text": "$149", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "create_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited create lessons" + } + }, + { + "feature_id": "create_test", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited create tests" + } + }, + { + "feature_id": "enabled_subject", + "included": 3, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "3 enabled subjects" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + }, + { + "feature_id": "teacher_coursework_grader", + "included": 150, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "150 teacher coursework graders" + } + } + ], + "created_at": 1773821622225, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_teacher_24m", + "name": "Teacher Pro (2 years)", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 549, + "interval": "year", + "interval_count": 2, + "display": { + "primary_text": "$549", + "secondary_text": "per 2 years" + } + }, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "create_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited create lessons" + } + }, + { + "feature_id": "create_test", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited create tests" + } + }, + { + "feature_id": "enabled_subject", + "included": 3, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "3 enabled subjects" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + }, + { + "feature_id": "teacher_coursework_grader", + "included": 150, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "150 teacher coursework graders" + } + } + ], + "created_at": 1773221106920, + "env": "live", + "archived": false, + "base_variant_id": "pro_teacher_1m", + "config": { + "ignore_past_due": false + } + }, + { + "id": "pro_teacher_trial", + "name": "Teacher Pro (Grant)", + "description": null, + "group": null, + "version": 5, + "add_on": false, + "auto_enable": false, + "price": null, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "create_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited create lessons" + } + }, + { + "feature_id": "create_test", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited create tests" + } + }, + { + "feature_id": "enabled_subject", + "included": 3, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "3 enabled subjects" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 5, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5 grader daily quotas" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + }, + { + "feature_id": "school_student", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited student seats" + } + }, + { + "feature_id": "teacher_coursework_grader", + "included": 150, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "150 teacher coursework graders" + } + }, + { + "feature_id": "school_teacher", + "included": 0, + "unlimited": true, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited teacher seats" + } + } + ], + "created_at": 1778143401133, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "school_pro", + "name": "Classroom Pro", + "description": null, + "group": null, + "version": 11, + "add_on": false, + "auto_enable": false, + "price": null, + "items": [ + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "ai_checker_word", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 AI checker words" + } + }, + { + "feature_id": "assign_tests", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Assign tests" + } + }, + { + "feature_id": "can_add_students", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Can add students" + } + }, + { + "feature_id": "classroom_analytics", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Classroom analytics" + } + }, + { + "feature_id": "create_homework", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Create homework" + } + }, + { + "feature_id": "create_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited create lessons" + } + }, + { + "feature_id": "create_test", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited create tests" + } + }, + { + "feature_id": "energy", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited energies" + } + }, + { + "feature_id": "grader_daily_quota", + "included": 50, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "50 grader daily quotas" + } + }, + { + "feature_id": "publish_lessons", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Publish lessons" + } + }, + { + "feature_id": "read_flashcard", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read flashcards" + } + }, + { + "feature_id": "read_lesson", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read lessons" + } + }, + { + "feature_id": "read_note", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read notes" + } + }, + { + "feature_id": "read_walkthrough", + "included": 0, + "unlimited": true, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "Unlimited read walkthroughs" + } + }, + { + "feature_id": "school_student", + "included": 500, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "500 student seats" + } + }, + { + "feature_id": "teacher_coursework_grader", + "included": 500, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "500 teacher coursework graders" + } + }, + { + "feature_id": "school_teacher", + "included": 500, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "500 teacher seats" + } + } + ], + "created_at": 1777018263619, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + } + ], + "count": 55, + "next_cursor": null +} diff --git a/server/tests/integration/crud/plans/diffing/runable-plans.json b/server/tests/integration/crud/plans/diffing/runable-plans.json new file mode 100644 index 000000000..53ca28580 --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/runable-plans.json @@ -0,0 +1,3518 @@ +{ + "items": [ + { + "id": "add-on_credits", + "name": "Add-on Credits", + "description": null, + "group": null, + "version": 2, + "add_on": true, + "auto_enable": false, + "price": { + "amount": 10, + "interval": "one_off", + "display": { + "primary_text": "$10" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 10000, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "10,000 runable credits" + } + } + ], + "created_at": 1762650993066, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "add-on_credits-1", + "name": "Add-on Credits-1", + "description": null, + "group": null, + "version": 1, + "add_on": true, + "auto_enable": false, + "price": { + "amount": 30, + "interval": "one_off", + "display": { + "primary_text": "$30" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 30000, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "30,000 runable credits" + } + } + ], + "created_at": 1762650946543, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "add-on_credits-1_max", + "name": "Add-on Credits-1 Max", + "description": null, + "group": null, + "version": 1, + "add_on": true, + "auto_enable": false, + "price": { + "amount": 30, + "interval": "one_off", + "display": { + "primary_text": "$30" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 34500, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "34,500 runable credits" + } + } + ], + "created_at": 1762650946543, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "add-on_credits-2", + "name": "Add-on Credits-2", + "description": null, + "group": null, + "version": 1, + "add_on": true, + "auto_enable": false, + "price": { + "amount": 50, + "interval": "one_off", + "display": { + "primary_text": "$50" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 50000, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "50,000 runable credits" + } + } + ], + "created_at": 1762651011800, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "add-on_credits-2_max", + "name": "Add-on Credits-2 Max", + "description": null, + "group": null, + "version": 1, + "add_on": true, + "auto_enable": false, + "price": { + "amount": 50, + "interval": "one_off", + "display": { + "primary_text": "$50" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 57500, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "57,500 runable credits" + } + } + ], + "created_at": 1762651011800, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "add-on_credits_max", + "name": "Add-on Credits Max", + "description": null, + "group": null, + "version": 1, + "add_on": true, + "auto_enable": false, + "price": { + "amount": 10, + "interval": "one_off", + "display": { + "primary_text": "$10" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 11500, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "11,500 runable credits" + } + } + ], + "created_at": 1762650993066, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "referral_credit_pack", + "name": "Referral Credit Pack", + "description": null, + "group": null, + "version": 3, + "add_on": true, + "auto_enable": false, + "price": null, + "items": [ + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1763483233988, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_basic", + "name": "Runable Basic", + "description": null, + "group": null, + "version": 21, + "add_on": false, + "auto_enable": true, + "price": null, + "items": [ + { + "feature_id": "1_concurrent_task", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "1 Concurrent Task" + } + }, + { + "feature_id": "slides_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Slides Generation" + } + }, + { + "feature_id": "website_builder", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Webapp Builder" + } + }, + { + "feature_id": "limited_connectors", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Limited Connectors" + } + }, + { + "feature_id": "no_data_export", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "No Data Export" + } + }, + { + "feature_id": "runable_credits", + "included": 0, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "0 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 0, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "0 runable credits" + } + } + ], + "created_at": 1774641015395, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_go", + "name": "Runable Go", + "description": null, + "group": null, + "version": 2, + "add_on": false, + "auto_enable": false, + "price": null, + "items": [ + { + "feature_id": "slides_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Slides Generation" + } + }, + { + "feature_id": "website_builder", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Webapp Builder" + } + }, + { + "feature_id": "limited_connectors", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Limited Connectors" + } + }, + { + "feature_id": "no_data_export", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "No Data Export" + } + }, + { + "feature_id": "runable_credits", + "included": 0, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "0 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 0, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "0 runable credits" + } + } + ], + "created_at": 1767955606988, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_max_monthly", + "name": "Runable Max Monthly", + "description": null, + "group": null, + "version": 8, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 249, + "interval": "month", + "display": { + "primary_text": "$249", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "15_more_credits_on_add-on", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "15% more credits on add-on" + } + }, + { + "feature_id": "image_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Image Generation" + } + }, + { + "feature_id": "podcast_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Podcast Generation" + } + }, + { + "feature_id": "ai_report_generation_with_wide_research", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Report Generation with wide research" + } + }, + { + "feature_id": "ai_slides_generation_with_better_design", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Slides Generation with better design" + } + }, + { + "feature_id": "video_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Video Generation" + } + }, + { + "feature_id": "ai_webapp_builder_with_data_analytics", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Webapp Builder with Data Analytics" + } + }, + { + "feature_id": "connectors", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Connectors" + } + }, + { + "feature_id": "export_outside_runable", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Export Outside Runable" + } + }, + { + "feature_id": "multi-model_ai_chat", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Multi-Model AI Chat" + } + }, + { + "feature_id": "runable_credits", + "included": 249000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "249,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 5000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5,000 runable credits" + } + }, + { + "feature_id": "10_concurrent_tasks", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited Concurrent Tasks" + } + }, + { + "feature_id": "unlimited_context", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited Context" + } + } + ], + "created_at": 1767734700778, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_max_yearly", + "name": "Runable Max Yearly", + "description": null, + "group": null, + "version": 3, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 1200, + "interval": "year", + "display": { + "primary_text": "$1,200", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "15_more_credits_on_add-on", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "15% more credits on add-on" + } + }, + { + "feature_id": "image_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Image Generation" + } + }, + { + "feature_id": "podcast_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Podcast Generation" + } + }, + { + "feature_id": "ai_report_generation_with_wide_research", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Report Generation with wide research" + } + }, + { + "feature_id": "ai_slides_generation_with_better_design", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Slides Generation with better design" + } + }, + { + "feature_id": "video_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Video Generation" + } + }, + { + "feature_id": "ai_webapp_builder_with_data_analytics", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Webapp Builder with Data Analytics" + } + }, + { + "feature_id": "connectors", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Connectors" + } + }, + { + "feature_id": "export_outside_runable", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Export Outside Runable" + } + }, + { + "feature_id": "multi-model_ai_chat", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Multi-Model AI Chat" + } + }, + { + "feature_id": "runable_credits", + "included": 5000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "5,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 249000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "249,000 runable credits" + } + }, + { + "feature_id": "10_concurrent_tasks", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited Concurrent Tasks" + } + }, + { + "feature_id": "unlimited_context", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Unlimited Context" + } + } + ], + "created_at": 1767735407388, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_plus_monthly", + "name": "Runable Plus Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 9, + "interval": "month", + "display": { + "primary_text": "$9", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "2_concurrent_tasks", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "2 Concurrent Tasks" + } + }, + { + "feature_id": "image_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Image Generation" + } + }, + { + "feature_id": "podcast_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Podcast Generation" + } + }, + { + "feature_id": "advanced_report_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Report Generation" + } + }, + { + "feature_id": "slides_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Slides Generation" + } + }, + { + "feature_id": "video_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Video Generation" + } + }, + { + "feature_id": "website_builder", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Webapp Builder" + } + }, + { + "feature_id": "connectors", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Connectors" + } + }, + { + "feature_id": "export_outside_runable", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Export Outside Runable" + } + }, + { + "feature_id": "runable_credits", + "included": 500, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "500 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 9000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "9,000 runable credits" + } + } + ], + "created_at": 1767721337889, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_plus_yearly", + "name": "Runable Plus Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 108, + "interval": "year", + "display": { + "primary_text": "$108", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "2_concurrent_tasks", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "2 Concurrent Tasks" + } + }, + { + "feature_id": "image_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Image Generation" + } + }, + { + "feature_id": "podcast_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Podcast Generation" + } + }, + { + "feature_id": "advanced_report_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Report Generation" + } + }, + { + "feature_id": "slides_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Slides Generation" + } + }, + { + "feature_id": "video_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Video Generation" + } + }, + { + "feature_id": "website_builder", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Webapp Builder" + } + }, + { + "feature_id": "connectors", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Connectors" + } + }, + { + "feature_id": "export_outside_runable", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Export Outside Runable" + } + }, + { + "feature_id": "runable_credits", + "included": 500, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "500 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 9000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "9,000 runable credits" + } + } + ], + "created_at": 1767721708902, + "env": "live", + "archived": false, + "base_variant_id": "runable_plus_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_10000_monthly", + "name": "Runable Pro 10000 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 10000, + "interval": "month", + "display": { + "primary_text": "$10,000", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 10000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "10,000,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666021812, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_10000_yearly", + "name": "Runable Pro 10000 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 120000, + "interval": "year", + "display": { + "primary_text": "$120,000", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 10000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "10,000,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666022532, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_10000_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_1000_monthly", + "name": "Runable Pro 1000 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 1000, + "interval": "month", + "display": { + "primary_text": "$1,000", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 1000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "1,000,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666015571, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_1000_yearly", + "name": "Runable Pro 1000 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 12000, + "interval": "year", + "display": { + "primary_text": "$12,000", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 1000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "1,000,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666016318, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_1000_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_100_monthly", + "name": "Runable Pro 100 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 100, + "interval": "month", + "display": { + "primary_text": "$100", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 100000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "100,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666006252, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_100_yearly", + "name": "Runable Pro 100 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 1200, + "interval": "year", + "display": { + "primary_text": "$1,200", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 100000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "100,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666006994, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_100_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_1500_monthly", + "name": "Runable Pro 1500 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 1500, + "interval": "month", + "display": { + "primary_text": "$1,500", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 1500000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "1,500,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666017078, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_1500_yearly", + "name": "Runable Pro 1500 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 18000, + "interval": "year", + "display": { + "primary_text": "$18,000", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 1500000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "1,500,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666017818, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_1500_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_20000_monthly", + "name": "Runable Pro 20000 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 20000, + "interval": "month", + "display": { + "primary_text": "$20,000", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 20000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "20,000,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666023353, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_20000_yearly", + "name": "Runable Pro 20000 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 240000, + "interval": "year", + "display": { + "primary_text": "$240,000", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 20000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "20,000,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666024166, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_20000_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_2000_monthly", + "name": "Runable Pro 2000 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 2000, + "interval": "month", + "display": { + "primary_text": "$2,000", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 2000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "2,000,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666018641, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_2000_yearly", + "name": "Runable Pro 2000 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 24000, + "interval": "year", + "display": { + "primary_text": "$24,000", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 2000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "2,000,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666019365, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_2000_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_200_monthly", + "name": "Runable Pro 200 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 200, + "interval": "month", + "display": { + "primary_text": "$200", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 200000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "200,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666007768, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_200_yearly", + "name": "Runable Pro 200 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 2400, + "interval": "year", + "display": { + "primary_text": "$2,400", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 200000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "200,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666008603, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_200_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_25_monthly", + "name": "Runable Pro 25 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 25, + "interval": "month", + "display": { + "primary_text": "$25", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 500, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "500 runable credits" + } + } + ], + "created_at": 1772666001793, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_25_yearly", + "name": "Runable Pro 25 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 300, + "interval": "year", + "display": { + "primary_text": "$300", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "25,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 500, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "500 runable credits" + } + } + ], + "created_at": 1772666002567, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_25_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_300_monthly", + "name": "Runable Pro 300 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 300, + "interval": "month", + "display": { + "primary_text": "$300", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 300000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "300,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666009335, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_300_yearly", + "name": "Runable Pro 300 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 3600, + "interval": "year", + "display": { + "primary_text": "$3,600", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 300000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "300,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666010136, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_300_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_400_monthly", + "name": "Runable Pro 400 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 400, + "interval": "month", + "display": { + "primary_text": "$400", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 400000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "400,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666010964, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_400_yearly", + "name": "Runable Pro 400 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 4800, + "interval": "year", + "display": { + "primary_text": "$4,800", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 400000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "400,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666011698, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_400_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_5000_monthly", + "name": "Runable Pro 5000 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 5000, + "interval": "month", + "display": { + "primary_text": "$5,000", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 5000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "5,000,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666020174, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_5000_yearly", + "name": "Runable Pro 5000 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 60000, + "interval": "year", + "display": { + "primary_text": "$60,000", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 5000000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "5,000,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666020995, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_5000_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_500_monthly", + "name": "Runable Pro 500 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 500, + "interval": "month", + "display": { + "primary_text": "$500", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 500000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "500,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666012427, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_500_yearly", + "name": "Runable Pro 500 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 6000, + "interval": "year", + "display": { + "primary_text": "$6,000", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 500000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "500,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666013212, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_500_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_50_monthly", + "name": "Runable Pro 50 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 50, + "interval": "month", + "display": { + "primary_text": "$50", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 50000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "50,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666003303, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_50_yearly", + "name": "Runable Pro 50 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 600, + "interval": "year", + "display": { + "primary_text": "$600", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 50000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "50,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666004047, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_50_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_750_monthly", + "name": "Runable Pro 750 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 750, + "interval": "month", + "display": { + "primary_text": "$750", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 750000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "750,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666014035, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_750_yearly", + "name": "Runable Pro 750 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 9000, + "interval": "year", + "display": { + "primary_text": "$9,000", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 750000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "750,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666014759, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_750_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_75_monthly", + "name": "Runable Pro 75 Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 75, + "interval": "month", + "display": { + "primary_text": "$75", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 75000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "75,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666004781, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_75_yearly", + "name": "Runable Pro 75 Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 900, + "interval": "year", + "display": { + "primary_text": "$900", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 75000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "75,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + } + ], + "created_at": 1772666005523, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_75_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_monthly", + "name": "Runable Pro Monthly", + "description": null, + "group": null, + "version": 13, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 29, + "interval": "month", + "display": { + "primary_text": "$29", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "3_concurrent_tasks", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "3 Concurrent Tasks" + } + }, + { + "feature_id": "image_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Image Generation" + } + }, + { + "feature_id": "podcast_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Podcast Generation" + } + }, + { + "feature_id": "advanced_report_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Report Generation" + } + }, + { + "feature_id": "slides_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Slides Generation" + } + }, + { + "feature_id": "video_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Video Generation" + } + }, + { + "feature_id": "website_builder", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Webapp Builder" + } + }, + { + "feature_id": "connectors", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Connectors" + } + }, + { + "feature_id": "export_outside_runable", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Export Outside Runable" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 29000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "29,000 runable credits" + } + } + ], + "created_at": 1767734351586, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_pro_yearly", + "name": "Runable Pro Yearly", + "description": null, + "group": null, + "version": 8, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 216, + "interval": "year", + "display": { + "primary_text": "$216", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "3_concurrent_tasks", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "3 Concurrent Tasks" + } + }, + { + "feature_id": "image_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Image Generation" + } + }, + { + "feature_id": "podcast_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Podcast Generation" + } + }, + { + "feature_id": "advanced_report_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Report Generation" + } + }, + { + "feature_id": "slides_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Slides Generation" + } + }, + { + "feature_id": "video_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Video Generation" + } + }, + { + "feature_id": "website_builder", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Webapp Builder" + } + }, + { + "feature_id": "connectors", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Connectors" + } + }, + { + "feature_id": "export_outside_runable", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Export Outside Runable" + } + }, + { + "feature_id": "runable_credits", + "included": 1000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 29000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "29,000 runable credits" + } + } + ], + "created_at": 1767735180143, + "env": "live", + "archived": false, + "base_variant_id": "runable_pro_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_starter_monthly", + "name": "Runable Starter Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 10, + "interval": "month", + "display": { + "primary_text": "$10", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "1_concurrent_task", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "1 Concurrent Task" + } + }, + { + "feature_id": "slides_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Slides Generation" + } + }, + { + "feature_id": "website_builder", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Webapp Builder" + } + }, + { + "feature_id": "limited_connectors", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Limited Connectors" + } + }, + { + "feature_id": "no_data_export", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "No Data Export" + } + }, + { + "feature_id": "runable_credits", + "included": 1, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1 runable credit" + } + }, + { + "feature_id": "runable_credits", + "included": 10000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "10,000 runable credits" + } + } + ], + "created_at": 1762594036620, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_starter_yearly", + "name": "Runable Starter Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 120, + "interval": "year", + "display": { + "primary_text": "$120", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "1_concurrent_task", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "1 Concurrent Task" + } + }, + { + "feature_id": "slides_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Slides Generation" + } + }, + { + "feature_id": "website_builder", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Webapp Builder" + } + }, + { + "feature_id": "limited_connectors", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Limited Connectors" + } + }, + { + "feature_id": "no_data_export", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "No Data Export" + } + }, + { + "feature_id": "runable_credits", + "included": 1, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "1 runable credit" + } + }, + { + "feature_id": "runable_credits", + "included": 10000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "10,000 runable credits" + } + } + ], + "created_at": 1762594036620, + "env": "live", + "archived": false, + "base_variant_id": "runable_starter_monthly", + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_topup_100", + "name": "Runable Topup 100", + "description": null, + "group": null, + "version": 2, + "add_on": true, + "auto_enable": false, + "price": { + "amount": 100, + "interval": "one_off", + "display": { + "primary_text": "$100" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 130000, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "130,000 runable credits" + } + } + ], + "created_at": 1776204727618, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_topup_15", + "name": "Runable Topup 15", + "description": null, + "group": null, + "version": 1, + "add_on": true, + "auto_enable": false, + "price": { + "amount": 15, + "interval": "one_off", + "display": { + "primary_text": "$15" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 12000, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "12,000 runable credits" + } + } + ], + "created_at": 1776204724848, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_topup_25", + "name": "Runable Topup 25", + "description": null, + "group": null, + "version": 1, + "add_on": true, + "auto_enable": false, + "price": { + "amount": 25, + "interval": "one_off", + "display": { + "primary_text": "$25" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 25000, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "25,000 runable credits" + } + } + ], + "created_at": 1775590211705, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_topup_50", + "name": "Runable Topup 50", + "description": null, + "group": null, + "version": 2, + "add_on": true, + "auto_enable": false, + "price": { + "amount": 50, + "interval": "one_off", + "display": { + "primary_text": "$50" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 60000, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "60,000 runable credits" + } + } + ], + "created_at": 1776204726608, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_topup_75", + "name": "Runable Topup 75", + "description": null, + "group": null, + "version": 1, + "add_on": true, + "auto_enable": false, + "price": { + "amount": 75, + "interval": "one_off", + "display": { + "primary_text": "$75" + } + }, + "items": [ + { + "feature_id": "runable_credits", + "included": 75000, + "unlimited": false, + "reset": { + "interval": "one_off" + }, + "price": null, + "display": { + "primary_text": "75,000 runable credits" + } + } + ], + "created_at": 1775590213327, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_unlimited_monthly", + "name": "Runable Unlimited Monthly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 49, + "interval": "month", + "display": { + "primary_text": "$49", + "secondary_text": "per month" + } + }, + "items": [ + { + "feature_id": "5_concurrent_tasks", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "5 Concurrent Tasks" + } + }, + { + "feature_id": "image_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Image Generation" + } + }, + { + "feature_id": "podcast_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Podcast Generation" + } + }, + { + "feature_id": "advanced_report_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Report Generation" + } + }, + { + "feature_id": "slides_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Slides Generation" + } + }, + { + "feature_id": "video_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Video Generation" + } + }, + { + "feature_id": "website_builder", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Webapp Builder" + } + }, + { + "feature_id": "connectors", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Connectors" + } + }, + { + "feature_id": "export_outside_runable", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Export Outside Runable" + } + }, + { + "feature_id": "multi-model_ai_chat", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Multi-Model AI Chat" + } + }, + { + "feature_id": "runable_credits", + "included": 2000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "2,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 49000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "49,000 runable credits" + } + } + ], + "created_at": 1767721337889, + "env": "live", + "archived": false, + "base_variant_id": null, + "config": { + "ignore_past_due": false + } + }, + { + "id": "runable_unlimited_yearly", + "name": "Runable Unlimited Yearly", + "description": null, + "group": null, + "version": 1, + "add_on": false, + "auto_enable": false, + "price": { + "amount": 300, + "interval": "year", + "display": { + "primary_text": "$300", + "secondary_text": "per year" + } + }, + "items": [ + { + "feature_id": "5_concurrent_tasks", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "5 Concurrent Tasks" + } + }, + { + "feature_id": "image_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Image Generation" + } + }, + { + "feature_id": "podcast_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Podcast Generation" + } + }, + { + "feature_id": "advanced_report_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Report Generation" + } + }, + { + "feature_id": "slides_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Slides Generation" + } + }, + { + "feature_id": "video_generation", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Video Generation" + } + }, + { + "feature_id": "website_builder", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "AI Webapp Builder" + } + }, + { + "feature_id": "connectors", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Connectors" + } + }, + { + "feature_id": "export_outside_runable", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Export Outside Runable" + } + }, + { + "feature_id": "multi-model_ai_chat", + "included": 0, + "unlimited": false, + "reset": null, + "price": null, + "display": { + "primary_text": "Multi-Model AI Chat" + } + }, + { + "feature_id": "runable_credits", + "included": 2000, + "unlimited": false, + "reset": { + "interval": "day" + }, + "price": null, + "display": { + "primary_text": "2,000 runable credits" + } + }, + { + "feature_id": "runable_credits", + "included": 49000, + "unlimited": false, + "reset": { + "interval": "month" + }, + "price": null, + "display": { + "primary_text": "49,000 runable credits" + } + } + ], + "created_at": 1767721708902, + "env": "live", + "archived": false, + "base_variant_id": "runable_unlimited_monthly", + "config": { + "ignore_past_due": false + } + } + ] +} diff --git a/server/tests/integration/crud/plans/diffing/utils/findById.ts b/server/tests/integration/crud/plans/diffing/utils/findById.ts new file mode 100644 index 000000000..fef6a21c2 --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/utils/findById.ts @@ -0,0 +1,5 @@ +export const findById = (items: T[], id: string): T => { + const item = items.find((p) => p.id === id); + if (!item) throw new Error(`Item not found: ${id}`); + return item; +}; diff --git a/server/tests/integration/crud/plans/diffing/utils/normalizePlan.ts b/server/tests/integration/crud/plans/diffing/utils/normalizePlan.ts new file mode 100644 index 000000000..d606327bf --- /dev/null +++ b/server/tests/integration/crud/plans/diffing/utils/normalizePlan.ts @@ -0,0 +1,72 @@ +import type { ApiPlanV1 } from "@autumn/shared"; +import type { ApplyDiffOutput } from "@autumn/shared/utils/planV1Utils/diff/applyDiff.js"; + +export const ITEM_FIELDS = [ + "feature_id", + "included", + "unlimited", + "reset", + "price", + "rollover", +] as const; + +export type ApiPlanItem = ApiPlanV1["items"][number]; + +export type NormalizablePlan = { + price: ApiPlanV1["price"]; + items: ApiPlanV1["items"]; + free_trial?: ApiPlanV1["free_trial"]; +}; + +export const normalizeRollover = (rollover: ApiPlanItem["rollover"]) => { + if (rollover === null || rollover === undefined) return undefined; + const out: Record = { + expiry_duration_type: rollover.expiry_duration_type, + }; + if (rollover.max != null) out.max = rollover.max; + if (rollover.max_percentage != null) + out.max_percentage = rollover.max_percentage; + if (rollover.expiry_duration_length !== undefined) + out.expiry_duration_length = rollover.expiry_duration_length; + return out; +}; + +export const normalizeItem = (item: ApiPlanItem) => { + const out: Record = {}; + for (const k of ITEM_FIELDS) { + if (k === "rollover") { + const val = item.rollover; + if (val !== undefined && val !== null) out[k] = normalizeRollover(val); + } else { + const val = item[k]; + // Diff omits nullish fields in create params; treat null == absent. + if (val !== undefined && val !== null) out[k] = val; + } + } + return out; +}; + +export const normalizePrice = (price: ApiPlanV1["price"]) => { + if (price === null || price === undefined) return null; + const { display: _d, ...rest } = price; + return rest; +}; + +export const normalizeFreeTrial = (ft: ApiPlanV1["free_trial"]) => { + if (ft === null || ft === undefined) return null; + const out = { ...ft }; + if (out.on_end === null || out.on_end === undefined) delete out.on_end; + return out; +}; + +export const normalizePlan = (plan: NormalizablePlan | ApplyDiffOutput) => ({ + price: normalizePrice(plan.price), + items: [...plan.items] + .sort((a, b) => { + const byFeature = a.feature_id.localeCompare(b.feature_id); + if (byFeature !== 0) return byFeature; + return (a.included ?? 0) - (b.included ?? 0); + }) + .map(normalizeItem), + free_trial: normalizeFreeTrial(plan.free_trial), +});