openprompt-lang 1.2.6 → 1.3.0

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.
Files changed (43) hide show
  1. package/README.md +62 -8
  2. package/docs/EMBEDDINGS.md +214 -0
  3. package/docs/FRAMEWORK.md +52 -0
  4. package/docs/ONBOARDING_WORKFLOW.md +151 -0
  5. package/docs/OPL-ERRORES.md +504 -0
  6. package/docs/OPL_ACADEMIC_ISSUES.md +158 -0
  7. package/docs/WEB_SCRAPER_PLAN.md +454 -0
  8. package/package.json +7 -1
  9. package/scripts/postinstall.js +37 -0
  10. package/src/cli/commands-knowledge.js +1 -0
  11. package/src/cli/commands-opl.js +79 -1
  12. package/src/cli/commands-work.js +3 -1
  13. package/src/cli/commands-workflow.js +125 -6
  14. package/src/commands/init-core.js +188 -12
  15. package/src/commands/init-existing.js +13 -6
  16. package/src/commands/init-helpers.js +20 -14
  17. package/src/commands/knowledge-ops.js +52 -0
  18. package/src/commands/opl-embeddings.js +556 -0
  19. package/src/commands/opl-help.js +26 -2
  20. package/src/commands/opl-search.js +106 -2
  21. package/src/commands/opl-webscrape.js +390 -0
  22. package/src/commands/work-context.js +17 -0
  23. package/src/commands/workflow/close/index.js +2 -1
  24. package/src/commands/workflow/delivery/index.js +4 -0
  25. package/src/commands/workflow/discovery/index.js +4 -0
  26. package/src/commands/workflow/epic-cli.js +192 -0
  27. package/src/commands/workflow/select.js +146 -0
  28. package/src/commands/workflow/specification/index.js +4 -0
  29. package/src/commands/workflow/sprint-cli.js +174 -0
  30. package/src/core/engine/sandbox.js +7 -3
  31. package/src/core/webscrape/analyzer.js +481 -0
  32. package/src/core/webscrape/deep-scraper.js +1027 -0
  33. package/src/core/workflow/epic-manager.js +845 -0
  34. package/src/core/workflow/gates.js +180 -1
  35. package/src/core/workflow/selector.js +707 -0
  36. package/src/embeddings/chunker.js +450 -0
  37. package/src/embeddings/embedder.js +431 -0
  38. package/src/embeddings/index-pipeline.js +320 -0
  39. package/src/embeddings/vector-store.js +505 -0
  40. package/src/mcp-plan-server.js +12 -5
  41. package/src/mcp-shared-state.js +25 -0
  42. package/src/mcp-refactor/mcp-server.js +0 -171
  43. package/src/mcp-server-backup.js +0 -1913
@@ -0,0 +1,504 @@
1
+ # 📋 Auditoría OPL — AppMobilSaaSEcommerce
2
+
3
+ > **Generado:** 2026-05-23
4
+ > **Propósito:** Documentar todos los errores, problemas de anotaciones, y deuda técnica encontrada en el proyecto para resolverlos sistemáticamente.
5
+
6
+ ---
7
+
8
+ ## 📊 Resumen del proyecto
9
+
10
+ | Aspecto | Valor |
11
+ |---------|-------|
12
+ | Stack | React 18 + Vite 6 + TypeScript 5.9 + Tailwind 3 |
13
+ | Mobile | Ionic 8 + Capacitor 7 (Android/iOS) |
14
+ | Backend | Supabase (Auth, DB, Realtime, Storage, Edge Functions) |
15
+ | Archivos totales | ~90+ archivos fuente |
16
+ | Componentes UI | 31 componentes de página + 49 shadcn/ui |
17
+ | Hooks | 10 hooks personalizados |
18
+ | Archivos con anotaciones OPL | **3 de 50+** (✅ `useOfflineQueue`, `useCapacitorLifecycle`, `DeliveryZones`, `pushNotifications`) |
19
+ | Archivos sin anotaciones OPL | **~46 archivos** |
20
+ | Tests unitarios | **0** |
21
+
22
+ ---
23
+
24
+ ## 🚨 CATEGORÍA 1: Anotaciones OPL faltantes
25
+
26
+ ### 1.1 — `src/App.tsx` — Sin anotaciones OPL
27
+ **Archivo:** `src/App.tsx` (266 líneas)
28
+
29
+ ```typescript
30
+ // @use(kind, contract, limit, deps)
31
+ // @kind(page)
32
+ // @contract(in: void -> out: JSX.Element)
33
+ // @limit(lines: 300, deps: 10)
34
+ // @deps(@external: [react, sonner, lucide-react], @internal: [
35
+ // ./components/Login, ./components/Dashboard, ./components/Catalog,
36
+ // ./components/Reports, ./components/BottomNav, ./components/Settings,
37
+ // ./components/Notifications, ./components/QueueModal,
38
+ // ./components/OfferExecutionModal, ./components/CalendarModal,
39
+ // ./components/OfflineRestrictionModal, ./components/PinPadModal,
40
+ // ./hooks/useAuth, ./hooks/useAppData, ./hooks/useOfflineQueue,
41
+ // ./hooks/useCapacitorLifecycle, ./hooks/useRealtimeSync,
42
+ // ./hooks/useProducts, ./hooks/useOrders, ./hooks/useOffers,
43
+ // ./hooks/useMetrics, ./services/pushNotifications
44
+ // ])
45
+ ```
46
+
47
+ ### 1.2 — `src/main.tsx` — Sin anotaciones OPL
48
+ **Archivo:** `src/main.tsx` (11 líneas)
49
+
50
+ ```typescript
51
+ // @use(kind, deps)
52
+ // @kind(entry)
53
+ // @deps(@external: [react-dom, @ionic/react], @internal: [./App])
54
+ ```
55
+
56
+ ### 1.3 — `src/hooks/useAuth.ts` — Sin anotaciones OPL
57
+ **Archivo:** `src/hooks/useAuth.ts` (98 líneas)
58
+
59
+ ```typescript
60
+ // @use(kind, contract, limit, deps)
61
+ // @kind(hook)
62
+ // @contract(in: void -> out: UseAuthReturn)
63
+ // @limit(lines: 100)
64
+ // @deps(@external: [react, sonner, @supabase/supabase-js], @internal: [../lib/supabase])
65
+ ```
66
+
67
+ ### 1.4 — `src/hooks/useAppData.ts` — Sin anotaciones OPL
68
+ **Archivo:** `src/hooks/useAppData.ts` (199 líneas)
69
+
70
+ ```typescript
71
+ // @use(kind, contract, limit, deps)
72
+ // @kind(hook)
73
+ // @contract(in: void -> out: UseAppDataReturn)
74
+ // @limit(lines: 200, params: 0)
75
+ // @deps(@external: [react, sonner, @supabase/supabase-js], @internal: [
76
+ // ../lib/supabase, ../lib/cache, ../utils/mappers, ../types
77
+ // ])
78
+ ```
79
+
80
+ ### 1.5 — `src/hooks/useOrders.ts` — Sin anotaciones OPL
81
+ **Archivo:** `src/hooks/useOrders.ts` (97 líneas)
82
+
83
+ ```typescript
84
+ // @use(kind, contract, limit, deps)
85
+ // @kind(hook)
86
+ // @contract(in: UseOrdersOptions -> out: UseOrdersReturn)
87
+ // @limit(lines: 100)
88
+ // @deps(@external: [react, sonner, @supabase/supabase-js], @internal: [../lib/supabase, ../types])
89
+ ```
90
+
91
+ ### 1.6 — `src/hooks/useProducts.ts` — Sin anotaciones OPL
92
+ **Archivo:** `src/hooks/useProducts.ts` (256 líneas)
93
+
94
+ ```typescript
95
+ // @use(kind, contract, limit, deps)
96
+ // @kind(hook)
97
+ // @contract(in: UseProductsOptions -> out: UseProductsReturn)
98
+ // @limit(lines: 260, params: 1)
99
+ // @deps(@external: [react, sonner, @supabase/supabase-js], @internal: [
100
+ // ../lib/supabase, ../lib/cache, ../types/product, ../types
101
+ // ])
102
+ ```
103
+
104
+ ### 1.7 — `src/hooks/useOffers.ts` — Sin anotaciones OPL
105
+ **Archivo:** `src/hooks/useOffers.ts` (60 líneas)
106
+
107
+ ```typescript
108
+ // @use(kind, contract, limit, deps)
109
+ // @kind(hook)
110
+ // @contract(in: UseOffersOptions -> out: UseOffersReturn)
111
+ // @limit(lines: 60)
112
+ // @deps(@external: [react, sonner, @supabase/supabase-js], @internal: [../lib/supabase, ../lib/cache, ../types])
113
+ ```
114
+
115
+ ### 1.8 — `src/hooks/useRealtimeSync.ts` — Sin anotaciones OPL
116
+ **Archivo:** `src/hooks/useRealtimeSync.ts` (102 líneas)
117
+
118
+ ```typescript
119
+ // @use(kind, contract, limit, deps)
120
+ // @kind(hook)
121
+ // @contract(in: UseRealtimeSyncOptions -> out: void)
122
+ // @limit(lines: 105)
123
+ // @deps(@external: [react, sonner, @supabase/supabase-js], @internal: [
124
+ // ../lib/supabase, ../types, ../types/product, ../utils/mappers
125
+ // ])
126
+ ```
127
+
128
+ ### 1.9 — `src/hooks/useMetrics.ts` — Sin anotaciones OPL
129
+ **Archivo:** `src/hooks/useMetrics.ts` (154 líneas)
130
+
131
+ ```typescript
132
+ // @use(kind, contract, limit, deps)
133
+ // @kind(hook)
134
+ // @contract(in: orders: Order[], products: Product[], reviews: any[], userMetrics -> out: { metrics, isCrunching })
135
+ // @limit(lines: 155)
136
+ // @deps(@external: [react], @internal: [../types, ../types/product])
137
+ ```
138
+
139
+ ### 1.10 — `src/hooks/useDeliveryZones.ts` — TIENE anotaciones (bien)
140
+ ✅ Archivo ya tiene `// @use(kind, contract, limit, deps)` correctamente.
141
+
142
+ ### 1.11 — `src/lib/supabase.ts` — Sin anotaciones OPL
143
+ **Archivo:** `src/lib/supabase.ts` (27 líneas)
144
+
145
+ ```typescript
146
+ // @use(kind, contract, limit, deps)
147
+ // @kind(lib)
148
+ // @contract(in: void -> out: SupabaseClient)
149
+ // @limit(lines: 30)
150
+ // @deps(@external: [@supabase/supabase-js])
151
+ ```
152
+
153
+ ### 1.12 — `src/lib/cache.ts` — Sin anotaciones OPL
154
+ **Archivo:** `src/lib/cache.ts` (59 líneas)
155
+
156
+ ```typescript
157
+ // @use(kind, contract, limit)
158
+ // @kind(service)
159
+ // @contract(in: setCache(key, data, ttl) -> void | getCache(key) -> T | null)
160
+ // @limit(lines: 60)
161
+ ```
162
+
163
+ ### 1.13 — `src/lib/queue.ts` — Sin anotaciones OPL
164
+ **Archivo:** `src/lib/queue.ts` (65 líneas)
165
+
166
+ ```typescript
167
+ // @use(kind, contract, limit)
168
+ // @kind(service)
169
+ // @contract(in: QueueItem -> out: void)
170
+ // @limit(lines: 65)
171
+ ```
172
+
173
+ ### 1.14 — `src/lib/storage.ts` — Sin anotaciones OPL
174
+ **Archivo:** `src/lib/storage.ts` (91 líneas)
175
+
176
+ ```typescript
177
+ // @use(kind, contract, limit, deps)
178
+ // @kind(service)
179
+ // @contract(in: files: File[], productId: string -> out: string[])
180
+ // @limit(lines: 95)
181
+ // @deps(@external: [@supabase/supabase-js], @internal: [./supabase])
182
+ ```
183
+
184
+ ### 1.15 — `src/lib/sanitizer.ts` — Sin anotaciones OPL
185
+ **Archivo:** `src/lib/sanitizer.ts` (27 líneas)
186
+
187
+ ```typescript
188
+ // @use(kind, contract, limit)
189
+ // @kind(util)
190
+ // @contract(in: text: string | undefined | null -> out: string)
191
+ // @limit(lines: 30)
192
+ // @forbidden(any)
193
+ ```
194
+
195
+ ### 1.16 — `src/lib/supabaseLogger.ts` — Sin anotaciones OPL
196
+ **Archivo:** `src/lib/supabaseLogger.ts` (172 líneas)
197
+
198
+ ```typescript
199
+ // @use(kind, contract, limit, deps)
200
+ // @kind(service)
201
+ // @contract(in: supabaseUrl: string -> out: class SupabaseLogger)
202
+ // @limit(lines: 175)
203
+ // @deps(@external: [crypto])
204
+ ```
205
+
206
+ ---
207
+
208
+ ## 🔴 CATEGORÍA 2: Componentes sin anotaciones OPL
209
+
210
+ ### 2.1 — Componentes de página (todos sin anotaciones)
211
+
212
+ | Archivo | Líneas | Anotaciones |
213
+ |---------|--------|-------------|
214
+ | `src/components/Dashboard.tsx` | 148 | ❌ Faltan |
215
+ | `src/components/Catalog.tsx` | 379 | ❌ Faltan |
216
+ | `src/components/Login.tsx` | 294 | ❌ Faltan |
217
+ | `src/components/Reports.tsx` | 388 | ❌ Faltan |
218
+ | `src/components/Settings.tsx` | 402 | ❌ Faltan |
219
+ | `src/components/BottomNav.tsx` | 57 | ❌ Faltan |
220
+ | `src/components/Notifications.tsx` | 167 | ❌ Faltan |
221
+ | `src/components/OrderDetail.tsx` | 391 | ❌ Faltan |
222
+ | `src/components/OrderCard.tsx` | 92 | ❌ Faltan |
223
+ | `src/components/ProductCard.tsx` | 183 | ❌ Faltan |
224
+ | `src/components/ProductForm.tsx` | 468 | ❌ Faltan (**MUY GRANDE**, debe dividirse) |
225
+ | `src/components/UserManagement.tsx` | 238 | ❌ Faltan |
226
+ | `src/components/ReviewModeration.tsx` | 171 | ❌ Faltan |
227
+ | `src/components/InboxTab.tsx` | 31 | ❌ Faltan |
228
+ | `src/components/ActiveOrdersTab.tsx` | 31 | ❌ Faltan |
229
+ | `src/components/HistoryTab.tsx` | — | ❌ Faltan |
230
+ | `src/components/DeliveryZones.tsx` | 272 | ✅ **TIENE** anotaciones |
231
+
232
+ ### 2.2 — Modales (todos sin anotaciones)
233
+
234
+ | Archivo | Líneas | Anotaciones |
235
+ |---------|--------|-------------|
236
+ | `src/components/PinPadModal.tsx` | 176 | ❌ Faltan |
237
+ | `src/components/OfferBuilderModal.tsx` | 202 | ❌ Faltan |
238
+ | `src/components/OfferExecutionModal.tsx` | — | ❌ Faltan |
239
+ | `src/components/QueueModal.tsx` | — | ❌ Faltan |
240
+ | `src/components/StockModal.tsx` | — | ❌ Faltan |
241
+ | `src/components/RejectModal.tsx` | — | ❌ Faltan |
242
+ | `src/components/DelayedConfirmModal.tsx` | — | ❌ Faltan |
243
+ | `src/components/CalendarModal.tsx` | — | ❌ Faltan |
244
+ | `src/components/ChangePasswordModal.tsx` | — | ❌ Faltan |
245
+ | `src/components/CategoryPickerModal.tsx` | — | ❌ Faltan |
246
+ | `src/components/AboutModal.tsx` | — | ❌ Faltan |
247
+ | `src/components/OfflineRestrictionModal.tsx` | — | ❌ Faltan |
248
+ | `src/components/ConnectionDebugModal.tsx` | — | ❌ Faltan (código muerto) |
249
+ | `src/components/DebugPanel.tsx` | — | ❌ Faltan (código muerto) |
250
+
251
+ ### 2.3 — Servicios
252
+
253
+ | Archivo | Líneas | Anotaciones |
254
+ |---------|--------|-------------|
255
+ | `src/services/pushNotifications.ts` | 93 | ✅ **TIENE** anotaciones |
256
+
257
+ ### 2.4 — Utils
258
+
259
+ | Archivo | Líneas | Anotaciones |
260
+ |---------|--------|-------------|
261
+ | `src/utils/mappers.ts` | 46 | ❌ Faltan |
262
+ | `src/utils/imageUtils.ts` | 73 | ❌ Faltan |
263
+
264
+ ### 2.5 — Web/Theme
265
+
266
+ | Archivo | Líneas | Anotaciones |
267
+ |---------|--------|-------------|
268
+ | `src/web/ThemeContext.tsx` | 62 | ❌ Faltan |
269
+ | `src/web/themes.ts` | — | ❌ Faltan |
270
+
271
+ ---
272
+
273
+ ## 🟡 CATEGORÍA 3: Errores de diseño y código detectados
274
+
275
+ ### 3.1 — 🔴 Overfetching masivo de Supabase
276
+ **Archivo:** `src/hooks/useAppData.ts` (líneas 101-124)
277
+ ```typescript
278
+ // ❌ Se traen TODAS las columnas de 5 tablas
279
+ const ordersPromise = supabase.from('orders').select('*, order_items(*)').range(0, 99);
280
+ const productsPromise = supabase.from('products').select('*');
281
+ ```
282
+ **Impacto:** $40-80/mes extra en ancho de banda de Supabase.
283
+
284
+ ### 3.2 — 🔴 3 canales Realtime en vez de 1
285
+ **Archivo:** `src/hooks/useRealtimeSync.ts` (líneas 28-93)
286
+ ```typescript
287
+ // ❌ 3 suscripciones separadas
288
+ supabase.channel('public:orders')...
289
+ supabase.channel('public:offer_reminders')...
290
+ supabase.channel('public:products')...
291
+ ```
292
+ **Impacto:** $20-50/mes extra. Debe ser un solo canal.
293
+
294
+ ### 3.3 — 🔴 Efecto colateral dentro de setState
295
+ **Archivo:** `src/hooks/useProducts.ts` (líneas 140-191)
296
+ ```typescript
297
+ setProducts(prevProducts => {
298
+ // ❌ Llamada a Supabase DENTRO del updater de setState
299
+ supabase.from('products').update(updates).eq('id', productId).then(...)
300
+ return prevProducts.map(...)
301
+ });
302
+ ```
303
+ **Impacto:** Anti-pattern grave. Causa doble ejecución en StrictMode.
304
+
305
+ ### 3.4 — 🔴 Sin RLS en tablas principales
306
+ **Archivo:** `supabase/migrations/`
307
+ - ✅ `admin_push_tokens` → RLS implementado
308
+ - ✅ `event_logs` → RLS implementado
309
+ - ❌ `orders` → SIN RLS
310
+ - ❌ `products` → SIN RLS
311
+ - ❌ `order_items` → SIN RLS
312
+ - ❌ `product_reviews` → SIN RLS
313
+ - ❌ `offer_reminders` → SIN RLS
314
+ - ❌ `delivery_zones` → SIN RLS
315
+ - ❌ `user_profiles` → SIN RLS
316
+
317
+ **Impacto:** Cualquiera con la anon key puede leer/modificar/borrar datos.
318
+
319
+ ### 3.5 — 🔴 `.env` comiteado en Git
320
+ **Archivo:** `.env`
321
+ ```env
322
+ VITE_SUPABASE_URL=https://cszlktmntlyqeslilpnu.supabase.co
323
+ VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIs...
324
+ ```
325
+ **Impacto:** Credenciales expuestas permanentemente en el historial de Git.
326
+
327
+ ### 3.6 — 🔴 PIN secreto hardcodeado
328
+ **Archivo:** `src/components/Login.tsx` (línea 9)
329
+ ```typescript
330
+ const CREATION_SECRET_PIN = '738250';
331
+ ```
332
+ **Impacto:** Cualquiera que lea el código sabe el PIN para crear cuentas admin.
333
+
334
+ ### 3.7 — 🟡 N+1 queries en bulk offer
335
+ **Archivo:** `src/hooks/useProducts.ts` (líneas 221-228)
336
+ ```typescript
337
+ // ❌ N updates individuales en vez de 1 batch
338
+ const uparts = updates.map(u => supabase.from('products').update({...}).eq('id', u.id));
339
+ await Promise.all(uparts);
340
+ ```
341
+
342
+ ### 3.8 — 🟡 `useMemo` usado como `useEffect`
343
+ **Archivo:** `src/App.tsx` (líneas 102-106)
344
+ ```typescript
345
+ // ❌ useMemo es para valores computados, no efectos
346
+ useMemo(() => { registerPushNotifications(user.id) }, [user?.id]);
347
+ ```
348
+
349
+ ### 3.9 — 🟡 JSON.stringify como dependencias de useEffect
350
+ **Archivo:** `src/hooks/useMetrics.ts` (líneas 144-151)
351
+ ```typescript
352
+ // ❌ Serialización completa en cada render
353
+ useEffect(() => { ... }, [JSON.stringify(orders.map(...))]);
354
+ ```
355
+
356
+ ### 3.10 — 🟡 Hook monstruo useAppData
357
+ **Archivo:** `src/hooks/useAppData.ts` (199 líneas)
358
+ **Problema:** Maneja 11 estados + 7 setters de 5 dominios diferentes (products, orders, reviews, reminders, metrics, dbStatus, loading).
359
+
360
+ ### 3.11 — 🟡 ProductForm de 468 líneas
361
+ **Archivo:** `src/components/ProductForm.tsx` (468 líneas)
362
+ **Problema:** Supera el límite recomendado de 200-250 líneas. Debe dividirse en subcomponentes.
363
+
364
+ ### 3.12 — 🟡 Caché inconsistente
365
+ **Archivo:** `src/hooks/useAppData.ts` (líneas 81-136)
366
+ **Problema:** `setCache` guarda datos crudos de Supabase, pero `getCache` consume datos mapeados. Hay doble transformación.
367
+
368
+ ### 3.13 — 🟡 fetchRole llamado dos veces en useAuth
369
+ **Archivo:** `src/hooks/useAuth.ts` (líneas 46-69)
370
+ **Problema:** `getSession()` dispara fetchRole y `onAuthStateChange` también lo dispara para el evento INITIAL_SESSION.
371
+
372
+ ### 3.14 — 🟡 handleDeleteUser solo elimina perfil, no auth user
373
+ **Archivo:** `src/components/UserManagement.tsx` (línea 103)
374
+ ```typescript
375
+ await supabase.from('user_profiles').delete().eq('id', id);
376
+ // ❌ auth.users sigue existiendo
377
+ ```
378
+
379
+ ### 3.15 — 🟡 Código muerto: ConnectionDebugModal, DebugPanel
380
+ **Archivos:** `src/components/ConnectionDebugModal.tsx`, `src/components/DebugPanel.tsx`
381
+ **Problema:** Componentes que existen pero no se importan ni usan en App.tsx.
382
+
383
+ ### 3.16 — 🟡 49 componentes shadcn/ui instalados, muchos sin usar
384
+ **Archivo:** `src/components/ui/` (49 archivos)
385
+ **Problema:** Se instaló shadcn/ui completo pero muchos componentes (carousel, chart, command, context-menu, hover-card, input-otp, menubar, navigation-menu, pagination, resizable, scroll-area, sidebar, slider, toggle-group, tooltip, etc.) no se usan.
386
+
387
+ ### 3.17 — 🟡 16 CSS modulares + Tailwind duplicados
388
+ **Archivo:** `src/styles/*.css` (16 archivos)
389
+ **Problema:** Se mezcla Tailwind (`@apply`) con CSS clásico, duplicando estilos y aumentando el bundle.
390
+
391
+ ### 3.18 — 🟡 sanitizer.ts rompe caracteres UTF-8
392
+ **Archivo:** `src/lib/sanitizer.ts` (líneas 16-20)
393
+ ```typescript
394
+ .replace(/'/g, '’') // ❌ Rompe "Don's Special" → "Don’s Special"
395
+ .replace(/"/g, '”') // ❌ Rompe comillas válidas
396
+ ```
397
+
398
+ ### 3.19 — 🟡 Edge Functions no integradas con frontend
399
+ **Archivos:** `supabase/functions/` (4 funciones)
400
+ **Problema:** `apply-queue` duplica lógica del frontend, `sync-snapshot` nunca se llama, `new-order` solo logea.
401
+
402
+ ### 3.20 — 🟡 16 parámetros en useCapacitorLifecycle
403
+ **Archivo:** `src/hooks/useCapacitorLifecycle.ts` (líneas 12-31)
404
+ **Problema:** Demasiadas propiedades en el options object (code smell).
405
+
406
+ ### 3.21 — 🟡 Alias @/ configurado pero no usado
407
+ **Archivos:** `vite.config.ts:51`, `tsconfig.json:23-24`
408
+ ```json
409
+ "paths": { "@/*": ["./src/*"] }
410
+ ```
411
+ **Problema:** Ningún archivo importa con `@/`, todos usan rutas relativas como `../`.
412
+
413
+ ### 3.22 — 🟡 edge functions `_shared/` con secretos hardcodeados potenciales
414
+ **Archivo:** `supabase/functions/notify-admin/index.ts`
415
+ **Problema:** Usa `Deno.env.get()` para credenciales de Firebase, pero no hay validación de que existan.
416
+
417
+ ### 3.23 — 🟢 Duplicación de scrollbar-hide y hide-scrollbar
418
+ **Archivo:** `src/index.css` (líneas 90-104)
419
+ **Problema:** Dos utility classes con el mismo propósito.
420
+
421
+ ### 3.24 — 🟢 Variables CSS --brand-* duplican propósito de Tailwind
422
+ **Archivo:** `src/index.css` (líneas 37-41)
423
+ **Problema:** Las variables CSS solo se usan en los CSS modulares, no en Tailwind.
424
+
425
+ ### 3.25 — 🟢 Sin tests unitarios
426
+ **Problema:** No hay ningún archivo de test (`*.test.ts`, `*.spec.ts`). No se puede verificar regresión.
427
+
428
+ ---
429
+
430
+ ## 💰 Impacto económico estimado en Supabase
431
+
432
+ | Problema | Costo/mes | Solución |
433
+ |----------|-----------|----------|
434
+ | Overfetching (SELECT *) | $40-80 | Columnas específicas |
435
+ | 3 canales Realtime | $20-50 | 1 canal |
436
+ | N+1 queries bulk offers | $5-15 | Batch `.in()` |
437
+ | Sin RLS (riesgo de abuso) | $100+ | RLS policies |
438
+ | Sin paginación real | $10-30 | Cursor-based |
439
+ | **Total evitable** | **~$75-175/mes** | |
440
+
441
+ ---
442
+
443
+ ## 📋 Checklist de resolución
444
+
445
+ ### 🔴 Prioridad 1 — Seguridad (HACER AHORA)
446
+
447
+ - [ ] **P1.1** Agregar `@use()`, `@kind`, `@contract`, `@deps` a TODOS los archivos
448
+ - [ ] **P1.2** Implementar RLS en todas las tablas (orders, products, order_items, product_reviews, offer_reminders, delivery_zones, user_profiles)
449
+ - [ ] **P1.3** Agregar `.env` a `.gitignore` y rotar la anon key
450
+ - [ ] **P1.4** Mover PIN secreto a variable de entorno
451
+ - [ ] **P1.5** Fix: handleToggleSale — sacar efecto colateral de setState
452
+
453
+ ### 🔴 Prioridad 2 — Performance (HACER PRONTO)
454
+
455
+ - [ ] **P2.1** Optimizar fetchData con columnas específicas + paginación cursor-based
456
+ - [ ] **P2.2** Reducir de 3 a 1 canal Realtime con filtros por tabla
457
+ - [ ] **P2.3** Cambiar N+1 queries a batch update con `.in()`
458
+ - [ ] **P2.4** Reemplazar `useMemo` por `useEffect` en push notifications
459
+
460
+ ### 🟡 Prioridad 3 — Refactor (PLAZO MEDIO)
461
+
462
+ - [ ] **P3.1** Separar `useAppData` en hooks por dominio
463
+ - [ ] **P3.2** Dividir ProductForm en subcomponentes (< 250 líneas c/u)
464
+ - [ ] **P3.3** Unificar CSS: eliminar 16 CSS modulares, usar solo Tailwind
465
+ - [ ] **P3.4** Limpiar shadcn/ui no utilizados
466
+ - [ ] **P3.5** Eliminar código duplicado (compressImage, scrollbar classes)
467
+ - [ ] **P3.6** Eliminar código muerto (ConnectionDebugModal, DebugPanel)
468
+ - [ ] **P3.7** Usar alias @/ en imports
469
+ - [ ] **P3.8** Revisar/fix sanitizer.ts (no romper UTF-8)
470
+ - [ ] **P3.9** Integrar Edge Functions reales con frontend
471
+ - [ ] **P3.10** Agregar test unitarios (mínimo 1 por hook)
472
+
473
+ ### 🟢 Prioridad 4 — Deuda técnica menor
474
+
475
+ - [ ] **P4.1** Crear @learn-error por cada bug fijo
476
+ - [ ] **P4.2** Configurar `prompt-lang.json` con strict mode
477
+ - [ ] **P4.3** Establecer dominio en `prompt-lang.json`
478
+ - [ ] **P4.4** Ejecutar `npx openprompt-lang qa-gen` para generar tests
479
+
480
+ ---
481
+
482
+ ## 📌 Archivos con anotaciones OPL ya existentes (para referencia)
483
+
484
+ ✅ Estos archivos ya tienen anotaciones y sirven como modelo:
485
+
486
+ 1. `src/hooks/useOfflineQueue.ts`
487
+ 2. `src/hooks/useCapacitorLifecycle.ts`
488
+ 3. `src/hooks/useDeliveryZones.ts`
489
+ 4. `src/services/pushNotifications.ts`
490
+ 5. `src/components/DeliveryZones.tsx`
491
+
492
+ ---
493
+
494
+ ## 🏁 Notas finales
495
+
496
+ Este documento debe actualizarse a medida que se resuelvan los problemas.
497
+ Cada vez que se corrija un error, agregar:
498
+ ```typescript
499
+ // @learn-error id=XXX input='...' expected=200 actual=500 fix='...'
500
+ ```
501
+
502
+ ---
503
+
504
+ *Documento generado durante sesión de auditoría OPL — 2026-05-23*
@@ -0,0 +1,158 @@
1
+ # 🎓 OPL Academic — Bitácora de Problemas
2
+
3
+ > Documento para registrar problemas, fricciones y errores detectados en el sistema de enseñanza (Teaching System) de openPrompt-Lang.
4
+ > Cada entrada documenta: síntoma, causa raíz, impacto, solución propuesta y estado.
5
+
6
+ ---
7
+
8
+ ## 📋 Índice de Problemas
9
+
10
+ | # | Fecha | Título | Severidad | Estado |
11
+ |---|-------|--------|-----------|--------|
12
+ | 1 | 2026-05-24 | Onboarding IA en proyecto existente | 🔴 Alta | Abierto |
13
+ | 2 | 2026-05-24 | `opl rebuild` no detecta OPL automáticamente | 🟡 Media | Abierto |
14
+ | 3 | 2026-05-24 | Falta documento post-init para IA | 🔴 Alta | Abierto |
15
+
16
+ ---
17
+
18
+ ## 🐛 Problemas Reportados
19
+
20
+ ### P-001: Onboarding IA en proyecto existente
21
+
22
+ | Campo | Valor |
23
+ |-------|-------|
24
+ | **Fecha** | 2026-05-24 |
25
+ | **Reportado por** | usuario |
26
+ | **Severidad** | 🔴 Alta |
27
+ | **Módulo** | Academic — Init / Onboarding |
28
+ | **Estado** | 🔴 Abierto |
29
+
30
+ **Síntoma:**
31
+ Al iniciar una sesión con IA en un proyecto existente que ya tiene elementos de OPL, la IA no sabe qué hacer. No hay un punto de entrada claro que le diga "esto ya tiene OPL, aquí está el estado actual, continúa desde aquí".
32
+
33
+ **Causa raíz:**
34
+ No existe un documento de onboarding generado automáticamente que la IA pueda leer al inicio de cada sesión para restaurar contexto.
35
+
36
+ **Impacto:**
37
+ - La IA pierde ~15 minutos regenerando contexto cada sesión
38
+ - Toma decisiones inconsistentes porque no conoce el estado real del proyecto
39
+ - El usuario tiene que re-explicar manualmente lo que ya se hizo
40
+
41
+ **Solución propuesta:**
42
+ - Crear `docs/ONBOARDING_WORKFLOW.md` — documento canónico que la IA lee al iniciar
43
+ - Integrar `opl init` para que genere este documento automáticamente
44
+ - Dos versiones: `INICIAR_NUEVO.md` (proyecto nuevo) e `INICIAR_EXISTENTE.md` (proyecto en curso)
45
+
46
+ **Referencias:**
47
+ - `erroresDeFlujo.md` (línea 2)
48
+ - Sprint embeddings → TICKET-011 (propuesto)
49
+
50
+ ---
51
+
52
+ ### P-002: `opl rebuild` no detecta OPL automáticamente
53
+
54
+ | Campo | Valor |
55
+ |-------|-------|
56
+ | **Fecha** | 2026-05-24 |
57
+ | **Reportado por** | usuario |
58
+ | **Severidad** | 🟡 Media |
59
+ | **Módulo** | CLI — rebuild |
60
+ | **Estado** | 🟡 Abierto |
61
+
62
+ **Síntoma:**
63
+ `opl rebuild` falla o funciona incorrectamente cuando los elementos de OPL no están presentes o no son detectables automáticamente.
64
+
65
+ **Causa raíz:**
66
+ El comando `rebuild` asume cierta estructura pre-existente en lugar de ser autosuficiente.
67
+
68
+ **Solución propuesta:**
69
+ Hacer que `rebuild` funciones en dos modos:
70
+ 1. **Con detección**: Si encuentra elementos OPL, los respeta y reconstruye
71
+ 2. **Sin detección**: Si no encuentra nada, crea la estructura desde cero con defaults inteligentes
72
+
73
+ **Referencias:**
74
+ - `erroresDeFlujo.md` (línea 4)
75
+
76
+ ---
77
+
78
+ ### P-003: Falta documento post-init para IA
79
+
80
+ | Campo | Valor |
81
+ |-------|-------|
82
+ | **Fecha** | 2026-05-24 |
83
+ | **Reportado por** | usuario |
84
+ | **Severidad** | 🔴 Alta |
85
+ | **Módulo** | CLI — init |
86
+ | **Estado** | 🔴 Abierto |
87
+
88
+ **Síntoma:**
89
+ Después de ejecutar `opl init`, no se genera ningún documento que la IA pueda usar para entender el contexto del proyecto. La IA llega "en frío" a cada sesión.
90
+
91
+ **Causa raíz:**
92
+ `opl init` configura el proyecto (crea prompt-lang.json, AGENTS.md, etc.) pero no genera un punto de entrada específico para la IA que le diga "esto es lo que hay, esto es lo que falta, continúa".
93
+
94
+ **Solución propuesta:**
95
+ Que `opl init` genere automáticamente:
96
+ - `INICIAR_NUEVO.md` si es proyecto nuevo
97
+ - `INICIAR_EXISTENTE.md` si es proyecto existente con OPL
98
+
99
+ Estos documentos deben incluir:
100
+ - Stack detectado
101
+ - Estado de la configuración OPL
102
+ - Próximos pasos recomendados
103
+ - Enlace a `AGENTS.md` y `docs/AI_CONTEXT.md`
104
+
105
+ **Referencias:**
106
+ - `erroresDeFlujo.md` (línea 6)
107
+ - `docs/ONBOARDING_WORKFLOW.md`
108
+
109
+ ---
110
+
111
+ ## 📊 Estadísticas
112
+
113
+ | Métrica | Valor |
114
+ |---------|-------|
115
+ | Total problemas | 3 |
116
+ | Severidad Alta | 2 |
117
+ | Severidad Media | 1 |
118
+ | Severidad Baja | 0 |
119
+ | Abiertos | 3 |
120
+ | En Progreso | 0 |
121
+ | Resueltos | 0 |
122
+
123
+ ---
124
+
125
+ ## 📝 Cómo Reportar un Problema Nuevo
126
+
127
+ Usa esta plantilla al añadir una nueva entrada:
128
+
129
+ ```markdown
130
+ ### P-XXX: Título descriptivo
131
+
132
+ | Campo | Valor |
133
+ |-------|-------|
134
+ | **Fecha** | YYYY-MM-DD |
135
+ | **Reportado por** | — |
136
+ | **Severidad** | 🔴 Alta / 🟡 Media / 🟢 Baja |
137
+ | **Módulo** | — |
138
+ | **Estado** | 🔴 Abierto |
139
+
140
+ **Síntoma:**
141
+ _¿Qué ocurre exactamente?_
142
+
143
+ **Causa raíz:**
144
+ _¿Por qué ocurre?_
145
+
146
+ **Impacto:**
147
+ _¿A quién afecta y cómo?_
148
+
149
+ **Solución propuesta:**
150
+ _¿Cómo se arreglaría?_
151
+
152
+ **Referencias:**
153
+ - _enlaces a código, docs, commits_
154
+ ```
155
+
156
+ ---
157
+
158
+ *Última actualización: 2026-05-24*