DDL-SPEC: Schema core_settings
Identificacion
| Campo |
Valor |
| Schema |
core_settings |
| Modulo |
MGN-006 |
| Version |
1.0 |
| Estado |
En Diseno |
| Autor |
Requirements-Analyst |
| Fecha |
2025-12-05 |
Descripcion General
El schema core_settings gestiona configuraciones del sistema, por tenant, preferencias de usuario y feature flags. Implementa herencia de configuraciones y evaluacion eficiente de flags.
RF Cubiertos
| RF |
Titulo |
Tablas |
| RF-SETTINGS-001 |
Configuraciones Sistema |
system_settings |
| RF-SETTINGS-002 |
Configuraciones Tenant |
tenant_settings, plan_settings |
| RF-SETTINGS-003 |
Preferencias Usuario |
user_preferences |
| RF-SETTINGS-004 |
Feature Flags |
feature_flags, feature_flag_overrides |
Diagrama ER
erDiagram
system_settings {
uuid id PK
varchar key UK
jsonb value
varchar data_type
varchar category
text description
boolean is_public
boolean is_editable
jsonb default_value
jsonb validation_rules
}
plan_settings {
uuid id PK
uuid plan_id FK
varchar key
jsonb value
}
tenant_settings {
uuid id PK
uuid tenant_id FK
varchar key
jsonb value
varchar inherited_from
boolean is_overridden
}
user_preferences {
uuid id PK
uuid user_id FK
varchar key
jsonb value
timestamptz synced_at
}
feature_flags {
uuid id PK
varchar key UK
varchar name
text description
varchar flag_type
jsonb default_value
jsonb rollout_config
boolean is_active
timestamptz expires_at
}
feature_flag_overrides {
uuid id PK
uuid feature_flag_id FK
varchar level
uuid level_id
jsonb value
boolean is_active
}
plan_settings }o--|| subscription_plans : "plan"
tenant_settings }o--|| tenants : "tenant"
user_preferences }o--|| users : "user"
feature_flag_overrides }o--|| feature_flags : "flag"
Tablas
1. system_settings
Configuraciones globales del sistema.
| Columna |
Tipo |
Nullable |
Default |
Descripcion |
id |
UUID |
NOT NULL |
gen_random_uuid() |
PK |
key |
VARCHAR(100) |
NOT NULL |
- |
Clave unica |
value |
JSONB |
NOT NULL |
- |
Valor actual |
data_type |
VARCHAR(20) |
NOT NULL |
'string' |
Tipo de dato |
category |
VARCHAR(50) |
NOT NULL |
- |
Categoria |
description |
TEXT |
NULL |
- |
Descripcion UI |
is_public |
BOOLEAN |
NOT NULL |
false |
Visible a tenants |
is_editable |
BOOLEAN |
NOT NULL |
true |
Modificable runtime |
default_value |
JSONB |
NULL |
- |
Valor por defecto |
validation_rules |
JSONB |
NULL |
'{}' |
Reglas validacion |
created_at |
TIMESTAMPTZ |
NOT NULL |
NOW() |
Fecha creacion |
updated_at |
TIMESTAMPTZ |
NOT NULL |
NOW() |
Fecha actualizacion |
updated_by |
UUID |
NULL |
- |
Usuario modificador |
CONSTRAINT pk_system_settings PRIMARY KEY (id),
CONSTRAINT uk_system_settings_key UNIQUE (key),
CONSTRAINT chk_system_settings_data_type
CHECK (data_type IN ('string', 'number', 'boolean', 'json', 'array', 'secret'))
CREATE INDEX idx_system_settings_category ON core_settings.system_settings(category);
CREATE INDEX idx_system_settings_public ON core_settings.system_settings(is_public) WHERE is_public = true;
2. plan_settings
Configuraciones por defecto por plan de suscripcion.
| Columna |
Tipo |
Nullable |
Default |
Descripcion |
id |
UUID |
NOT NULL |
gen_random_uuid() |
PK |
plan_id |
UUID |
NOT NULL |
- |
FK a subscription_plans |
key |
VARCHAR(100) |
NOT NULL |
- |
Clave de setting |
value |
JSONB |
NOT NULL |
- |
Valor para el plan |
created_at |
TIMESTAMPTZ |
NOT NULL |
NOW() |
Fecha creacion |
updated_at |
TIMESTAMPTZ |
NOT NULL |
NOW() |
Fecha actualizacion |
CONSTRAINT pk_plan_settings PRIMARY KEY (id),
CONSTRAINT uk_plan_settings_plan_key UNIQUE (plan_id, key),
CONSTRAINT fk_plan_settings_plan
FOREIGN KEY (plan_id) REFERENCES core_tenants.subscription_plans(id) ON DELETE CASCADE
3. tenant_settings
Configuraciones personalizadas por tenant.
| Columna |
Tipo |
Nullable |
Default |
Descripcion |
id |
UUID |
NOT NULL |
gen_random_uuid() |
PK |
tenant_id |
UUID |
NOT NULL |
- |
FK a tenants |
key |
VARCHAR(100) |
NOT NULL |
- |
Clave de setting |
value |
JSONB |
NOT NULL |
- |
Valor personalizado |
inherited_from |
VARCHAR(20) |
NOT NULL |
'custom' |
system/plan/custom |
is_overridden |
BOOLEAN |
NOT NULL |
true |
Sobreescribe herencia |
created_at |
TIMESTAMPTZ |
NOT NULL |
NOW() |
Fecha creacion |
updated_at |
TIMESTAMPTZ |
NOT NULL |
NOW() |
Fecha actualizacion |
CONSTRAINT pk_tenant_settings PRIMARY KEY (id),
CONSTRAINT uk_tenant_settings_tenant_key UNIQUE (tenant_id, key),
CONSTRAINT fk_tenant_settings_tenant
FOREIGN KEY (tenant_id) REFERENCES core_tenants.tenants(id) ON DELETE CASCADE,
CONSTRAINT chk_tenant_settings_inherited
CHECK (inherited_from IN ('system', 'plan', 'custom'))
-- RLS
ALTER TABLE core_settings.tenant_settings ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON core_settings.tenant_settings
FOR ALL USING (tenant_id = current_setting('app.current_tenant_id')::uuid);
4. user_preferences
Preferencias personales de usuario.
| Columna |
Tipo |
Nullable |
Default |
Descripcion |
id |
UUID |
NOT NULL |
gen_random_uuid() |
PK |
user_id |
UUID |
NOT NULL |
- |
FK a users |
key |
VARCHAR(100) |
NOT NULL |
- |
Clave de preferencia |
value |
JSONB |
NOT NULL |
- |
Valor |
synced_at |
TIMESTAMPTZ |
NOT NULL |
NOW() |
Ultima sync |
created_at |
TIMESTAMPTZ |
NOT NULL |
NOW() |
Fecha creacion |
updated_at |
TIMESTAMPTZ |
NOT NULL |
NOW() |
Fecha actualizacion |
CONSTRAINT pk_user_preferences PRIMARY KEY (id),
CONSTRAINT uk_user_preferences_user_key UNIQUE (user_id, key),
CONSTRAINT fk_user_preferences_user
FOREIGN KEY (user_id) REFERENCES core_users.users(id) ON DELETE CASCADE
5. feature_flags
Definicion de feature flags.
| Columna |
Tipo |
Nullable |
Default |
Descripcion |
id |
UUID |
NOT NULL |
gen_random_uuid() |
PK |
key |
VARCHAR(100) |
NOT NULL |
- |
Clave unica |
name |
VARCHAR(255) |
NOT NULL |
- |
Nombre descriptivo |
description |
TEXT |
NULL |
- |
Descripcion |
flag_type |
VARCHAR(20) |
NOT NULL |
'boolean' |
boolean/percentage/variant |
default_value |
JSONB |
NOT NULL |
'false' |
Valor por defecto |
rollout_config |
JSONB |
NULL |
'{}' |
Config de rollout |
is_active |
BOOLEAN |
NOT NULL |
true |
Flag activo |
expires_at |
TIMESTAMPTZ |
NULL |
- |
Expiracion |
created_at |
TIMESTAMPTZ |
NOT NULL |
NOW() |
Fecha creacion |
updated_at |
TIMESTAMPTZ |
NOT NULL |
NOW() |
Fecha actualizacion |
created_by |
UUID |
NULL |
- |
Usuario creador |
CONSTRAINT pk_feature_flags PRIMARY KEY (id),
CONSTRAINT uk_feature_flags_key UNIQUE (key),
CONSTRAINT chk_feature_flags_type
CHECK (flag_type IN ('boolean', 'percentage', 'variant'))
6. feature_flag_overrides
Overrides de flags por nivel.
| Columna |
Tipo |
Nullable |
Default |
Descripcion |
id |
UUID |
NOT NULL |
gen_random_uuid() |
PK |
feature_flag_id |
UUID |
NOT NULL |
- |
FK a feature_flags |
level |
VARCHAR(20) |
NOT NULL |
- |
plan/tenant/user |
level_id |
UUID |
NOT NULL |
- |
ID del nivel |
value |
JSONB |
NOT NULL |
- |
Valor override |
is_active |
BOOLEAN |
NOT NULL |
true |
Override activo |
created_at |
TIMESTAMPTZ |
NOT NULL |
NOW() |
Fecha creacion |
created_by |
UUID |
NULL |
- |
Usuario creador |
CONSTRAINT pk_feature_flag_overrides PRIMARY KEY (id),
CONSTRAINT uk_feature_flag_overrides UNIQUE (feature_flag_id, level, level_id),
CONSTRAINT fk_feature_flag_overrides_flag
FOREIGN KEY (feature_flag_id) REFERENCES core_settings.feature_flags(id) ON DELETE CASCADE,
CONSTRAINT chk_feature_flag_overrides_level
CHECK (level IN ('plan', 'tenant', 'user'))
CREATE INDEX idx_feature_flag_overrides_lookup
ON core_settings.feature_flag_overrides(feature_flag_id, level, level_id);
Funciones de Utilidad
Obtener Setting Efectivo del Tenant
CREATE OR REPLACE FUNCTION core_settings.get_tenant_setting(
p_tenant_id UUID,
p_key VARCHAR
) RETURNS JSONB AS $$
DECLARE
v_value JSONB;
v_plan_id UUID;
BEGIN
-- 1. Buscar en tenant_settings
SELECT value INTO v_value
FROM core_settings.tenant_settings
WHERE tenant_id = p_tenant_id AND key = p_key AND is_overridden = true;
IF v_value IS NOT NULL THEN
RETURN v_value;
END IF;
-- 2. Buscar en plan_settings
SELECT t.plan_id INTO v_plan_id
FROM core_tenants.tenants t WHERE t.id = p_tenant_id;
SELECT value INTO v_value
FROM core_settings.plan_settings
WHERE plan_id = v_plan_id AND key = p_key;
IF v_value IS NOT NULL THEN
RETURN v_value;
END IF;
-- 3. Retornar system default
SELECT COALESCE(value, default_value) INTO v_value
FROM core_settings.system_settings
WHERE key = p_key;
RETURN v_value;
END;
$$ LANGUAGE plpgsql STABLE;
Evaluar Feature Flag
CREATE OR REPLACE FUNCTION core_settings.evaluate_feature_flag(
p_key VARCHAR,
p_tenant_id UUID DEFAULT NULL,
p_user_id UUID DEFAULT NULL
) RETURNS JSONB AS $$
DECLARE
v_flag RECORD;
v_override JSONB;
v_result JSONB;
BEGIN
-- Obtener flag base
SELECT * INTO v_flag
FROM core_settings.feature_flags
WHERE key = p_key AND is_active = true
AND (expires_at IS NULL OR expires_at > NOW());
IF v_flag IS NULL THEN
RETURN jsonb_build_object('enabled', false, 'source', 'not_found');
END IF;
-- Buscar override por user
IF p_user_id IS NOT NULL THEN
SELECT value INTO v_override
FROM core_settings.feature_flag_overrides
WHERE feature_flag_id = v_flag.id AND level = 'user' AND level_id = p_user_id AND is_active = true;
IF v_override IS NOT NULL THEN
RETURN jsonb_build_object('enabled', v_override, 'source', 'user_override');
END IF;
END IF;
-- Buscar override por tenant
IF p_tenant_id IS NOT NULL THEN
SELECT value INTO v_override
FROM core_settings.feature_flag_overrides
WHERE feature_flag_id = v_flag.id AND level = 'tenant' AND level_id = p_tenant_id AND is_active = true;
IF v_override IS NOT NULL THEN
RETURN jsonb_build_object('enabled', v_override, 'source', 'tenant_override');
END IF;
END IF;
-- Retornar default
RETURN jsonb_build_object('enabled', v_flag.default_value, 'source', 'default');
END;
$$ LANGUAGE plpgsql STABLE;
Seed Data
System Settings
INSERT INTO core_settings.system_settings (key, value, data_type, category, description, is_editable) VALUES
('security.max_login_attempts', '5', 'number', 'security', 'Intentos maximos de login', true),
('security.lockout_duration_minutes', '15', 'number', 'security', 'Duracion bloqueo en minutos', true),
('security.token_expiry_hours', '24', 'number', 'security', 'Expiracion token en horas', true),
('security.password_min_length', '8', 'number', 'security', 'Longitud minima password', true),
('email.smtp_host', '""', 'string', 'email', 'Host SMTP', true),
('email.smtp_port', '587', 'number', 'email', 'Puerto SMTP', true),
('storage.max_file_size_mb', '10', 'number', 'storage', 'Tamano maximo archivo MB', true),
('storage.allowed_extensions', '["pdf","jpg","png","xlsx"]', 'array', 'storage', 'Extensiones permitidas', true),
('performance.cache_ttl_seconds', '300', 'number', 'performance', 'TTL cache segundos', true),
('performance.pagination_max_limit', '100', 'number', 'performance', 'Max items por pagina', false);
Feature Flags
INSERT INTO core_settings.feature_flags (key, name, flag_type, default_value, description) VALUES
('feature.oauth_login', 'Login con OAuth', 'boolean', 'true', 'Habilita login con proveedores OAuth'),
('feature.dark_mode', 'Modo Oscuro', 'boolean', 'true', 'Habilita tema oscuro'),
('feature.export_excel', 'Exportar Excel', 'boolean', 'true', 'Permite exportar a Excel'),
('feature.bulk_operations', 'Operaciones Masivas', 'boolean', 'true', 'Permite operaciones en lote'),
('feature.ai_suggestions', 'Sugerencias IA', 'boolean', 'false', 'Sugerencias con IA');
Historial
| Version |
Fecha |
Autor |
Cambios |
| 1.0 |
2025-12-05 |
Requirements-Analyst |
Creacion inicial |