template-saas/docs/01-modulos/SAAS-005-plans.md
rckrdmrd 50a821a415
Some checks failed
CI / Backend CI (push) Has been cancelled
CI / Frontend CI (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / CI Summary (push) Has been cancelled
[SIMCO-V38] feat: Actualizar a SIMCO v3.8.0
- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8
- Actualizaciones de configuracion

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 08:53:08 -06:00

235 lines
4.8 KiB
Markdown

---
id: "SAAS-005"
title: "Planes y Limites"
type: "Module"
status: "Published"
priority: "P0"
module: "plans"
version: "1.0.0"
created_date: "2026-01-07"
updated_date: "2026-01-10"
---
# SAAS-005: Planes y Limites
## Metadata
- **Codigo:** SAAS-005
- **Modulo:** Plans
- **Prioridad:** P0
- **Estado:** Completado
- **Fase:** 2 - Billing
## Descripcion
Sistema de planes y limites: definicion de planes con features y limites, verificacion de limites en runtime, y feature gating basado en plan.
## Objetivos
1. Definir planes (Free, Starter, Pro, Enterprise)
2. Features por plan
3. Limites configurables
4. Verificacion en runtime
5. Feature gating
## Alcance
### Incluido
- 4 planes predefinidos
- Features booleanas por plan
- Limites numericos por plan
- Funciones de verificacion
- Middleware de plan
### Excluido
- Planes custom por tenant
- Addons/complementos
- Overage charges
## Planes Definidos
### Free
```yaml
price: $0/mes
features:
- basic_dashboard: true
- api_access: false
- ai_assistant: false
- webhooks: false
- custom_branding: false
limits:
users: 1
storage_mb: 100
api_calls_month: 1000
```
### Starter ($29/mes)
```yaml
price: $29/mes | $290/ano
features:
- basic_dashboard: true
- api_access: true
- ai_assistant: false
- webhooks: false
- custom_branding: false
limits:
users: 5
storage_mb: 1000
api_calls_month: 10000
```
### Pro ($79/mes)
```yaml
price: $79/mes | $790/ano
features:
- basic_dashboard: true
- api_access: true
- ai_assistant: true
- webhooks: true
- custom_branding: false
limits:
users: 20
storage_mb: 10000
api_calls_month: 100000
ai_tokens_month: 50000
```
### Enterprise ($199/mes)
```yaml
price: $199/mes | $1990/ano
features:
- basic_dashboard: true
- api_access: true
- ai_assistant: true
- webhooks: true
- custom_branding: true
- sso: true
- audit_logs: true
limits:
users: unlimited
storage_mb: unlimited
api_calls_month: unlimited
ai_tokens_month: 200000
```
## Modelo de Datos
### Tablas (schema: plans)
**plans**
- id, name, code, description
- price_monthly, price_yearly, currency
- features (JSONB), limits (JSONB)
- stripe_monthly_price_id, stripe_yearly_price_id
- is_active, sort_order
**plan_features** (opcional, para tracking)
- id, plan_id, feature_key
- enabled, config
## Funciones de Verificacion
### SQL Functions
```sql
-- Obtener limites del tenant
CREATE FUNCTION get_tenant_limits(p_tenant_id UUID)
RETURNS JSONB AS $$
SELECT p.limits
FROM subscriptions s
JOIN plans p ON s.plan_id = p.id
WHERE s.tenant_id = p_tenant_id
AND s.status = 'active';
$$ LANGUAGE SQL;
-- Verificar limite
CREATE FUNCTION check_limit(
p_tenant_id UUID,
p_limit_key TEXT,
p_current_value INT
) RETURNS BOOLEAN AS $$
SELECT CASE
WHEN (get_tenant_limits(p_tenant_id)->>p_limit_key)::INT = -1 THEN true
ELSE p_current_value < (get_tenant_limits(p_tenant_id)->>p_limit_key)::INT
END;
$$ LANGUAGE SQL;
```
### Backend Service
```typescript
class PlansService {
async hasFeature(tenantId: string, feature: string): Promise<boolean> {
const plan = await this.getTenantPlan(tenantId);
return plan.features[feature] === true;
}
async checkLimit(tenantId: string, limit: string, current: number): Promise<boolean> {
const plan = await this.getTenantPlan(tenantId);
const max = plan.limits[limit];
return max === -1 || current < max; // -1 = unlimited
}
}
```
## Endpoints API
| Metodo | Endpoint | Descripcion |
|--------|----------|-------------|
| GET | /plans | Listar planes |
| GET | /plans/:code | Obtener plan |
| GET | /plans/current | Plan actual del tenant |
| GET | /plans/current/limits | Limites actuales |
| GET | /plans/current/usage | Uso actual |
## Guards y Decorators
```typescript
// Guard de feature
@RequiresFeature('ai_assistant')
async askAI(question: string) {
// Solo ejecuta si tiene feature
}
// Guard de plan minimo
@RequiresPlan('pro')
async advancedReport() {
// Solo Pro o superior
}
// Verificacion de limite
@CheckLimit('users')
async createUser(dto: CreateUserDto) {
// Verifica antes de crear
}
```
## Entregables
| Entregable | Estado | Archivo |
|------------|--------|---------|
| plans.service.ts | Completado | `modules/plans/` |
| plan.guard.ts | Completado | `guards/` |
| Seeds de planes | Completado | `seeds/prod/plans.sql` |
| DDL plans schema | Completado | `ddl/schemas/plans/` |
## Dependencias
### Depende de
- SAAS-002 (Tenants)
- SAAS-004 (Billing - para suscripcion)
### Bloquea a
- SAAS-003 (Users - limite usuarios)
- SAAS-006 (AI - feature flag)
- SAAS-010 (Webhooks - feature flag)
## Criterios de Aceptacion
- [x] 4 planes creados en BD
- [x] Features se verifican correctamente
- [x] Limites se respetan
- [x] Upgrade desbloquea features
- [x] UI muestra plan actual
---
**Ultima actualizacion:** 2026-01-10