Skip to content

2.4.0

Released: TBD

Highlights

  • Per-tenant plan limits, editable from the admin panel. When creating or editing a tenant, admins can now set each plan limit — per-resource creation caps (clients, suppliers, items, users) and the monthly PAC folio allowance — seeded from the plan default and individually overridable. The PAC folio allowance is now plan-tiered (FREE 0 · BASIC 50 · STARTER 100 · PROFESSIONAL 250 · ENTERPRISE 500) instead of a single flat default. See Per-Tenant Plan Limits.

Added

  • planQuotaDefaults admin query. Returns every plan's per-resource creation defaults (null = unlimited) and folio allowance, sourced from the same quota_for / folio_allowance_for functions enforcement uses — the admin panel pre-fills the tenant form from this.
  • quotaOverrides + monthlyFolioAllowance on createTenant / updateTenant. Write per-resource creation caps and the monthly folio override at provisioning time or later. Tenant.quotaOverrides is now exposed on the tenant type.
  • ResourceType GraphQL enum (CLIENT, SUPPLIER, ITEM, USER) and the ResourceQuota / ResourceQuotaInput / ResourceQuotaDefault / PlanQuotaDefaults types on the admin schema.
  • Plan-tiered PAC folio defaults (PLAN_FOLIO_ALLOWANCES in plan_quotas.py).

Changed

  • PAC folio allowance falls back to the plan default, not a flat 20. PacMetricsService._effective_allowance and seed_month now resolve a tenant's monthly allowance as monthly_folio_allowance override → plan default (folio_allowance_for). The per-tenant override still wins when set.
  • updateTenant(quotaOverrides=...) publishes a cache invalidation so workers reload the cached TenantPG and enforce the new quota on the next request.

Fixed

  • None.

Migrations

  • None. Both quota_overrides and monthly_folio_allowance columns already existed; this release only wires the write path and the plan-tiered folio default.

Frontend impact

  • The admin panel (cifras-admin) gained a "Resource Limits" section in the tenant create and edit dialogs: one input per resource plus a PAC-folios input, seeded from planQuotaDefaults for the selected plan and re-seeded on plan change; blank = follow the plan default. Read Tenant.quotaOverrides { resource limit } + Tenant.monthlyFolioAllowance to display current limits, and send quotaOverrides / monthlyFolioAllowance on create/update ([] clears resource overrides; omit to leave unchanged).
  • ⚠️ Behavior change: tenants with a null monthly_folio_allowance previously got 20 included folios/month; they now get their plan allowance (FREE 0 … ENTERPRISE 500). Set an explicit monthlyFolioAllowance for any tenant that needs a different number.

Versioning notes

  • Bumped with uv run python scripts/bump_version.py 2.4.0 --changelog-stub. MINOR — additive admin GraphQL (new query, new optional mutation args, new types) with no breaking schema change. The folio-default behavior change is intentional and configurable per tenant.