@nocios/crudify-ui 1.3.1 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,344 +0,0 @@
1
- # ESPECIFICACIÓN TÉCNICA: CrudifyDataProvider
2
-
3
- ## 🎯 OBJETIVO
4
-
5
- Crear un provider unificado que encapsule toda la funcionalidad de autenticación, gestión de tokens y operaciones CRUD, eliminando la duplicación de código entre crudia-ui y crudify-ui, mientras mantiene **100% de compatibilidad** con el sistema de producción.
6
-
7
- ## 🔍 ANÁLISIS DEL SISTEMA ACTUAL
8
-
9
- ### CRUDIA-UI (Sistema de Producción que FUNCIONA)
10
-
11
- **Arquitectura de Providers:**
12
- ```
13
- GlobalNotificationProvider
14
- ├── AppProvider (configuración desde ENV/cookies)
15
- ├── DataProvider (inicialización de crudify + JWT)
16
- ├── UIProvider
17
- ├── DashboardProvider
18
- └── Components
19
- ```
20
-
21
- **Flujo de Inicialización Crítico:**
22
- 1. `AppProvider` lee configuración de ENV vars + cookies
23
- 2. `DataProvider` inicializa crudify globalmente con `publicApiKey` y `env`
24
- 3. `DataProvider` maneja JWT tokens con `secureSessionStorage`
25
- 4. `DataProvider` configura interceptores para manejo de errores
26
- 5. Componentes usan `crudify` directamente o via `useCrudifyWithNotifications`
27
-
28
- **Puntos de Integración Críticos:**
29
- - `secureSessionStorage` con key `"authToken"`
30
- - `crudify.config(env)` + `crudify.init(publicApiKey, "none")`
31
- - `crudify.setToken(token)` sincronizado con storage
32
- - Interceptores para manejo de tokens expirados
33
- - Sistema de notificaciones integrado
34
-
35
- ### CRUDIFY-UI (Sistema que Falla)
36
-
37
- **Problemas Identificados:**
38
- 1. **Doble Inicialización**: `DataProvider` + `CrudifyProvider`
39
- 2. **Storage Incompatible**: No usa `secureSessionStorage`
40
- 3. **Falta Provider Global**: Solo `JWTSessionProvider` local
41
- 4. **Error**: "Crudify: Not initialized" por conflictos
42
-
43
- ## 🏗️ DISEÑO DEL NUEVO SISTEMA
44
-
45
- ### PRINCIPIOS DE DISEÑO
46
-
47
- 1. **Compatibilidad Total**: No romper crudia-ui (producción)
48
- 2. **Encapsulación**: Todo en npm-crudify-ui, sin duplicación
49
- 3. **Configuración Flexible**: ENV vars, cookies, o parámetros
50
- 4. **Error Handling Robusto**: Fallas graduales, no cascada
51
- 5. **API Simple**: Hooks fáciles de usar
52
-
53
- ### ARQUITECTURA PROPUESTA
54
-
55
- ```
56
- CrudifyDataProvider (NUEVO)
57
- ├── ConfigurationManager (lee ENV + cookies)
58
- ├── CrudifyInitializer (inicializa crudify UNA SOLA VEZ)
59
- ├── TokenManager (JWT + secureSessionStorage)
60
- ├── ErrorInterceptor (manejo de errores automático)
61
- ├── NotificationSystem (opcional)
62
- └── Hooks Exportados:
63
- ├── useCrudifyAuth (estado de autenticación)
64
- ├── useCrudifyUser (datos del usuario + perfil)
65
- ├── useCrudifyData (operaciones CRUD)
66
- └── useCrudifyConfig (configuración actual)
67
- ```
68
-
69
- ## 📋 ESPECIFICACIÓN DETALLADA
70
-
71
- ### 1. CONFIGURACIÓN
72
-
73
- **Prioridad de Configuración:**
74
- ```typescript
75
- interface CrudifyConfig {
76
- env?: "dev" | "stg" | "prod"
77
- publicApiKey?: string
78
- loginActions?: string[]
79
- appName?: string
80
- logo?: string
81
- colors?: Record<string, string>
82
- }
83
-
84
- // Orden de prioridad:
85
- // 1. Props explícitas al Provider
86
- // 2. Variables de entorno (VITE_TEST_*)
87
- // 3. Cookies (para multi-tenant)
88
- // 4. Error si falta publicApiKey
89
- ```
90
-
91
- **Variables de Entorno Soportadas:**
92
- - `VITE_TEST_ENV`
93
- - `VITE_TEST_PUBLIC_API_KEY`
94
- - `VITE_TEST_LOGIN_ACTIONS`
95
-
96
- **Cookies Multi-tenant:**
97
- - `publicApiKey`
98
- - `environment`
99
- - `appName`
100
- - `loginActions`
101
- - `logo`
102
- - `colors`
103
-
104
- ### 2. GESTIÓN DE TOKENS
105
-
106
- **Storage Strategy:**
107
- ```typescript
108
- // COMPATIBILIDAD TOTAL con crudia-ui
109
- class SecureSessionStorage {
110
- private readonly TOKEN_KEY = "authToken"
111
-
112
- setToken(token: string): void
113
- getToken(): string | null
114
- removeItem(key: string): void
115
- migrateFromLocalStorage(key: string): void
116
- clear(): void
117
- }
118
- ```
119
-
120
- **JWT Management:**
121
- ```typescript
122
- interface TokenManager {
123
- // Sincronización automática: storage <-> crudify
124
- setToken(token: string | null): void
125
- getToken(): string | null
126
- parseToken(): JWTPayload | null
127
- isTokenValid(): boolean
128
- getTokenExpiration(): Date | null
129
-
130
- // Auto-cleanup en caso de expiración
131
- setupExpirationCheck(): void
132
- }
133
- ```
134
-
135
- ### 3. INICIALIZACIÓN DE CRUDIFY
136
-
137
- **Inicialización Única y Robusta:**
138
- ```typescript
139
- class CrudifyInitializer {
140
- private static isInitialized = false
141
- private static initializationPromise: Promise<void> | null = null
142
-
143
- static async initialize(config: CrudifyConfig): Promise<void> {
144
- // Prevenir doble inicialización
145
- if (this.isInitialized) return
146
- if (this.initializationPromise) return this.initializationPromise
147
-
148
- this.initializationPromise = this.performInitialization(config)
149
- await this.initializationPromise
150
- this.isInitialized = true
151
- }
152
-
153
- private static async performInitialization(config: CrudifyConfig): Promise<void> {
154
- await crudify.config(config.env || 'prod')
155
- await crudify.init(config.publicApiKey!, 'none')
156
-
157
- // Verificar que los métodos estén disponibles
158
- if (typeof crudify.readItems !== 'function') {
159
- throw new Error('Crudify not properly initialized')
160
- }
161
- }
162
- }
163
- ```
164
-
165
- ### 4. HOOKS PÚBLICOS
166
-
167
- **useCrudifyAuth - Estado de Autenticación:**
168
- ```typescript
169
- interface UseCrudifyAuthReturn {
170
- // Estado básico
171
- isAuthenticated: boolean
172
- loading: boolean
173
- error: string | null
174
-
175
- // Datos del token
176
- token: string | null
177
- user: JWTPayload | null // Datos del JWT
178
- tokenExpiration: Date | null
179
-
180
- // Acciones
181
- setToken: (token: string | null) => void
182
- logout: () => void
183
- refreshToken?: () => Promise<void> // Futuro
184
- }
185
- ```
186
-
187
- **useCrudifyUser - Datos del Usuario:**
188
- ```typescript
189
- interface UseCrudifyUserReturn {
190
- // Datos básicos del JWT
191
- userEmail: string | null
192
- userId: string | null
193
- userIdentifier: string | null
194
-
195
- // Perfil completo desde BD
196
- userProfile: UserProfile | null
197
- profileLoading: boolean
198
- profileError: string | null
199
-
200
- // Datos extendidos formateados
201
- extendedData: {
202
- fullProfile: UserProfile | null
203
- totalFields: number
204
- displayData: Record<string, any>
205
- }
206
-
207
- // Acciones
208
- refreshProfile: () => Promise<void>
209
- clearProfile: () => void
210
- }
211
- ```
212
-
213
- **useCrudifyData - Operaciones CRUD:**
214
- ```typescript
215
- interface UseCrudifyDataReturn {
216
- // Operaciones básicas
217
- readItems: (moduleKey: string, filter?: object, options?: any) => Promise<CrudifyResponse>
218
- readItem: (moduleKey: string, filter: object, options?: any) => Promise<CrudifyResponse>
219
- createItem: (moduleKey: string, data: object, options?: any) => Promise<CrudifyResponse>
220
- updateItem: (moduleKey: string, data: object, options?: any) => Promise<CrudifyResponse>
221
- deleteItem: (moduleKey: string, id: string, options?: any) => Promise<CrudifyResponse>
222
-
223
- // Operaciones avanzadas
224
- transaction: (operations: any[], options?: any) => Promise<CrudifyResponse>
225
- login: (email: string, password: string) => Promise<CrudifyResponse>
226
-
227
- // Estado
228
- isInitialized: boolean
229
- initializationError: string | null
230
- }
231
- ```
232
-
233
- **useCrudifyConfig - Configuración:**
234
- ```typescript
235
- interface UseCrudifyConfigReturn {
236
- config: CrudifyConfig
237
- isConfigured: boolean
238
- configError: string | null
239
-
240
- // Para debugging
241
- configSource: 'props' | 'env' | 'cookies'
242
- rawConfig: Record<string, any>
243
- }
244
- ```
245
-
246
- ## 🔄 ESTRATEGIA DE MIGRACIÓN
247
-
248
- ### FASE 1: Implementación (No Rompe Nada)
249
-
250
- 1. **Crear CrudifyDataProvider** manteniendo APIs existentes
251
- 2. **Mantener CrudifyProvider** para compatibilidad
252
- 3. **Agregar hooks nuevos** sin afectar los existentes
253
- 4. **Testing exhaustivo** en ambos sistemas
254
-
255
- ### FASE 2: Migración Gradual
256
-
257
- 1. **Actualizar crudify-ui** para usar CrudifyDataProvider
258
- 2. **Mantener crudia-ui** sin cambios (producción)
259
- 3. **Documentar migración** opcional para crudia-ui
260
-
261
- ### FASE 3: Consolidación (Futuro)
262
-
263
- 1. **Deprecar APIs antiguas** con warnings
264
- 2. **Migrar crudia-ui** opcionalmente
265
- 3. **Limpiar código** redundante
266
-
267
- ## 🛡️ GARANTÍAS DE COMPATIBILIDAD
268
-
269
- ### CRUDIA-UI (Producción)
270
- - ✅ **API actual intacta**: Todos los imports/exports existentes
271
- - ✅ **DataProvider compatible**: Mismo comportamiento exacto
272
- - ✅ **Storage compatible**: Misma key `"authToken"`
273
- - ✅ **Interceptores**: Mismo manejo de errores
274
- - ✅ **Notificaciones**: Sistema existente sin cambios
275
-
276
- ### CRUDIFY-UI (Desarrollo)
277
- - ✅ **Migración simple**: Un solo Provider reemplaza todo
278
- - ✅ **Hooks simples**: APIs más fáciles de usar
279
- - ✅ **Configuración flexible**: ENV + cookies + props
280
- - ✅ **Error handling**: Más robusto que el actual
281
-
282
- ## 🧪 PLAN DE TESTING
283
-
284
- ### Tests de Compatibilidad
285
- 1. **crudia-ui**: Login, operaciones CRUD, manejo de errores
286
- 2. **npm-crudify-ui**: APIs existentes sin cambios
287
- 3. **crudify-ui**: Nueva implementación funcional
288
-
289
- ### Tests de Integración
290
- 1. **Doble inicialización**: Sin conflictos
291
- 2. **Storage**: Compatibilidad entre sistemas
292
- 3. **Tokens**: Manejo correcto de JWT
293
- 4. **Errores**: Graceful degradation
294
-
295
- ### Tests de Regresión
296
- 1. **Multi-tenant**: Cookies funcionando
297
- 2. **ENV vars**: Configuración correcta
298
- 3. **Login flow**: End-to-end completo
299
- 4. **User profile**: Datos cargados correctamente
300
-
301
- ## 📚 DOCUMENTACIÓN
302
-
303
- ### Para Desarrolladores
304
- 1. **Guía de migración** desde sistema actual
305
- 2. **API reference** completa
306
- 3. **Ejemplos de uso** para cada hook
307
- 4. **Troubleshooting** común
308
-
309
- ### Para Producción
310
- 1. **No-breaking changes** garantizados
311
- 2. **Rollback plan** si es necesario
312
- 3. **Monitoring** de errores
313
- 4. **Performance** sin degradación
314
-
315
- ## 🚀 CRONOGRAMA
316
-
317
- ### Semana 1: Implementación Core
318
- - [ ] ConfigurationManager
319
- - [ ] CrudifyInitializer
320
- - [ ] TokenManager
321
- - [ ] Tests unitarios
322
-
323
- ### Semana 2: Hooks y Provider
324
- - [ ] CrudifyDataProvider
325
- - [ ] useCrudifyAuth
326
- - [ ] useCrudifyUser
327
- - [ ] useCrudifyData
328
-
329
- ### Semana 3: Integración y Testing
330
- - [ ] Migración crudify-ui
331
- - [ ] Tests de compatibilidad crudia-ui
332
- - [ ] Tests end-to-end
333
- - [ ] Documentación
334
-
335
- ### Semana 4: Validación y Deploy
336
- - [ ] Testing exhaustivo
337
- - [ ] Code review
338
- - [ ] Deploy y monitoring
339
- - [ ] Documentación final
340
-
341
- ---
342
-
343
- **RIESGO: MÍNIMO** - El diseño mantiene 100% compatibilidad hacia atrás
344
- **BENEFICIO: MÁXIMO** - Elimina duplicación y simplifica enormemente el desarrollo futuro
package/example-app.tsx DELETED
@@ -1,197 +0,0 @@
1
- // =============================
2
- // EXAMPLE APP - REFRESH TOKEN PATTERN
3
- // =============================
4
-
5
- /**
6
- * Ejemplo completo de aplicación usando el Refresh Token Pattern
7
- * Demuestra todas las características nuevas de crudify-ui v1.2+
8
- */
9
-
10
- import React from 'react';
11
- import ReactDOM from 'react-dom/client';
12
- import { ThemeProvider, createTheme } from '@mui/material/styles';
13
- import { CssBaseline, Container, AppBar, Toolbar, Typography, Box } from '@mui/material';
14
- import {
15
- SessionProvider,
16
- LoginComponent,
17
- SessionStatus,
18
- SessionDebugInfo,
19
- useSessionContext,
20
- ProtectedRoute
21
- } from '@nocios/crudify-ui';
22
-
23
- const theme = createTheme();
24
-
25
- // Componente de aplicación principal
26
- function App() {
27
- return (
28
- <ThemeProvider theme={theme}>
29
- <CssBaseline />
30
-
31
- {/* Envolver toda la app con SessionProvider */}
32
- <SessionProvider
33
- options={{
34
- autoRestore: true, // Restaurar sesión automáticamente
35
- enableLogging: true, // Logs para debug
36
- onSessionExpired: () => { // Callback cuando expira la sesión
37
- console.log('Session expired - redirecting to login');
38
- // Aquí podrías hacer redirect, mostrar modal, etc.
39
- },
40
- onSessionRestored: (tokens) => {
41
- console.log('Session restored successfully:', tokens);
42
- }
43
- }}
44
- >
45
- <AppContent />
46
- </SessionProvider>
47
- </ThemeProvider>
48
- );
49
- }
50
-
51
- // Contenido principal de la aplicación
52
- function AppContent() {
53
- return (
54
- <>
55
- {/* App Bar */}
56
- <AppBar position="static">
57
- <Toolbar>
58
- <Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
59
- Crudify Refresh Token Demo
60
- </Typography>
61
- <SessionStatus />
62
- </Toolbar>
63
- </AppBar>
64
-
65
- {/* Contenido principal */}
66
- <Container maxWidth="lg" sx={{ mt: 4, mb: 4 }}>
67
- <LoginComponent />
68
-
69
- {/* Área protegida - solo visible si está autenticado */}
70
- <ProtectedRoute fallback={null}>
71
- <ProtectedArea />
72
- </ProtectedRoute>
73
-
74
- {/* Debug info (solo en desarrollo) */}
75
- {process.env.NODE_ENV === 'development' && (
76
- <SessionDebugInfo />
77
- )}
78
- </Container>
79
- </>
80
- );
81
- }
82
-
83
- // Área protegida de la aplicación
84
- function ProtectedArea() {
85
- const { refreshTokens, isExpiringSoon } = useSessionContext();
86
-
87
- return (
88
- <Box sx={{ mt: 4, p: 3, bgcolor: 'background.paper', borderRadius: 1 }}>
89
- <Typography variant="h5" gutterBottom>
90
- Protected Area 🔒
91
- </Typography>
92
-
93
- <Typography variant="body1" paragraph>
94
- This content is only visible to authenticated users. The session is managed
95
- automatically with the Refresh Token Pattern.
96
- </Typography>
97
-
98
- {isExpiringSoon && (
99
- <Box sx={{ mb: 2, p: 2, bgcolor: 'warning.light', borderRadius: 1 }}>
100
- <Typography variant="body2">
101
- ⚠️ Your token is expiring soon, but don't worry - it will be refreshed automatically!
102
- </Typography>
103
- </Box>
104
- )}
105
-
106
- {/* Ejemplo de uso de CRUD operations */}
107
- <CrudOperationsExample />
108
- </Box>
109
- );
110
- }
111
-
112
- // Ejemplo de operaciones CRUD con auto-refresh
113
- function CrudOperationsExample() {
114
- const [data, setData] = React.useState(null);
115
- const [loading, setLoading] = React.useState(false);
116
- const [error, setError] = React.useState(null);
117
-
118
- // Importar crudify
119
- const crudify = React.useMemo(() => {
120
- // En una app real, ya estaría inicializado
121
- import('@nocios/crudify-browser').then(module => module.default);
122
- }, []);
123
-
124
- const fetchData = async () => {
125
- setLoading(true);
126
- setError(null);
127
-
128
- try {
129
- // Esta operación usará automáticamente el auto-refresh si es necesario
130
- const result = await crudify.getPermissions();
131
-
132
- if (result.success) {
133
- setData(result.data);
134
- } else {
135
- setError('Failed to fetch data: ' + JSON.stringify(result.errors));
136
- }
137
- } catch (err) {
138
- setError('Network error: ' + err.message);
139
- } finally {
140
- setLoading(false);
141
- }
142
- };
143
-
144
- return (
145
- <Box sx={{ mt: 3 }}>
146
- <Typography variant="h6" gutterBottom>
147
- CRUD Operations with Auto-Refresh
148
- </Typography>
149
-
150
- <button onClick={fetchData} disabled={loading}>
151
- {loading ? 'Loading...' : 'Fetch Permissions (Test Auto-Refresh)'}
152
- </button>
153
-
154
- {error && (
155
- <Box sx={{ mt: 2, p: 2, bgcolor: 'error.light', borderRadius: 1 }}>
156
- <Typography variant="body2" color="error">
157
- {error}
158
- </Typography>
159
- </Box>
160
- )}
161
-
162
- {data && (
163
- <Box sx={{ mt: 2, p: 2, bgcolor: 'success.light', borderRadius: 1 }}>
164
- <Typography variant="body2">
165
- ✅ Data fetched successfully! Auto-refresh is working.
166
- </Typography>
167
- <pre style={{ fontSize: '12px', marginTop: '8px' }}>
168
- {JSON.stringify(data, null, 2)}
169
- </pre>
170
- </Box>
171
- )}
172
- </Box>
173
- );
174
- }
175
-
176
- // =============================
177
- // BOOTSTRAP DE LA APLICACIÓN
178
- // =============================
179
-
180
- // Para usar este ejemplo:
181
- // 1. npm install @nocios/crudify-ui@^1.2.0
182
- // 2. Configurar crudify con tu API key antes de renderizar
183
- // 3. Renderizar la aplicación
184
-
185
- export default App;
186
-
187
- // Ejemplo de inicialización
188
- /*
189
- import { crudify } from '@nocios/crudify-ui';
190
-
191
- // Configurar crudify antes de renderizar la app
192
- await crudify.init('your-api-key', 'debug');
193
-
194
- // Renderizar la aplicación
195
- const root = ReactDOM.createRoot(document.getElementById('root')!);
196
- root.render(<App />);
197
- */