V8 Central — Product & Technical Spec
  1. Docs
  2. Core platform
  3. Plans

#Plans

A plan is what can be bought. It is not a pricing card. It's the definition behind a relationship:

#What V7 sells (reference only, do not hard-code)

These values show the shape the V8 API must return. They are V7 code constants, not V8 decisions.

ConceptV7 values
TiersFree, Newbie, Pro, Master, Business (+ Legacy). Restructured new users only see Newbie (shown as "Managed") and Business (shown as "Self Managed")
CyclesMonthly, Yearly (charged as 10 months), Lifetime
Plan typesserver_based (old: one subscription per server), subscription_based (current: one account subscription), Lifetime
Limitsallowed_servers, allowed_applications per plan (e.g. Free 0 servers / 1 app, others 200 apps)
FeaturesPermission rows enabled per tier (<tier>_default = 1)
Trialtrial_mode + trial_days from settings. Newbie/Free need no payment
DiscountsRecurring and lifetime discounts per tier (env config), promo codes, discount-percentage endpoint
Rate limitsAPI rate limit per tier (free 60 … business 180 req/min)

#What the plans screen needs from the API

DataWhyStatus
Plan catalog: id, name, display name, description, cycles + price per cycle, currency, limits, feature list, trial availability, is-current, can-selectRender plans without hard-codingMissing
Current subscription: plan, cycle, status, renews/expires at, cancel-at-period-endCurrent-plan cardMissing
Usage: servers used / allowed, applications used / allowedUsage bars, limit warningsMissing (V7 new-subscription-plan returns serverCount, applicationCount)
Upgrade quote: amount now, credit applied, tax, promo, next renewalCheckout summaryMissing (V7 remaining-credit)
Eligibility: which plans this account may choose (e.g. restructured tiers)Disable or hide optionsMissing

#Plan screens

  • Plans (/[locale]/plans): cycle toggle (only cycles the API offers), plan cards built only from API data, the current plan marked, upgrade/downgrade buttons enabled by the API's can_select, feature comparison table.
  • Current plan card (dashboard + subscription page): name, cycle, status badge, renewal date, usage bars, "Upgrade" call to action when usage ≥ 80% or a limit is hit.
  • Enterprise / contact: V7 has enterprise-contact-request. Optional. Open question

#Upgrade, downgrade, renewal, cancellation, expiration

ActionV7 behaviourV8
UpgradePATCH change-subscription with plan + cycle. Requires enough credits (shortfall > $1 → "Your credit is not enough"). Charges the differenceMissing
DowngradeSame endpoint. Validity recalculated from remaining credit (remainingPlanCredit). Can't go below current usage AssumptionMissing Open question
RenewalPATCH renew-subscription, paid from credits. If expired 16+ days, the new period starts today. Otherwise the remaining days are addedMissing
CancelPATCH cancel-subscription sets a cancel flag (subscription_plan_cancel). Lifetime can't be cancelled. resume-subscription undoes itMissing
ExpirationDaily job decreases expires_in_days. Reminders when < 8 days left. Expired (< 0) → server actions blocked except server deleteMissing
Free plan0 servers / 1 application in the new standard table. A free-forever single server exists for some old usersOpen question
LifetimeSeparate controller: create, upgrade, advanced lifetimeOpen question keep for V8?

#Usage limits

  • The backend counts and decides. The frontend only shows the numbers and disables buttons as a hint.
  • Applications live on OSS panels, so counting applications needs a call to every server (or a cached count). This is a real cost. Decision D-6: do application limits still apply in V8?

#Rules for the frontend

  • Never hard-code prices, limits, features, cycles or currency. Every number comes from the API.
  • Format money with next-intl useFormatter().number(value, {style:'currency', currency}) using the API's currency.
  • Show plan names from the API (display_name) to avoid the V7 rename confusion (Newbie → "Managed").
ServerAvatar V8 Central · prepared by central-app-2 (Pair 2 frontend) for Bhavik Jethwa · nothing in this spec is implemented yet · Built 2026-10-03 12:35 UTC