Funcionalidades
Ruta:
/owner/settings/featuresVisualiza y gestiona las funcionalidades incluidas en tu plan de suscripción actual.
Vista general
Sección titulada «Vista general»La pantalla de Funcionalidades muestra un dashboard con todas las características disponibles en Factux, indicando cuáles están activas según tu plan de suscripción.
Tarjetas de resumen
Sección titulada «Tarjetas de resumen»| Tarjeta | Color | Descripción |
|---|---|---|
| Funcionalidades Activas | Verde | Cantidad de features habilitadas vs total |
| Estado de Suscripción | Variable | Indica si tienes plan activo, trial o sin suscripción |
| Plan Actual | Info | Muestra el nombre y slug de tu plan |
Información mostrada
Sección titulada «Información mostrada»Columnas de la tabla: Expansión, Funcionalidad, Categoría, Estado, Acciones
Categorías disponibles:
- Cumplimiento (compliance)
- Integración (integration)
- Reportes (reporting)
- Colaboración (collaboration)
- Seguridad (security)
- Automatización (automation)
- Ventas (sales)
- Inventario (inventory)
- Operaciones (operations)
- Financiero (financial)
Estados posibles:
| Estado | Badge | Descripción |
|---|---|---|
| Incluida | Verde | Funcionalidad activa en tu plan |
| No disponible | Rojo | Requiere actualizar plan |
| En Beta | Azul | Funcionalidad en versión beta |
| Temporalmente no disponible | Amarillo | En desarrollo o pausada |
Sistema de funcionalidades
Sección titulada «Sistema de funcionalidades»Modelo de control de acceso
Sección titulada «Modelo de control de acceso»Factux utiliza un sistema granular de control de funcionalidades basado en planes:
-
Catálogo de funcionalidades (
plan_features)- Cada funcionalidad tiene una clave única (feature_key)
- Se categoriza para mejor organización
- Puede requerir configuración adicional
-
Asignación a planes (
plan_features_mapping)- Define qué funcionalidades incluye cada plan
- Permite habilitar/deshabilitar features por plan
- Establece prioridades de acceso
-
Validación en tiempo real
- Edge function valida acceso antes de usar una feature
- Registra intentos de acceso (permitidos y bloqueados)
- Sugiere plan siguiente si no tienes acceso
Estados de desarrollo
Sección titulada «Estados de desarrollo»Las funcionalidades pueden tener diferentes estados de visibilidad:
| Visibilidad | Acceso | Descripción |
|---|---|---|
public | Todos los planes que la incluyan | Funcionalidad disponible públicamente |
beta | Planes seleccionados + aviso beta | En pruebas con usuarios reales |
internal | Solo desarrollo interno | No visible para clientes |
development | Bloqueada | En construcción activa |
Categorías de funcionalidades
Sección titulada «Categorías de funcionalidades»Cumplimiento (compliance)
Sección titulada «Cumplimiento (compliance)»Funcionalidades relacionadas con normativas fiscales y legales.
Ejemplos:
- VeriFactu (envío de registros AEAT)
- Facturación electrónica
- Certificados digitales
- SII (Suministro Inmediato de Información)
Integración (integration)
Sección titulada «Integración (integration)»Conexiones con servicios externos y APIs.
Ejemplos:
- Conexión bancaria
- Pasarelas de pago
- ERP externos
- API REST de Factux
Automatización (automation)
Sección titulada «Automatización (automation)»Tareas programadas y flujos automáticos.
Ejemplos:
- Facturas recurrentes
- Recordatorios de pago
- Workflows personalizados
- Notificaciones automáticas
Reportes (reporting)
Sección titulada «Reportes (reporting)»Generación de informes y análisis.
Ejemplos:
- Informes de ventas
- Análisis de cobros
- Métricas de negocio
- Exportaciones avanzadas
Funciones principales
Sección titulada «Funciones principales»| Función | Descripción | Documentación |
|---|---|---|
| Ver funcionalidades | Consulta todas las features y su estado | Ver |
| Filtrar por categoría | Muestra solo features de una categoría | Ver |
| Expandir detalles | Visualiza descripción completa de una feature | Ver |
| Actualizar plan | Acceso directo a página de planes | Ver |
Restricciones de acceso
Sección titulada «Restricciones de acceso»Solo propietarios
Sección titulada «Solo propietarios»Esta configuración está restringida a propietarios del negocio. Los colaboradores y empleados no pueden acceder.
Mensaje mostrado:
Acceso restringido Solo los propietarios pueden acceder a esta configuración.
Razones de bloqueo de features
Sección titulada «Razones de bloqueo de features»Cuando una funcionalidad no está disponible, se muestra uno de estos mensajes:
| Código | Mensaje corto | Descripción completa |
|---|---|---|
no_subscription | No tienes una suscripción activa | Necesitas suscribirte a un plan para acceder |
feature_not_in_plan | No incluida en tu plan actual | Actualiza tu plan para acceder |
feature_disabled | Funcionalidad deshabilitada temporalmente | Inténtalo más tarde |
limit_exceeded | Límite de uso alcanzado | Has alcanzado el límite de tu plan |
trial_expired | Período de prueba finalizado | Suscríbete a un plan para continuar |
feature_in_development | En desarrollo | Funcionalidad no disponible públicamente |
feature_temporarily_unavailable | Temporalmente no disponible | En mantenimiento o pausada |
Referencia técnica
Sección titulada «Referencia técnica»Tablas de base de datos
plan_features
Sección titulada «plan_features»Catálogo maestro de todas las funcionalidades disponibles.
| Columna | Tipo | Descripción |
|---|---|---|
id | uuid | Identificador único |
key | text | Clave única de la funcionalidad (ej: verifactu) |
name | text | Nombre visible (ej: “VeriFactu”) |
description | text | Descripción completa |
category | text | Categoría (compliance, integration, etc.) |
icon_name | text | Nombre del icono Lucide (ej: shield) |
requires_setup | boolean | Si requiere configuración adicional |
documentation_url | text | URL a documentación específica |
created_at | timestamptz | Fecha de creación |
updated_at | timestamptz | Última actualización |
Constraints:
categorydebe ser uno de: compliance, integration, collaboration, reporting, automation, security, sales, inventory, operations, financialkeyes único (índiceidx_plan_features_key_unique)
plan_features_mapping
Sección titulada «plan_features_mapping»Asignación de funcionalidades a planes de suscripción.
| Columna | Tipo | Descripción |
|---|---|---|
id | uuid | Identificador único |
plan_id | uuid | FK a subscription_plans |
feature_key | text | FK a plan_features.key |
enabled | boolean | Si la feature está activa en este plan |
priority | integer | Prioridad de acceso (mayor = más prioritario) |
created_at | timestamptz | Fecha de creación |
updated_at | timestamptz | Última actualización |
Constraints:
- Único por combinación
(plan_id, feature_key) - Cascada en DELETE de plan o feature
feature_development_status
Sección titulada «feature_development_status»Estado de desarrollo y visibilidad de funcionalidades.
| Columna | Tipo | Descripción |
|---|---|---|
feature_key | text | FK a plan_features.key |
is_active | boolean | Si la feature está activa globalmente |
is_paused | boolean | Si está temporalmente pausada |
pause_reason | text | Razón de la pausa |
is_beta | boolean | Si está en fase beta |
visibility | text | Nivel de visibilidad (public, beta, internal, development) |
release_date | timestamptz | Fecha de lanzamiento planificada |
metadata | jsonb | Metadatos adicionales |
feature_access_logs
Sección titulada «feature_access_logs»Registro de intentos de acceso a funcionalidades.
| Columna | Tipo | Descripción |
|---|---|---|
business_id | uuid | Negocio que intenta acceder |
feature_key | text | Funcionalidad solicitada |
action | text | Acción: access o blocked |
reason | text | Razón del resultado |
metadata | jsonb | Información adicional del intento |
created_at | timestamptz | Timestamp del intento |
Políticas RLS
plan_features
Sección titulada «plan_features»| Política | Operación | Regla |
|---|---|---|
Anyone can read plan_features | SELECT | Público (cualquiera puede leer) |
Active admins can insert plan_features | INSERT | Solo administradores activos |
Active admins can update plan_features | UPDATE | Solo administradores activos |
Active admins can delete plan_features | DELETE | Solo administradores activos |
plan_features_mapping
Sección titulada «plan_features_mapping»| Política | Operación | Regla |
|---|---|---|
Anyone can read plan_features_mapping | SELECT | Público (cualquiera puede leer) |
Admins can manage plan_features_mapping | ALL | Solo administradores activos |
Nota: Los logs de acceso (feature_access_logs) son solo escritura desde Edge Functions.
Edge Functions
validate-feature-access
Sección titulada «validate-feature-access»Ruta: supabase/functions/validate-feature-access
Propósito: Valida si un negocio tiene acceso a una funcionalidad específica.
Request:
interface ValidateFeatureAccessRequest { business_id: string; feature_key: string;}Response:
interface FeatureAccessResponse { enabled: boolean; reason?: string; nextPlan?: { id: string; name: string; price: number; billing_cycle: string; }; currentUsage?: number; limit?: number; limitKey?: string; isBeta?: boolean; betaMessage?: string; metadata?: Record<string, any>;}Flujo de validación:
- Verifica suscripción activa o en trial
- Busca feature en
plan_features_mapping - Valida
feature_development_status - Registra el intento en
feature_access_logs - Retorna resultado + siguiente plan si bloqueado
Razones de bloqueo:
no_subscription— Sin suscripción activafeature_not_in_plan— Feature no incluidafeature_disabled— Deshabilitada explícitamentefeature_temporarily_unavailable— En pausa o inactivafeature_in_development— Visibilidad internal/development
validate-feature-access-batch
Sección titulada «validate-feature-access-batch»Propósito: Valida múltiples features de una sola vez (optimización).
Request:
interface ValidateFeatureAccessBatchRequest { business_id: string; feature_keys: string[];}Response:
interface BatchResponse { results: Record<string, FeatureAccessResponse>;}Tipos TypeScript
Database Types
Sección titulada «Database Types»// Desde src/integrations/supabase/types.ts
interface PlanFeatures { Row: { id: string; key: string; name: string; description: string | null; category: string; icon_name: string | null; requires_setup: boolean | null; documentation_url: string | null; created_at: string | null; updated_at: string | null; }; Insert: { id?: string; key: string; name: string; description?: string | null; category: string; icon_name?: string | null; requires_setup?: boolean | null; documentation_url?: string | null; created_at?: string | null; updated_at?: string | null; }; Update: { key?: string; name?: string; description?: string | null; category?: string; icon_name?: string | null; requires_setup?: boolean | null; documentation_url?: string | null; updated_at?: string | null; };}
interface PlanFeaturesMapping { Row: { id: string; plan_id: string; feature_key: string; enabled: boolean | null; priority: number | null; created_at: string | null; updated_at: string | null; }; Insert: { id?: string; plan_id: string; feature_key: string; enabled?: boolean | null; priority?: number | null; created_at?: string | null; updated_at?: string | null; }; Update: { plan_id?: string; feature_key?: string; enabled?: boolean | null; priority?: number | null; updated_at?: string | null; };}Feature Flags (Frontend)
Sección titulada «Feature Flags (Frontend)»// Desde src/config/features.ts
export const FEATURE_FLAGS = { // Dynamic Sidebar con feature access control DYNAMIC_SIDEBAR: import.meta.env.VITE_ENABLE_DYNAMIC_SIDEBAR !== 'false',
// Debug mode para sidebar DEBUG_SIDEBAR: import.meta.env.VITE_DEBUG_SIDEBAR === 'true',
// Feature access validation STRICT_FEATURE_VALIDATION: import.meta.env.VITE_STRICT_FEATURE_VALIDATION === 'true',} as const;
export type FeatureFlag = keyof typeof FEATURE_FLAGS;
export function isFeatureEnabled(flag: FeatureFlag): boolean { return FEATURE_FLAGS[flag] ?? false;}Hooks React
useFeatureAccess
Sección titulada «useFeatureAccess»Archivo: src/hooks/useFeatureAccess.ts
Verifica acceso a una funcionalidad específica.
interface UseFeatureAccessOptions { businessId: string; featureKey: string; autoCheck?: boolean;}
interface UseFeatureAccessReturn { enabled: boolean; loading: boolean; error: string | null; data: FeatureAccessResponse | null; check: () => Promise<void>; nextPlan?: { id: string; name: string; price: number; billing_cycle: string; }; reason?: string; limit?: number; limitKey?: string;}
// Usoconst { enabled, loading, nextPlan } = useFeatureAccess({ businessId: currentBusinessId, featureKey: 'verifactu', autoCheck: true});
if (loading) return <Spinner />;if (!enabled) return <FeatureBlocker nextPlan={nextPlan} />;return <FeatureComponent />;useMultipleFeatureAccess
Sección titulada «useMultipleFeatureAccess»Verifica múltiples funcionalidades a la vez.
const features = useMultipleFeatureAccess({ businessId: currentBusinessId, featureKeys: ['verifactu', 'bank_connection', 'api_access'], autoCheck: true});
return ( <div> {features.features.map(f => ( <div key={f.featureKey}> {f.featureKey}: {f.enabled ? 'Habilitado' : 'Bloqueado'} </div> ))} </div>);useSubscriptionStatus
Sección titulada «useSubscriptionStatus»Archivo: src/hooks/useSubscriptionStatus.ts
Obtiene el estado completo de la suscripción.
interface SubscriptionStatus { hasSubscription: boolean; status: 'active' | 'trialing' | 'past_due' | 'canceled' | 'none'; planName?: string; planSlug?: string; planId?: string; plan?: { name: string; slug: string; limits?: Record<string, any>; }; currentPeriodStart?: Date; currentPeriodEnd?: Date; trialEnd?: Date; trialDaysRemaining?: number; isTrialing: boolean; isActive: boolean; cancelAtPeriodEnd: boolean; stripeCustomerId?: string; canAccessStripePortal: boolean;}
// Usoconst { subscriptionStatus, isLoading, refetch } = useSubscriptionStatus();
if (subscriptionStatus?.isTrialing) { return <TrialBanner daysRemaining={subscriptionStatus.trialDaysRemaining} />;}Componentes React
FeaturesDashboard
Sección titulada «FeaturesDashboard»Archivo: src/features/settings/components/FeaturesDashboard.tsx
Componente principal que muestra el dashboard de funcionalidades.
Props: Ninguna (usa contexto de autenticación)
Características:
- Tarjetas de resumen con estadísticas
- Tabla expandible con todas las features
- Filtros por categoría y búsqueda
- Iconos dinámicos desde Lucide
- Enlaces a actualización de plan
Estados:
interface FeatureFromDB { id: string; key: string; name: string; description: string; category: string; icon_name: string | null; requires_setup: boolean; is_enabled: boolean;}Categorías traducidas:
const CATEGORY_LABELS: Record<string, string> = { compliance: 'Cumplimiento', integration: 'Integración', reporting: 'Reportes', collaboration: 'Colaboración', security: 'Seguridad', automation: 'Automatización',};Queries de diagnóstico
Ver todas las features de un plan
Sección titulada «Ver todas las features de un plan»SELECT pf.key, pf.name, pf.category, pfm.enabled, pfm.priority, sp.name as plan_nameFROM plan_features pfINNER JOIN plan_features_mapping pfm ON pf.key = pfm.feature_keyINNER JOIN subscription_plans sp ON pfm.plan_id = sp.idWHERE sp.slug = 'profesional'ORDER BY pf.category, pf.name;Ver features activas de un negocio
Sección titulada «Ver features activas de un negocio»SELECT pf.key, pf.name, pf.category, bs.status as subscription_status, sp.name as current_planFROM businesses bINNER JOIN business_subscriptions bs ON b.id = bs.business_idINNER JOIN subscription_plans sp ON bs.plan_id = sp.idINNER JOIN plan_features_mapping pfm ON sp.id = pfm.plan_idINNER JOIN plan_features pf ON pfm.feature_key = pf.keyWHERE b.id = '<business_id>' AND bs.status IN ('active', 'trialing') AND pfm.enabled = trueORDER BY pf.category, pf.name;Features bloqueadas por plan
Sección titulada «Features bloqueadas por plan»SELECT pf.key, pf.name, pf.category, sp_next.name as next_plan_with_feature, sp_next.priceFROM plan_features pfLEFT JOIN plan_features_mapping pfm ON pf.key = pfm.feature_key AND pfm.plan_id = '<current_plan_id>'LEFT JOIN LATERAL ( SELECT sp.*, pfm2.enabled FROM subscription_plans sp INNER JOIN plan_features_mapping pfm2 ON sp.id = pfm2.plan_id WHERE pfm2.feature_key = pf.key AND pfm2.enabled = true AND sp.display_order > (SELECT display_order FROM subscription_plans WHERE id = '<current_plan_id>') ORDER BY sp.display_order LIMIT 1) sp_next ON trueWHERE pfm.id IS NULL OR pfm.enabled = false;Log de accesos bloqueados
Sección titulada «Log de accesos bloqueados»SELECT fal.created_at, b.name as business_name, pf.name as feature_name, fal.reason, fal.metadata->>'current_plan_id' as current_planFROM feature_access_logs falINNER JOIN businesses b ON fal.business_id = b.idLEFT JOIN plan_features pf ON fal.feature_key = pf.keyWHERE fal.action = 'blocked' AND fal.created_at > NOW() - INTERVAL '7 days'ORDER BY fal.created_at DESCLIMIT 50;Branding Factux
Sección titulada «Branding Factux»Los elementos visuales utilizan el color verde característico:
Color principal: hsl(68 100% 50%)
- Badges de funcionalidades activas
- Iconos de éxito
- Indicadores de estado positivo