1383 lines
24 KiB
Markdown
1383 lines
24 KiB
Markdown
|
|
# Frontend ERP – Sistema modular de Settings
|
|||
|
|
|
|||
|
|
## 1. Propósito
|
|||
|
|
|
|||
|
|
Este documento define la arquitectura del sistema de **Configuración (`Settings`)** del ERP.
|
|||
|
|
|
|||
|
|
El objetivo es disponer de una única experiencia de configuración para la empresa activa sin convertir la aplicación base en conocedora de las opciones particulares de cada módulo.
|
|||
|
|
|
|||
|
|
Principio rector:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
La aplicación conoce el sistema de Settings.
|
|||
|
|
La aplicación NO conoce los settings concretos de cada módulo.
|
|||
|
|
|
|||
|
|
Cada módulo declara las opciones de configuración que aporta.
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Este diseño debe integrarse con la arquitectura modular existente del frontend, manteniendo la separación entre routing, datos, controllers y UI.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. Alcance
|
|||
|
|
|
|||
|
|
### 2.1 `/settings`
|
|||
|
|
|
|||
|
|
`/settings` representa exclusivamente:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
Configuración de la empresa activa
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Ejemplos potenciales:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
/settings/company/details
|
|||
|
|
/settings/billing/verifactu
|
|||
|
|
/settings/billing/document-series
|
|||
|
|
/settings/billing/certificates
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Una modificación realizada aquí afecta a la empresa activa y, potencialmente, a todos los usuarios que trabajan con ella.
|
|||
|
|
|
|||
|
|
### 2.2 `/account`
|
|||
|
|
|
|||
|
|
La configuración personal del usuario queda fuera de este sistema:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
/account
|
|||
|
|
→ configuración personal del usuario
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Ejemplos:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
idioma
|
|||
|
|
apariencia
|
|||
|
|
preferencias personales
|
|||
|
|
seguridad de cuenta
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Por tanto:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
/settings ≠ /account
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
No se introduce en esta fase ningún `scope: "company" | "user"`, porque `/settings` tiene un único ámbito semántico: la empresa activa.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. Objetivos
|
|||
|
|
|
|||
|
|
El sistema debe permitir:
|
|||
|
|
|
|||
|
|
1. Disponer de una única entrada **Configuración** en la navegación principal.
|
|||
|
|
2. Reunir en `/settings` configuraciones procedentes de múltiples módulos.
|
|||
|
|
3. Permitir que varios módulos aporten opciones a una misma sección.
|
|||
|
|
4. Mantener a cada módulo como propietario de sus páginas, lógica y datos.
|
|||
|
|
5. Añadir una configuración nueva sin modificar el shell de Settings.
|
|||
|
|
6. Soportar navegación directa mediante URL.
|
|||
|
|
7. Aplicar permisos sobre opciones concretas.
|
|||
|
|
8. Mantener una experiencia visual consistente.
|
|||
|
|
9. Evitar un almacenamiento genérico de configuración.
|
|||
|
|
10. Evitar un framework dinámico excesivamente complejo.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. No objetivos
|
|||
|
|
|
|||
|
|
El sistema de Settings no debe convertirse en:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
un almacén genérico key/value
|
|||
|
|
un framework de formularios
|
|||
|
|
un sistema de permisos
|
|||
|
|
un router alternativo
|
|||
|
|
un gestor de estado global
|
|||
|
|
un registro genérico de componentes React
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Tampoco debe decidir cómo persiste cada dominio su configuración.
|
|||
|
|
|
|||
|
|
Ejemplos:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
VeriFactu → persistencia y reglas propias
|
|||
|
|
Series documentales → módulo document-series
|
|||
|
|
Datos de empresa → módulo propietario de company/identity
|
|||
|
|
Certificados → módulo propietario correspondiente
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Regla:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
Settings framework ≠ Settings persistence
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. Principio de propiedad
|
|||
|
|
|
|||
|
|
La propiedad se divide en dos niveles.
|
|||
|
|
|
|||
|
|
### 5.1 Shell de Settings
|
|||
|
|
|
|||
|
|
Responsable de:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
descubrimiento de configuraciones
|
|||
|
|
agrupación por secciones
|
|||
|
|
ordenación
|
|||
|
|
navegación
|
|||
|
|
layout
|
|||
|
|
estado de sección/entrada activa
|
|||
|
|
filtrado por permisos
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.2 Módulo propietario
|
|||
|
|
|
|||
|
|
Responsable de:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
routing de su configuración
|
|||
|
|
Page
|
|||
|
|
Page Controller
|
|||
|
|
Controllers
|
|||
|
|
Entities
|
|||
|
|
Hooks
|
|||
|
|
API
|
|||
|
|
validación
|
|||
|
|
persistencia
|
|||
|
|
reglas de negocio
|
|||
|
|
UI específica
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
La arquitectura interna de cada setting debe seguir el flujo general del ERP:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
API
|
|||
|
|
→ DTO
|
|||
|
|
→ Adapter
|
|||
|
|
→ Entity
|
|||
|
|
→ Hook
|
|||
|
|
→ Controller
|
|||
|
|
→ Page Controller
|
|||
|
|
→ UI
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Los controllers no deben conocer routing. La integración con URL/navegación sigue correspondiendo al Page Controller/Page.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6. Arquitectura general
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
apps/web
|
|||
|
|
│
|
|||
|
|
├── navegación principal
|
|||
|
|
│ │
|
|||
|
|
│ └── Configuración
|
|||
|
|
│ │
|
|||
|
|
│ ▼
|
|||
|
|
│ /settings
|
|||
|
|
│
|
|||
|
|
├── Settings Shell
|
|||
|
|
│ ├── SettingsLayout / SettingsPage
|
|||
|
|
│ ├── SettingsNavigation
|
|||
|
|
│ └── SettingsRegistry
|
|||
|
|
│
|
|||
|
|
└── módulos registrados
|
|||
|
|
│
|
|||
|
|
├──────────────────────────┬─────────────────────────┐
|
|||
|
|
▼ ▼ ▼
|
|||
|
|
customer-invoices document-series identity
|
|||
|
|
│ │ │
|
|||
|
|
└─ contribution └─ contribution └─ contribution
|
|||
|
|
│ │ │
|
|||
|
|
└───────────── Settings Registry ──────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
El shell consume metadatos declarativos, no implementaciones de dominio.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 7. Contribuciones de módulos
|
|||
|
|
|
|||
|
|
Cada módulo puede declarar las opciones de configuración que aporta.
|
|||
|
|
|
|||
|
|
El punto natural es el `manifest.ts` del módulo, siempre que la auditoría del repositorio confirme que este es el contrato correcto para ampliar metadatos de módulo.
|
|||
|
|
|
|||
|
|
Conceptualmente:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
export const customerInvoicesManifest = {
|
|||
|
|
// configuración existente del módulo
|
|||
|
|
|
|||
|
|
settings: {
|
|||
|
|
sections: [],
|
|||
|
|
entries: [],
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
El contrato exacto debe adaptarse al shape real del manifest existente.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8. Secciones compartidas entre módulos
|
|||
|
|
|
|||
|
|
Una sección de Settings no pertenece necesariamente a un único módulo.
|
|||
|
|
|
|||
|
|
Ejemplo:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
Facturación
|
|||
|
|
├── VeriFactu customer-invoices
|
|||
|
|
├── Series documentales document-series
|
|||
|
|
└── Certificados módulo propietario correspondiente
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Varios módulos pueden contribuir a:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
sectionId = "billing"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
sin conocerse entre ellos.
|
|||
|
|
|
|||
|
|
El registry se encarga de fusionar esas contribuciones.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 9. Contratos conceptuales
|
|||
|
|
|
|||
|
|
### 9.1 Sección
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
export interface ModuleSettingsSectionContribution {
|
|||
|
|
id: string;
|
|||
|
|
labelKey: string;
|
|||
|
|
order?: number;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 9.2 Entrada
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
export interface ModuleSettingsEntryContribution {
|
|||
|
|
id: string;
|
|||
|
|
sectionId: string;
|
|||
|
|
|
|||
|
|
labelKey: string;
|
|||
|
|
descriptionKey?: string;
|
|||
|
|
|
|||
|
|
path: string;
|
|||
|
|
|
|||
|
|
order?: number;
|
|||
|
|
permission?: string;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 9.3 Contribución completa
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
export interface ModuleSettingsContribution {
|
|||
|
|
sections?: ModuleSettingsSectionContribution[];
|
|||
|
|
entries?: ModuleSettingsEntryContribution[];
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Este contrato debe mantenerse deliberadamente pequeño.
|
|||
|
|
|
|||
|
|
No añadir en V1 salvo necesidad real:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
component
|
|||
|
|
loader
|
|||
|
|
icon renderer
|
|||
|
|
badge provider
|
|||
|
|
status resolver
|
|||
|
|
search keywords
|
|||
|
|
feature flag resolver
|
|||
|
|
nested tree arbitrario
|
|||
|
|
custom layout
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 10. Identidad de secciones
|
|||
|
|
|
|||
|
|
Las secciones deben utilizar IDs semánticos y estables.
|
|||
|
|
|
|||
|
|
Ejemplos:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
company
|
|||
|
|
billing
|
|||
|
|
sales
|
|||
|
|
purchases
|
|||
|
|
users
|
|||
|
|
integrations
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
No es necesario convertir inicialmente el conjunto en una unión TypeScript cerrada si eso dificulta la extensibilidad modular.
|
|||
|
|
|
|||
|
|
Ejemplo:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
{
|
|||
|
|
id: "billing",
|
|||
|
|
labelKey: "settings.sections.billing",
|
|||
|
|
order: 200,
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Si dos módulos declaran `billing`, el registry debe reconocer que representan la misma sección.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 11. Conflictos de secciones
|
|||
|
|
|
|||
|
|
El mismo `sectionId` no puede representar semánticas diferentes.
|
|||
|
|
|
|||
|
|
Ejemplo inválido:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
billing + "Facturación"
|
|||
|
|
billing + "Ventas"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Regla:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
mismo sectionId
|
|||
|
|
→ misma identidad semántica
|
|||
|
|
→ labels compatibles
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
En desarrollo, el registry debe detectar conflictos en lugar de resolverlos silenciosamente.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 12. Identidad de entradas
|
|||
|
|
|
|||
|
|
El `id` identifica una opción dentro del sistema de Settings.
|
|||
|
|
|
|||
|
|
Debe ser:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
estable
|
|||
|
|
semántico
|
|||
|
|
independiente del texto visible
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Ejemplos:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
verifactu
|
|||
|
|
document-series
|
|||
|
|
certificates
|
|||
|
|
company-details
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Evitar:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
setting1
|
|||
|
|
optionA
|
|||
|
|
config
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Si existe riesgo real de colisión, el registry puede usar internamente una identidad compuesta:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
moduleId + entryId
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
sin obligar a exponer esa representación al consumidor.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 13. Routing
|
|||
|
|
|
|||
|
|
### Regla principal
|
|||
|
|
|
|||
|
|
Settings registra destinos de navegación, no componentes React.
|
|||
|
|
|
|||
|
|
Evitar:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
{
|
|||
|
|
id: "verifactu",
|
|||
|
|
component: VerifactuSettingsPage,
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Preferir:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
{
|
|||
|
|
id: "verifactu",
|
|||
|
|
path: "/settings/billing/verifactu",
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
El módulo propietario continúa registrando su propia route.
|
|||
|
|
|
|||
|
|
### Motivo
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
Settings Registry
|
|||
|
|
→ conoce navegación
|
|||
|
|
|
|||
|
|
Módulo
|
|||
|
|
→ conoce página
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Esto evita convertir Settings en un segundo router o sistema de carga dinámica de React.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 14. Namespace de rutas
|
|||
|
|
|
|||
|
|
Convención objetivo:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
/settings/:section/:setting
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Ejemplos:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
/settings/company/details
|
|||
|
|
/settings/billing/verifactu
|
|||
|
|
/settings/billing/document-series
|
|||
|
|
/settings/billing/certificates
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
La ruta exacta debe verificarse contra el routing real antes de implementarla.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 15. Ruta raíz `/settings`
|
|||
|
|
|
|||
|
|
La raíz puede:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
redirigir a la primera configuración disponible
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
o presentar un índice/resumen de configuraciones.
|
|||
|
|
|
|||
|
|
La decisión final es de UX y puede tomarse al implementar el shell.
|
|||
|
|
|
|||
|
|
No debe contener lógica de dominio.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 16. Settings Registry
|
|||
|
|
|
|||
|
|
El registry es la pieza responsable de combinar las contribuciones de todos los módulos.
|
|||
|
|
|
|||
|
|
Entrada conceptual:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
ModuleManifest[]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Salida conceptual:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
export interface SettingsRegistry {
|
|||
|
|
sections: SettingsSection[];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export interface SettingsSection {
|
|||
|
|
id: string;
|
|||
|
|
labelKey: string;
|
|||
|
|
order: number;
|
|||
|
|
entries: SettingsEntry[];
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 17. Responsabilidades del registry
|
|||
|
|
|
|||
|
|
Debe:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
recoger contribuciones
|
|||
|
|
fusionar secciones comunes
|
|||
|
|
validar IDs
|
|||
|
|
detectar conflictos
|
|||
|
|
ordenar secciones
|
|||
|
|
ordenar entradas
|
|||
|
|
filtrar entradas no disponibles por permisos
|
|||
|
|
producir un resultado determinista
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
No debe:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
consultar APIs de negocio
|
|||
|
|
cargar configuración
|
|||
|
|
persistir valores
|
|||
|
|
renderizar formularios
|
|||
|
|
resolver reglas fiscales
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 18. Registro declarativo, no imperativo
|
|||
|
|
|
|||
|
|
Preferir:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
export const manifest = {
|
|||
|
|
settings: ...,
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
frente a:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
registerSetting(...);
|
|||
|
|
registerSetting(...);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Ventajas:
|
|||
|
|
|
|||
|
|
- evita side effects durante imports;
|
|||
|
|
- facilita validación;
|
|||
|
|
- hace visible la superficie pública del módulo;
|
|||
|
|
- permite inspección;
|
|||
|
|
- permite ordenar antes de renderizar;
|
|||
|
|
- encaja con una arquitectura basada en manifests.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 19. Lazy loading
|
|||
|
|
|
|||
|
|
El metadata usado para construir la navegación debe ser ligero.
|
|||
|
|
|
|||
|
|
El shell no debería necesitar importar toda una página para saber que existe una opción.
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
manifest metadata
|
|||
|
|
≠
|
|||
|
|
page implementation
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
El routing del módulo puede mantener lazy loading si la infraestructura actual ya lo soporta.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 20. Layout
|
|||
|
|
|
|||
|
|
Modelo recomendado:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
┌───────────────────────────────────────────────────────────┐
|
|||
|
|
│ Configuración │
|
|||
|
|
│ Configura el comportamiento de la empresa activa │
|
|||
|
|
├─────────────────┬─────────────────────────────────────────┤
|
|||
|
|
│ │ │
|
|||
|
|
│ Empresa │ │
|
|||
|
|
│ Datos │ │
|
|||
|
|
│ │ contenido del módulo │
|
|||
|
|
│ Facturación │ │
|
|||
|
|
│ VeriFactu │ │
|
|||
|
|
│ Series │ │
|
|||
|
|
│ Certificados │ │
|
|||
|
|
│ │ │
|
|||
|
|
│ Integraciones │ │
|
|||
|
|
│ │ │
|
|||
|
|
└─────────────────┴─────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
El panel izquierdo pertenece al framework.
|
|||
|
|
|
|||
|
|
El área de contenido pertenece a la ruta del módulo.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 21. Sistema visual
|
|||
|
|
|
|||
|
|
El shell debe reutilizar los componentes estructurales Rdx existentes cuando sean aplicables.
|
|||
|
|
|
|||
|
|
Por ejemplo:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
RdxPageContainer
|
|||
|
|
RdxPageHeader
|
|||
|
|
RdxPageStack
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
La infraestructura dependiente de routing, manifests, permisos o empresa activa no debe vivir en `packages/rdx-ui`.
|
|||
|
|
|
|||
|
|
`rdx-ui` puede contener únicamente piezas visuales genéricas y desacopladas.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 22. Navegación principal
|
|||
|
|
|
|||
|
|
La aplicación debe exponer una sola entrada:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
Configuración
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
El menú principal no debe contener directamente:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
VeriFactu
|
|||
|
|
Series
|
|||
|
|
Certificados
|
|||
|
|
Configuración de clientes
|
|||
|
|
...
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Estas opciones aparecen dentro de `/settings`.
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
App navigation
|
|||
|
|
└── Configuración
|
|||
|
|
└── SettingsNavigation
|
|||
|
|
├── Empresa
|
|||
|
|
├── Facturación
|
|||
|
|
├── ...
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 23. Empresa activa
|
|||
|
|
|
|||
|
|
Todo `/settings` debe operar sobre la empresa activa.
|
|||
|
|
|
|||
|
|
No debe introducirse un segundo selector o una segunda fuente de verdad.
|
|||
|
|
|
|||
|
|
Conceptualmente:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
active company changes
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
Settings context changes
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
module queries resolve data for new company
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
La implementación debe reutilizar la infraestructura de empresa activa existente en el ERP.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 24. Cambio de empresa activa
|
|||
|
|
|
|||
|
|
Una página de configuración no debe conservar datos pertenecientes a la empresa anterior después de cambiar la empresa activa.
|
|||
|
|
|
|||
|
|
Debe resolverse mediante la infraestructura ya existente de:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
company context
|
|||
|
|
headers
|
|||
|
|
query keys
|
|||
|
|
query invalidation
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
No mediante estado duplicado dentro del framework Settings.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 25. Persistencia
|
|||
|
|
|
|||
|
|
Regla fundamental:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
Settings framework
|
|||
|
|
≠
|
|||
|
|
Settings persistence
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
No crear únicamente por este sistema:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
settings table
|
|||
|
|
settings(key, value)
|
|||
|
|
GenericSettingsRepository
|
|||
|
|
useSettings()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Cada dominio conserva su propia persistencia y validación.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 26. Formularios
|
|||
|
|
|
|||
|
|
Cada setting mantiene sus propios formularios.
|
|||
|
|
|
|||
|
|
Ejemplo:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
VerifactuSettingsPage
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
VerifactuSettingsEditor
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
React Hook Form
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Settings no proporciona un `GenericSettingsForm`.
|
|||
|
|
|
|||
|
|
Los formularios deben seguir las convenciones ya consolidadas del ERP para fields y React Hook Form.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 27. Guardado
|
|||
|
|
|
|||
|
|
No debe existir un botón global:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
Guardar toda la configuración del ERP
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Cada entrada mantiene su propia transacción de guardado.
|
|||
|
|
|
|||
|
|
Ejemplos:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
/settings/billing/verifactu
|
|||
|
|
→ Guardar VeriFactu
|
|||
|
|
|
|||
|
|
/settings/company/details
|
|||
|
|
→ Guardar datos de empresa
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Esto evita mezclar dominios y transacciones.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 28. Errores
|
|||
|
|
|
|||
|
|
El shell gestiona únicamente errores estructurales del sistema Settings.
|
|||
|
|
|
|||
|
|
Ejemplos:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
ruta inválida
|
|||
|
|
entry inexistente
|
|||
|
|
acceso no permitido al subtree
|
|||
|
|
error de render del subtree
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
El módulo sigue gestionando errores de carga/guardado de su configuración mediante los patrones generales del ERP.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 29. Permisos
|
|||
|
|
|
|||
|
|
Una entrada puede declarar opcionalmente:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
permission?: string;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
El shell reutiliza la infraestructura central de autorización para decidir si la entrada está disponible.
|
|||
|
|
|
|||
|
|
Ejemplos conceptuales:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
VeriFactu
|
|||
|
|
→ manage_verifactu_settings
|
|||
|
|
|
|||
|
|
Certificados
|
|||
|
|
→ manage_company_certificates
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Settings no interpreta el permiso ni implementa autorización propia.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 30. Ocultar vs deshabilitar
|
|||
|
|
|
|||
|
|
Para una opción de Settings sin permiso, la decisión inicial es:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
no mostrarla
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
La navegación representa capacidades administrativas disponibles.
|
|||
|
|
|
|||
|
|
Esto no sustituye la autorización backend.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 31. Seguridad
|
|||
|
|
|
|||
|
|
Ocultar una entrada del menú no constituye autorización.
|
|||
|
|
|
|||
|
|
El backend debe seguir validando:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
usuario
|
|||
|
|
permiso
|
|||
|
|
empresa activa
|
|||
|
|
operación solicitada
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
El frontend únicamente adapta la experiencia de navegación.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 32. i18n
|
|||
|
|
|
|||
|
|
Los manifests deben declarar claves, no textos hardcodeados:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
labelKey
|
|||
|
|
descriptionKey
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Ejemplo:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
labelKey: "customerInvoices.settings.verifactu.title";
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
El módulo propietario mantiene sus traducciones.
|
|||
|
|
|
|||
|
|
Las secciones compartidas deben utilizar claves semánticamente compatibles.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 33. Ordenación
|
|||
|
|
|
|||
|
|
Cada sección y entrada puede declarar:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
order?: number;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Ejemplo:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
100 Empresa
|
|||
|
|
200 Facturación
|
|||
|
|
300 Ventas
|
|||
|
|
400 Compras
|
|||
|
|
500 Integraciones
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Dentro de Facturación:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
100 VeriFactu
|
|||
|
|
200 Series documentales
|
|||
|
|
300 Certificados
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
No usar orden alfabético como criterio principal porque los labels dependen del idioma.
|
|||
|
|
|
|||
|
|
Si `order` no existe, el resultado debe seguir siendo determinista mediante un valor por defecto y un desempate estable por `id`.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 34. Conflictos
|
|||
|
|
|
|||
|
|
El registry debe detectar al menos en desarrollo:
|
|||
|
|
|
|||
|
|
### Section ID conflict
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
mismo id
|
|||
|
|
labels incompatibles
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Entry ID conflict
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
misma identidad registrada más de una vez
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Path conflict
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
dos entries incompatibles apuntan a la misma ruta
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Missing section
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
entry apunta a una section inexistente
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Los conflictos no deben resolverse silenciosamente.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 35. Responsive
|
|||
|
|
|
|||
|
|
Desktop:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
navegación lateral + contenido
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Viewport estrecho:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
navegación adaptada
|
|||
|
|
→ selección/listado de settings
|
|||
|
|
→ contenido
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Debe mantenerse el mismo registry y las mismas rutas.
|
|||
|
|
|
|||
|
|
No crear dos sistemas de Settings diferentes.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 36. Accesibilidad
|
|||
|
|
|
|||
|
|
La navegación debe usar semántica real:
|
|||
|
|
|
|||
|
|
```html
|
|||
|
|
<nav>
|
|||
|
|
<a>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Requisitos mínimos:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
focus-visible
|
|||
|
|
aria-current="page"
|
|||
|
|
uso completo con teclado
|
|||
|
|
jerarquía correcta de headings
|
|||
|
|
estado activo perceptible sin depender solo del color
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 37. Deep links
|
|||
|
|
|
|||
|
|
Cada configuración debe ser direccionable directamente.
|
|||
|
|
|
|||
|
|
Ejemplo:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
/settings/billing/verifactu
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Debe funcionar con:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
refresh
|
|||
|
|
deep-link
|
|||
|
|
bookmark
|
|||
|
|
navegación interna
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
El estado activo se deriva de la URL, no de un `setSelectedSetting(...)` global.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 38. Cambios sin guardar
|
|||
|
|
|
|||
|
|
El shell no debe inspeccionar ni gestionar globalmente formularios dirty de los módulos.
|
|||
|
|
|
|||
|
|
Cada página propietaria debe usar el mecanismo estándar del ERP para:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
unsaved changes
|
|||
|
|
navigation guard
|
|||
|
|
cancel
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 39. Queries y caché
|
|||
|
|
|
|||
|
|
Cada módulo conserva sus query keys y estrategia de caché.
|
|||
|
|
|
|||
|
|
El framework no debe crear una query genérica:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
["settings", ...]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
para todos los dominios.
|
|||
|
|
|
|||
|
|
Ejemplos:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
VeriFactu settings query key
|
|||
|
|
→ customer-invoices
|
|||
|
|
|
|||
|
|
Document Series query keys
|
|||
|
|
→ document-series
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 40. Caso piloto: VeriFactu
|
|||
|
|
|
|||
|
|
VeriFactu será el primer consumidor real del framework.
|
|||
|
|
|
|||
|
|
Conceptualmente:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
customer-invoices
|
|||
|
|
└── manifest
|
|||
|
|
└── settings
|
|||
|
|
├── section: billing
|
|||
|
|
└── entry: verifactu
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Ruta objetivo:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
/settings/billing/verifactu
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
La ubicación física de su implementación debe definirse después de auditar el módulo real.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 41. Independencia entre Settings y módulos
|
|||
|
|
|
|||
|
|
Debe cumplirse:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
eliminar customer-invoices
|
|||
|
|
→ desaparecen automáticamente sus settings
|
|||
|
|
|
|||
|
|
Settings continúa funcionando
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Y también:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
añadir módulo nuevo
|
|||
|
|
→ puede aportar Settings
|
|||
|
|
→ sin modificar SettingsPage
|
|||
|
|
→ sin modificar SettingsNavigation
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Este es el principal criterio de aceptación del sistema.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 42. Independencia entre módulos
|
|||
|
|
|
|||
|
|
Un módulo no debe importar otro únicamente para registrar sus settings.
|
|||
|
|
|
|||
|
|
Incorrecto:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
customer-invoices
|
|||
|
|
→ importa document-series settings
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Correcto:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
customer-invoices manifest ─┐
|
|||
|
|
├→ registry
|
|||
|
|
document-series manifest ───┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 43. Anti-patterns prohibidos
|
|||
|
|
|
|||
|
|
### Configuración central hardcoded
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
const SETTINGS = [
|
|||
|
|
VerifactuSettings,
|
|||
|
|
DocumentSeriesSettings,
|
|||
|
|
CertificateSettings,
|
|||
|
|
];
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Registro central de componentes de dominio
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
{
|
|||
|
|
component: VerifactuSettingsPage,
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
como API principal del registry.
|
|||
|
|
|
|||
|
|
### Persistencia genérica indiscriminada
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
settings
|
|||
|
|
├── key
|
|||
|
|
└── value
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
para almacenar configuraciones de dominios diferentes.
|
|||
|
|
|
|||
|
|
### Switch central
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
switch (setting.id) {
|
|||
|
|
case "verifactu":
|
|||
|
|
case "certificates":
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Imports cruzados por Settings
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
apps/web/settings
|
|||
|
|
→ importa páginas concretas de todos los módulos
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
si el sistema modular de routing puede evitarlos.
|
|||
|
|
|
|||
|
|
### Routing o manifests en `rdx-ui`
|
|||
|
|
|
|||
|
|
No permitido.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 44. Extensiones futuras posibles
|
|||
|
|
|
|||
|
|
Solo cuando aparezca necesidad real:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
buscador de configuración
|
|||
|
|
badges de estado
|
|||
|
|
feature flags
|
|||
|
|
keywords
|
|||
|
|
settings favoritos
|
|||
|
|
navegación reciente
|
|||
|
|
secciones anidadas
|
|||
|
|
links externos
|
|||
|
|
estado "requiere atención"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
No forman parte de V1.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 45. Criterios de aceptación
|
|||
|
|
|
|||
|
|
El diseño se considera correctamente implementado si:
|
|||
|
|
|
|||
|
|
1. Añadir un setting nuevo no modifica el shell.
|
|||
|
|
2. Eliminar un módulo elimina automáticamente sus settings.
|
|||
|
|
3. Varios módulos pueden contribuir a la misma sección.
|
|||
|
|
4. Cada setting tiene URL propia.
|
|||
|
|
5. El módulo conserva control sobre sus datos y UI.
|
|||
|
|
6. Settings no persiste datos de negocio.
|
|||
|
|
7. `rdx-ui` no conoce routing ni manifests.
|
|||
|
|
8. No existen imports cruzados entre módulos por Settings.
|
|||
|
|
9. La empresa activa es el único scope de `/settings`.
|
|||
|
|
10. `/account` permanece independiente.
|
|||
|
|
11. El resultado del registry es determinista.
|
|||
|
|
12. Los conflictos de metadata se detectan en desarrollo.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 46. Fases de implementación recomendadas
|
|||
|
|
|
|||
|
|
### Fase 0 — Auditoría
|
|||
|
|
|
|||
|
|
Investigar sin modificar código:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
manifest actual
|
|||
|
|
module registry
|
|||
|
|
routing composition
|
|||
|
|
sidebar
|
|||
|
|
active company
|
|||
|
|
permissions
|
|||
|
|
i18n
|
|||
|
|
layouts
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Fase 1 — Contrato de contribuciones
|
|||
|
|
|
|||
|
|
Añadir únicamente:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
module manifest
|
|||
|
|
→ settings metadata
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
y el registry correspondiente.
|
|||
|
|
|
|||
|
|
### Fase 2 — Shell de Settings
|
|||
|
|
|
|||
|
|
Implementar:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
/settings
|
|||
|
|
SettingsLayout
|
|||
|
|
SettingsNavigation
|
|||
|
|
agrupación por sección
|
|||
|
|
routing
|
|||
|
|
permissions
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Sin introducir todavía lógica de dominios concretos.
|
|||
|
|
|
|||
|
|
### Fase 3 — Consumidor piloto
|
|||
|
|
|
|||
|
|
Integrar VeriFactu como primera contribución real.
|
|||
|
|
|
|||
|
|
### Fase 4 — Segundo módulo
|
|||
|
|
|
|||
|
|
Integrar una configuración aportada por otro módulo, preferentemente `document-series`, para validar que dos módulos contribuyen a `billing` sin conocerse.
|
|||
|
|
|
|||
|
|
### Fase 5 — Consolidación
|
|||
|
|
|
|||
|
|
Solo después revisar abstracciones comunes, tests y documentación del UI Kit.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 47. Tests mínimos
|
|||
|
|
|
|||
|
|
### Registry
|
|||
|
|
|
|||
|
|
Debe comprobar:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
fusiona secciones
|
|||
|
|
ordena entries
|
|||
|
|
detecta IDs duplicados
|
|||
|
|
detecta conflictos
|
|||
|
|
respeta permisos
|
|||
|
|
resultado determinista
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Routing
|
|||
|
|
|
|||
|
|
Debe comprobar:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
deep-link directo
|
|||
|
|
ruta inexistente
|
|||
|
|
navegación entre entries
|
|||
|
|
refresh
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### UI
|
|||
|
|
|
|||
|
|
Con Testing Library:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
navegación accesible
|
|||
|
|
aria-current
|
|||
|
|
entry visible/no visible por permisos
|
|||
|
|
render del contenido de la route
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
No testear implementación interna de cada módulo desde Settings.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 48. Decisiones consolidadas
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
/settings
|
|||
|
|
→ configuración de la empresa activa
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
/account
|
|||
|
|
→ configuración personal del usuario
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
Una única entrada "Configuración"
|
|||
|
|
en la navegación principal.
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
Varios módulos pueden contribuir
|
|||
|
|
a una misma sección.
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
La aplicación base no conoce
|
|||
|
|
los settings específicos de los módulos.
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
Los módulos declaran sus settings
|
|||
|
|
mediante metadata.
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
Settings registra navegación,
|
|||
|
|
no implementaciones React.
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
Cada dominio conserva
|
|||
|
|
su propia persistencia.
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
Settings no pertenece a rdx-ui.
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
VeriFactu será el primer consumidor real.
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 49. Pendientes que requieren auditoría
|
|||
|
|
|
|||
|
|
No deben cerrarse sin inspeccionar el repositorio:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
shape exacto de manifest.ts
|
|||
|
|
ubicación física del SettingsRegistry
|
|||
|
|
forma de agregar manifests
|
|||
|
|
routing modular actual
|
|||
|
|
sistema real de permisos
|
|||
|
|
fuente concreta de active company
|
|||
|
|
API de traducciones en manifests
|
|||
|
|
estrategia de lazy routes
|
|||
|
|
ruta exacta del SettingsLayout
|
|||
|
|
mecanismo de ErrorBoundary del shell
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 50. Regla mental final
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
App
|
|||
|
|
→ conoce Settings
|
|||
|
|
|
|||
|
|
Settings
|
|||
|
|
→ conoce contribuciones
|
|||
|
|
|
|||
|
|
Contribución
|
|||
|
|
→ conoce metadata
|
|||
|
|
|
|||
|
|
Módulo
|
|||
|
|
→ conoce dominio
|
|||
|
|
|
|||
|
|
Ruta
|
|||
|
|
→ conecta Settings con el módulo
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Criterio principal:
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
Añadir una opción de configuración desde un módulo
|
|||
|
|
NO debe requerir modificar el shell de Settings.
|
|||
|
|
```
|