Skip to content

Тарифы и квоты

Planner использует двухуровневую систему тарифов с раздельными квотами для пользователей и организаций.

Модель

Plan
├── name, description
├── price (месяц)
├── maxOrgs, maxStandaloneTeams
├── maxTeamsPerOrg, maxProjectsPerOrg
├── maxProjectsPerTeam, maxMembersPerTeam
├── storagePerOrg, storagePerTeam (в байтах)
├── public (false — скрыть от не-админов, для Enterprise)
└── features (JSON-список возможностей)

Два уровня тарифов

УровеньПривязкаКонтролирует
User.planIdПользовательКоличество организаций + самостоятельные команды
Organization.planIdОрганизацияКоманды, проекты, хранилище в рамках организации

Grace period при понижении

При переходе на тариф с меньшими лимитами действует 30-дневный льготный период:

  • previousPlanId + planChangedAt сохраняются на User/Organization
  • QuotaService.getEffectiveLimitsForUser/Org() возвращает MAX лимитов старого и нового тарифа
  • Через 30 дней применяются строгие лимиты нового тарифа
  • gracePeriodDaysLeft возвращается в QuotaInfo
  • Апгрейд применяется мгновенно (очищает previousPlanId)

API Endpoints

МетодПутьОписание
GET/api/plansСписок доступных тарифов
GET/api/users/me/quotaИнформация о квоте пользователя
PATCH/api/users/me/planСменить тариф пользователя
GET/api/organizations/by-slug/:slug/quotaКвота организации
PATCH/api/organizations/by-slug/:slug/planСменить тариф организации
GET/api/teams/by-slug/:teamSlug/quotaКвота команды

Проверка квот

Квоты проверяются перед созданием ресурсов:

  • checkCanCreateOrganization() — лимит организаций пользователя
  • checkCanCreateTeam() — лимит команд в организации
  • checkCanCreateProject() — лимит проектов
  • checkStorageQuota() — лимит хранилища

Фронтенд

Store тарифов

typescript
const store = usePlansStore()
const { plans, currentPlan, userQuota } = storeToRefs(store)

await store.fetchPlans()
await store.fetchUserQuota()
await store.selectPlan(planId)

Компоненты

  • PlanSelectionView.vue (/settings/plan) — страница выбора тарифа
  • PlanTable.vue — таблица сравнения тарифов
  • Grace period banner — предупреждение о льготном периоде при понижении

Ключевые детали реализации

  • Enterprise тариф скрыт от обычных пользователей (public: false)
  • Администраторы видят все тарифы через GET /admin/plans
  • Хранилище пересчитывается ежедневно в 3:00 (cron) из таблицы файлов
  • QuotasProcessor (Bull queue) — фоновый cron для истечения grace period