Plan & Subscription Management
Plan management in COS determines which features and limits are available to organizations. Plans are defined at the TenantGroup (holding) level; all tenants under a TenantGroup share the same plan limits.
Core Concepts
Plan Hierarchy
PlanTemplate (Template)
└─ PlanFeature (Plan Features — enabled/limit/tier per feature)
└─ PlanFeatureOverride (Group-Level Exception)
└─ FeatureDefinition (Platform-Wide Feature Definition)
Terminology
| Term | Description |
|---|---|
| PlanTemplate | Plan template (Free, Business, Enterprise, etc.) |
| FeatureDefinition | Platform-wide feature definition (e.g., max_users, swot_analysis) |
| PlanFeature | A plan's values for a specific feature (enabled/disabled, limit, tier) |
| PlanFeatureOverride | Exception overriding plan values for a specific TenantGroup |
| TenantGroup | Holding/group structure containing one or more tenants |
Default Plans
COS comes with 3 default plans:
Free
Basic plan for small teams.
- Users: 3
- Tenants: 1
- OKR: 5 objectives, 15 key results, 10 initiatives
- KPIs: 10
- Strategy modules: Disabled (SWOT, BSC, Themes, etc.)
- RBAC: BASIC (Admin + Member)
- Dashboard: BASIC
- KPI Library: BASIC
Business
Advanced plan for mid-size companies.
- Users: 50
- Tenants: 3
- OKR: Unlimited
- KPIs: Unlimited
- Strategy modules: Enabled (except EA and VRIO)
- PESTLE Analysis: Enabled
- Unit-Level Strategy: Disabled (TL cannot create/edit/delete)
- RBAC: FULL (4 roles: ADMIN/SM/TL/MEMBER)
- Dashboard: STANDARD
- KPI Library: FULL
- Additional: API access, audit log, gap management, performance reports
Enterprise
Full-featured plan for large organizations and holding companies.
- Users: Unlimited
- Tenants: Unlimited
- OKR: Unlimited
- KPIs: Unlimited
- Strategy modules: All enabled (EA, VRIO, Maturity Assessment, PESTLE included)
- Unit-Level Strategy: Enabled (TL can create analyses for their own unit)
- RBAC: FULL
- Dashboard: FULL
- Additional: SSO, white-label, cross-tenant view, priority support, full integration
Feature Categories
Platform features are organized into 7 categories:
Users & Organization (USERS_ORG)
| Feature | Description | Value Type |
|---|---|---|
| max_users | Maximum number of users | Numeric |
| max_tenants | Maximum number of tenants | Numeric |
| max_org_depth | Organization hierarchy depth | Numeric |
| org_versioning | Organization versioning | Boolean |
Strategy (STRATEGY)
Divided into subcategories: general, swot, pestle, porter, bcg, bsc, asis, resource, dma, excellence, findings.
| Feature | Subcategory | Description | Value Type |
|---|---|---|---|
| max_strategic_cycles | general | Maximum strategic cycles | Numeric |
| max_okr_cycles | general | Maximum OKR cycles | Numeric |
| strategic_themes | general | Strategic Themes | Boolean |
| max_strategic_themes | general | Max strategic theme count | Numeric |
| strategy_roadmap | general | Strategy Roadmap | Boolean |
| unit_level_strategy | general | Unit-Level Strategy | Boolean |
| ea_module | general | Enterprise Architecture (EA) | Boolean |
| maturity_assessment | general | Maturity Assessment | Boolean |
| swot_analysis | swot | SWOT Analysis | Boolean |
| max_swot_per_unit | swot | Max SWOT per unit | Numeric |
| pestle_analysis | pestle | PESTLE Analysis | Boolean |
| max_pestle_per_unit | pestle | Max PESTLE per unit | Numeric |
| porter_analysis | porter | Porter Five Forces Analysis | Boolean |
| max_porter_per_unit | porter | Max Porter per unit | Numeric |
| bcg_matrix | bcg | BCG Growth-Share Matrix | Boolean |
| max_bcg_per_unit | bcg | Max BCG per unit | Numeric |
| bsc_module | bsc | Balanced Scorecard | Boolean |
| max_bsc_per_unit | bsc | Max BSC per unit | Numeric |
| current_state_analysis | asis | Current State Analysis | Boolean |
| max_asis_per_unit | asis | Max As-Is per unit | Numeric |
| resource_inventory_vrio | resource | Resource Inventory & VRIO | Boolean |
| max_resource_per_unit | resource | Max resource analysis per unit | Numeric |
| digital_maturity_assessment_core | dma | DMA Core (60 questions) | Boolean |
| digital_maturity_assessment_extended | dma | DMA Extended (150 questions) | Boolean |
| digital_maturity_assessment_multi_rater | dma | DMA Multi-Rater | Boolean |
| max_digital_maturity_per_unit | dma | Max DMA per unit | Numeric |
| max_digital_maturity_raters_per_assessment | dma | Max raters per assessment | Numeric |
| max_digital_maturity_raters_per_question | dma | Max raters per question | Numeric |
| excellence_assessment_core | excellence | Excellence Assessment (Core) | Boolean |
| excellence_assessment_advanced | excellence | Excellence Assessment (Advanced) | Boolean |
| excellence_assessment_multi_rater | excellence | Excellence Multi-Rater | Boolean |
| max_excellence_assessment_per_unit | excellence | Max excellence per unit | Numeric |
| max_excellence_raters_per_assessment | excellence | Max raters per assessment | Numeric |
| max_excellence_raters_per_question | excellence | Max raters per question | Numeric |
| findings_module | findings | Findings Module | Boolean |
OKR
| Feature | Description | Value Type |
|---|---|---|
| max_objectives | Maximum objectives | Numeric |
| max_key_results | Maximum key results | Numeric |
| max_initiatives | Maximum initiatives | Numeric |
| okr_hierarchy | OKR hierarchy | Boolean |
| okr_approval_workflow | Approval workflow | Boolean |
| okr_confidentiality | Confidentiality control | Boolean |
| okr_multi_alignment | Multi-alignment | Boolean |
| okr_snapshots | Snapshots | Boolean |
KPI & Reporting (KPI_REPORT)
| Feature | Description | Value Type |
|---|---|---|
| max_kpis | Maximum KPI count | Numeric |
| kpi_library_tier | KPI Library tier | Tier (BASIC/FULL) |
| dashboards_tier | Dashboard access | Boolean |
| reports_tier | Reporting access | Boolean |
| gap_management | Gap management | Boolean |
| performance_reports | Performance reports | Boolean |
Product Management (PRODUCT)
Divided into subcategories: general, product_swot, product_scorecard, product_kpi.
| Feature | Subcategory | Description | Value Type |
|---|---|---|---|
| max_products | general | Maximum product count | Numeric |
| product_ownership | general | Product ownership assignment | Boolean |
| product_swot | product_swot | Product SWOT Analysis | Boolean |
| product_scorecard | product_scorecard | Product Scorecard | Boolean |
| max_product_scorecard_kpis | product_scorecard | Max product scorecard KPIs | Numeric |
| product_kpi_library | product_kpi | Product KPI Library | Boolean |
Administration & Security (ADMIN_SECURITY)
| Feature | Description | Value Type |
|---|---|---|
| rbac_tier | RBAC management | Boolean |
| cross_tenant_view | Cross-tenant view | Boolean |
| white_label | White-label branding | Boolean |
| sso | Single Sign-On (SSO) | Boolean |
| api_access | API access | Boolean |
| integrations_tier | Integration access | Boolean |
| kpi_api_integration | KPI API Integration | Boolean |
| max_api_integrations | Max API integration count | Numeric |
| min_cron_interval_minutes | Min cron interval (minutes) | Numeric |
| notification_tier | Notification tier | Tier (BASIC/FULL) |
| audit_log | Audit log | Boolean |
| priority_support | Priority support | Boolean |
Artificial Intelligence (AI)
| Feature | Description | Value Type |
|---|---|---|
| ai_assistant | AI Assistant | Boolean |
| ai_daily_messages | Daily AI message limit | Numeric |
| ai_max_conversations | Max active conversations | Numeric |
| ai_history_retention_days | Chat retention period (days) | Numeric |
| ai_web_research | Web research | Boolean |
| ai_daily_web_searches | Daily web search limit | Numeric |
| ai_data_generation | Sample data generation | Boolean |
| ai_rate_limit_per_minute | AI requests per minute limit | Numeric |
Plan Management (SuperAdmin)
Plan management is available exclusively to SUPER_ADMIN users.
Creating a Plan
- Navigate to the Plans page
- Click the New Plan button
- Fill in plan details:
- Code: Unique identifier (e.g.,
premium) - Name: Display name
- Description: Plan description
- Max Tenants: Maximum tenants allowed under this plan (0 = unlimited)
- Sort Order: Display order in lists
- Code: Unique identifier (e.g.,
- Set values for each feature (enabled/disabled, limit, tier)
- Click Save
Editing a Plan
- Feature values of an existing plan can be modified
- Plan code can be changed (must remain unique)
- Active/inactive status can be toggled
Plan Assignment
- Identify the TenantGroup you want to assign the plan to
- Use the
POST /plans/:planId/assignendpoint to assign the plan - Changes take effect immediately for all tenants in the group
Group Override (Exception)
Use overrides when you need different values than the plan for a specific TenantGroup:
- Navigate to the override page of the target group
- Select the feature you want to override
- Enter the new value
- Optionally add a reason
- Click Save
Note: Overrides only affect the specified feature. Features without overrides continue to use plan values.
Value Resolution Order
A feature's effective value is determined in this order (when an active subscription exists):
- PlanFeatureOverride — If a group-level override exists, this value is used
- PlanFeature — If no override, the plan's value is used
- FeatureDefinition — If not defined in the plan, the platform default is used
Important: Overrides are only active when the group has an active subscription. When the subscription expires or is cancelled, overrides are deactivated and Free plan values apply.
Subscription Management
The subscription system provides time-based access to plans. A TenantGroup must have an active subscription to access a paid plan.
Subscription Model
TenantGroup
└─ Subscription (1 active, N historical)
├─ PlanTemplate → subscribed plan
├─ BillingPeriod → MONTHLY / YEARLY
├─ startDate, endDate → subscription period
├─ gracePeriodDays → extra time after expiry (default: 7 days)
├─ autoRenew → auto-renewal flag
└─ status → ACTIVE / CANCELLED / EXPIRED
Subscription Statuses
| Status | Description |
|---|---|
| ACTIVE | Subscription is active, plan features and overrides are effective |
| CANCELLED | Cancelled by admin, group falls back to Free plan |
| EXPIRED | Period + grace period ended, automatically downgraded to Free |
Grace Period
When a subscription's end date passes, a 7-day grace period begins. During this time:
- Plan features remain active
- Overrides remain effective
- A warning banner is displayed in the UI
After the grace period:
- Subscription status changes to
EXPIRED - Group plan is downgraded to Free
- Overrides are deactivated
Business Rules
- Only 1 active subscription per group at a time
- Cannot create subscription for Free plan — Free is the default fallback
- Plan change: Cancel current subscription → create a new one
- Cancellation: Group immediately falls back to Free plan
- Deletion: Only CANCELLED or EXPIRED subscriptions can be soft-deleted
- autoRenew: Currently stored as a flag only; automated renewal is not yet active
UI Expiry Banner
A warning banner is shown to all users when the subscription is about to expire:
| Days Remaining | Banner Type | Message |
|---|---|---|
| ≤ 30 days | Info (blue) | "Your subscription expires in X days" |
| ≤ 7 days | Warning (orange) | "Your subscription expires in X days" |
| ≤ 1 day | Critical (red) | "Your subscription expires tomorrow!" |
| Grace period | Error (red) | "Your subscription has expired. Grace period: X days" |
Subscription API Endpoints
| Endpoint | Method | Description | Access |
|---|---|---|---|
/subscriptions | GET | List all subscriptions | SUPER_ADMIN |
/subscriptions/:id | GET | Subscription detail | SUPER_ADMIN |
/subscriptions | POST | Create new subscription | SUPER_ADMIN |
/subscriptions/:id | PATCH | Update (endDate/autoRenew/notes) | SUPER_ADMIN |
/subscriptions/:id/cancel | POST | Cancel subscription | SUPER_ADMIN |
/subscriptions/:id | DELETE | Soft delete subscription | SUPER_ADMIN |
/subscriptions/my-status | GET | Own group subscription status | All Roles |
Numeric Limit Rules
0= Unlimited (no limit on users, tenants, objectives, etc.)- Positive number = Allowed up to specified amount
enabled: falsemeans the limit value is ignored (feature is disabled)
Permission Matrix
| Operation | SUPER_ADMIN | GROUP_ADMIN | ADMIN | Others |
|---|---|---|---|---|
| List plans | ✅ | ❌ | ❌ | ❌ |
| Create plan | ✅ | ❌ | ❌ | ❌ |
| Edit plan | ✅ | ❌ | ❌ | ❌ |
| Delete plan | ✅ | ❌ | ❌ | ❌ |
| Assign plan | ✅ | ❌ | ❌ | ❌ |
| Feature definition CRUD | ✅ | ❌ | ❌ | ❌ |
| Define overrides | ✅ | ❌ | ❌ | ❌ |
| View effective plan | ✅ | ✅* | ❌ | ❌ |
* GROUP_ADMIN: Can only view the effective plan of their own group.
API Endpoints
| Endpoint | Method | Description | Access |
|---|---|---|---|
/plans | GET | List all plans | SUPER_ADMIN |
/plans | POST | Create a new plan | SUPER_ADMIN |
/plans/:planId | GET | Plan details | SUPER_ADMIN |
/plans/:planId | PATCH | Update a plan | SUPER_ADMIN |
/plans/:planId | DELETE | Delete a plan | SUPER_ADMIN |
/plans/:planId/assign | POST | Assign plan to TenantGroup | SUPER_ADMIN |
/plans/features | GET | List feature definitions | SUPER_ADMIN |
/plans/features | POST | Create feature definition | SUPER_ADMIN |
/plans/features/:featureKey | PATCH | Update feature definition | SUPER_ADMIN |
/plans/effective/:groupId | GET | Effective plan (with overrides) | SUPER_ADMIN, GROUP_ADMIN* |
/plans/my-groups | GET | My groups' plans | SUPER_ADMIN, GROUP_ADMIN* |
/plans/overrides/:groupId | GET | Group overrides | SUPER_ADMIN |
/plans/overrides/:groupId | PUT | Set/update overrides | SUPER_ADMIN |
* GROUP_ADMIN: Can only view their own group's plan.
Plan Enforcement (Limit Control)
Plan limits are automatically enforced at the backend. When a limit is exceeded, the operation is rejected with a 422 (Unprocessable Entity) error.
Enforcement Points
| Entity Creation | Feature Key | Scope |
|---|---|---|
| Add tenant | maxTenants (PlanTemplate) | Group-wide |
| Add user | max_users | Group-wide (all tenants combined) |
| Add objective | max_objectives | Per tenant |
| Add key result | max_key_results | Per tenant |
| Add initiative | max_initiatives | Per tenant |
Behavior Rules
- 0 = Unlimited: When the limit value is 0, no check is performed
- Existing data preserved: When a limit is exceeded, existing data is not deleted; only new additions are blocked
- Error message:
"[Entity] limit reached (current/limit). Plan upgrade required." - Logging: Every rejected operation is logged with
logger.warn
PlanFeature Guard (Boolean Feature Gate)
Boolean features (e.g., swot_analysis, bsc_module) can be controlled at the route level using the @PlanFeature decorator:
@UseGuards(PlanFeatureGuard)
@PlanFeature('swot_analysis')
@Get('swot')
getSwot() { ... }
Access to disabled features is rejected with a 422 error.
GROUP_ADMIN Plan Visibility
GROUP_ADMIN users can view their group's plan from the Platform → Plan Details page in the sidebar. This page is read-only:
- Plan name and features are displayed
- Each feature's value and source (Plan/Override/Default) is shown
- Limits and active features are grouped by category
- GROUP_ADMIN cannot modify plans or define overrides
FAQ
Q: Can I change a individual tenant's plan? A: No. Plans are defined at the TenantGroup level, not the tenant level. To change a tenant's plan, change its group's plan.
Q: Can I override the entire plan with overrides? A: Overrides are defined per feature. If you want to change all values, create a new plan and assign it to the group.
Q: What happens to groups when a plan is deleted? A: A plan cannot be deleted if TenantGroups are assigned to it. Move all groups to another plan first.
Q: What happens when a Free plan user exceeds limits? A: New creation operations are blocked. Existing data is preserved, but new records cannot be created until usage is within limits.
Q: What happens when a subscription expires? A: A 7-day grace period begins. During this time the plan remains active. After the grace period, the group is automatically downgraded to the Free plan.
Q: Is existing data deleted when a subscription is cancelled? A: No. The group falls back to the Free plan with Free limits. Existing data is preserved, but new operations exceeding Free limits are blocked.
Q: How do I change a group's plan? A: Cancel the current subscription, then create a new subscription for the desired plan.
Q: Do overrides work without a subscription? A: No. Overrides are only effective when there is an active subscription. Without a subscription, override values are ignored.