openprompt-lang 0.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 (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +663 -0
  3. package/bin/cli.js +110 -0
  4. package/bin/lint.js +50 -0
  5. package/docs/COMMANDS.md +229 -0
  6. package/docs/COMMITS/INDEX.md +11 -0
  7. package/docs/COMMITS/v0.1.0-existing.md +31 -0
  8. package/docs/COMMITS/v0.1.0-inicial.md +50 -0
  9. package/docs/COMMITS/v0.1.0-readme.md +24 -0
  10. package/docs/COMMITS/v0.2.0-strict-db-templates.md +50 -0
  11. package/docs/COMMITS/v0.3.0-parser-fixes-vscode.md +67 -0
  12. package/docs/COMMITS/v0.3.0-versioning-component.md +44 -0
  13. package/docs/DEPENDENCIES.md +45 -0
  14. package/docs/FRAMEWORK.md +1741 -0
  15. package/docs/SYNTAX.md +359 -0
  16. package/docs/VERSIONING.md +150 -0
  17. package/docs/referencia-metodologia/Anexos Finales Documentos de Respaldo y Estandarizaci/303/263n.md" +90 -0
  18. package/docs/referencia-metodologia/Cotizaciones.md +84 -0
  19. package/docs/referencia-metodologia/Example.md +1 -0
  20. package/docs/referencia-metodologia/ExtractorInformacion.py +78 -0
  21. package/docs/referencia-metodologia/Fase - 1 .- Desarrollo de la Metodolog/303/255a.md" +67 -0
  22. package/docs/referencia-metodologia/Fase - 2 .- Levantamiento de requisitos generales y traduccion a la IA.md +64 -0
  23. package/docs/referencia-metodologia/Fase - 3 .- Prototipado visual con IA (Figma Maker o equivalentes).md +64 -0
  24. package/docs/referencia-metodologia/Fase - 4 .- Especificacion de requisitos e iteracion con el cliente.md +58 -0
  25. package/docs/referencia-metodologia/Fase - 5 .- Estructuracion y maquetado de funciones (Scaffolding).md +118 -0
  26. package/docs/referencia-metodologia/Fase - 6 .- Estructuracion del backlog y division de tareas.md +48 -0
  27. package/docs/referencia-metodologia/Fase - 7 .- Desarrollo activo, pruebas y control de versiones.md +98 -0
  28. package/docs/referencia-metodologia/Fase - 8 .- Entrega, capacitaci/303/263n y mantenimiento.md" +55 -0
  29. package/docs/referencia-metodologia/Figma prompt template.md +130 -0
  30. package/docs/referencia-metodologia/Framework de Desarrollo Asistido por IA.md +1741 -0
  31. package/docs/referencia-metodologia/Indice General.md +83 -0
  32. package/docs/referencia-metodologia/Prompt refactorizar o creacion desde cero.md +50 -0
  33. package/docs/referencia-metodologia/docs/CONVENCIONES_DB.md +410 -0
  34. package/docs/referencia-metodologia/docs/CONVENCIONES_DOCUMENTACION.md +209 -0
  35. package/docs/referencia-metodologia/docs/PROMPTS/INDEX.md +73 -0
  36. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/01-hook-supabase.md +79 -0
  37. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/02-componente-ui.md +82 -0
  38. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/03-pagina-feature.md +70 -0
  39. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/04-comando-tauri.md +56 -0
  40. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/05-store-zustand.md +74 -0
  41. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/06-servicio-supabase.md +74 -0
  42. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/07-formulario-validacion.md +63 -0
  43. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/08-hook-capacitor.md +65 -0
  44. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/09-refactor-division.md +51 -0
  45. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/10-scaffolding-inicial.md +79 -0
  46. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/11-supabase-crud-service.md +114 -0
  47. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/12-supabase-hook-usetable.md +143 -0
  48. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/13-tauri-command-rust.md +84 -0
  49. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/14-tauri-wrapper-typescript.md +92 -0
  50. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/15-documentar-tabla-db.md +50 -0
  51. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/16-diagrama-arquitectura.md +60 -0
  52. package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/17-documentar-api-rpc.md +56 -0
  53. package/docs/referencia-metodologia/docs/PROMPTS/STACK/ionic-capacitor.md +52 -0
  54. package/docs/referencia-metodologia/docs/PROMPTS/STACK/react-web-puro.md +46 -0
  55. package/docs/referencia-metodologia/docs/PROMPTS/STACK/tauri-desktop.md +53 -0
  56. package/package.json +56 -0
  57. package/schemas/prompt-lang.json +98 -0
  58. package/src/commands/component.js +326 -0
  59. package/src/commands/context.js +206 -0
  60. package/src/commands/figma.js +63 -0
  61. package/src/commands/init.js +373 -0
  62. package/src/commands/suggest.js +31 -0
  63. package/src/commands/validate.js +183 -0
  64. package/src/generators/figma-prompt.js +56 -0
  65. package/src/utils/ai.js +143 -0
  66. package/src/utils/annotations.js +510 -0
  67. package/src/utils/config.js +60 -0
  68. package/vscode-extension/README.md +31 -0
  69. package/vscode-extension/language-configuration.json +7 -0
  70. package/vscode-extension/package.json +62 -0
  71. package/vscode-extension/snippets/promptlang.json +105 -0
  72. package/vscode-extension/syntaxes/annotations.tmGrammar.json +39 -0
  73. package/vscode-extension/syntaxes/promptlang.tmGrammar.json +14 -0
@@ -0,0 +1,83 @@
1
+ ---
2
+ title: Metodología de Desarrollo Asistido por IA
3
+ author: Matías Retamal
4
+ version: 1.0.0
5
+ tags:
6
+ - metodologia
7
+ - saas
8
+ - ia
9
+ - arquitectura
10
+ date: 2026-04-25
11
+ ---
12
+
13
+ # 🧠 Metodología de Desarrollo Asistido por IA
14
+
15
+ > [!info] Sobre este documento
16
+ > Este índice interactivo contiene la estructura definitiva del ciclo de vida de desarrollo de software para proyectos SaaS y Pymes, optimizado para el trabajo Full-Stack y la delegación algorítmica de código mediante Inteligencia Artificial.
17
+
18
+ ---
19
+
20
+ ## 🗂️ Índice General
21
+
22
+ > [!abstract] ETAPA I: Descubrimiento y Planificación Estratégica
23
+ > Comprende desde la primera reunión hasta la congelación del presupuesto y el alcance del MVP.
24
+ >
25
+ > **[[#1. Fase 1: Levantamiento de requisitos generales (Discovery)|1. Fase 1: Levantamiento de requisitos generales (Discovery)]]**
26
+ > - a. Detallado del funcionamiento del negocio y su dolor principal
27
+ > - b. Definición de límites comerciales (Alcance inicial)
28
+ >
29
+ > **[[#2. Fase 2: Traducción técnica y contratos (Historias de usuario)|2. Fase 2: Traducción técnica y contratos (Historias de usuario)]]**
30
+ > - a. Creación de Historias de Usuario
31
+ > - b. Traducción a definiciones de métodos (El Contrato Estructural)
32
+ >
33
+ > **[[#3. Fase 3: Diseño UI/UX y estructura visual (Wireframing)|3. Fase 3: Diseño UI/UX y estructura visual (Wireframing)]]**
34
+ > - a. Diseño de Prototipos interactivos
35
+ > - b. Estructura de vistas y componentes (Preparación para React)
36
+ >
37
+ > **[[#4. Fase 4: Especificación de requisitos e iteración con el cliente|4. Fase 4: Especificación de requisitos e iteración con el cliente]]**
38
+ > - a. Integración de correcciones del cliente (Feedback Loop)
39
+ > - b. Ciclo de preguntas, control de alcance y presupuesto final
40
+ > - c. Especificación de nuevos elementos funcionales
41
+ > - d. Bibliotecas necesarias y factibilidad técnica
42
+ > - e. Checklist de Aprobación: Inicio Oficial de Desarrollo (Go / No-Go)
43
+
44
+ > [!example] ETAPA II: Arquitectura y Preparación para IA
45
+ > Diseño de la arquitectura de carpetas, esqueletos de código (Scaffolding) y división estricta de tareas.
46
+ >
47
+ > **[[#5. Fase 5: Estructuración y maquetado de funciones (Scaffolding)|5. Fase 5: Estructuración y maquetado de funciones (Scaffolding)]]**
48
+ > - a. Creación de estructura básica de archivos de documentación
49
+ > - b. Definición de estructura de carpetas definitiva
50
+ > - c. Creación de archivos y esqueletos base (Scaffolding)
51
+ > - d. Ejemplo práctico de definición técnica (Contrato en Código)
52
+ > - e. Diagramas de apoyo técnico
53
+ > - f. Prompt Maestro para Generación de Scaffolding con IA
54
+ >
55
+ > **[[#6. Fase 6: Estructuración del backlog y división de tareas|6. Fase 6: Estructuración del backlog y división de tareas]]**
56
+ > - a. Sistema de Gestión Centralizado (Enfoque JSON-Driven)
57
+ > - b. Estrategia de Desarrollo por Capas (Layered Development)
58
+ > - c. Granularidad Extrema para la IA (Micro-Tasking)
59
+ > - d. Refinamiento Continuo (Refactoring Temprano)
60
+
61
+ > [!tip] ETAPA III: Desarrollo, Testing y Puesta en Producción
62
+ > Programación activa, control de versiones semántico y transferencia del software al cliente.
63
+ >
64
+ > **[[#7. Fase 7: Desarrollo activo, pruebas y control de versiones|7. Fase 7: Desarrollo activo, pruebas y control de versiones]]**
65
+ > - a. Metodología de Pruebas (Testing y Criterios de Aceptación)
66
+ > - b. Control de Versiones y Trazabilidad (Micro-Commits)
67
+ > - c. Ejemplo Práctico de un Commit Estandarizado
68
+ > - d. Gestión de Despliegues y Versionado Semántico
69
+ > - e. Sistema de Criterios para Cambio de Versión (SemVer Checklist)
70
+ >
71
+ > **[[#8. Fase 8: Entrega, capacitación y mantenimiento|8. Fase 8: Entrega, capacitación y mantenimiento]]**
72
+ > - a. Protocolo de Entrega y Cierre Administrativo
73
+ > - b. Capacitación y Onboarding del Cliente
74
+ > - c. Políticas de Soporte y Canales de Comunicación
75
+ > - d. Mantenimiento, Monitoreo y Escalabilidad
76
+
77
+ > [!quote] 📎 ETAPA IV: Anexos Comerciales y Legales
78
+ > **[[#Anexos Finales|Documentos de Respaldo y Estandarización]]**
79
+ > - 💰 Anexo A: Tabla de Precios de Referencia (UF / CLP)
80
+ > - 📄 Anexo B: Plantilla - Propuesta Inicial de Desarrollo
81
+ > - 🤝 Anexo C: Plantilla - Acta de Entrega Final y Descargos de Responsabilidad
82
+
83
+ ---
@@ -0,0 +1,50 @@
1
+ `**SYSTEM/CONTEXT:**`
2
+ `Eres un Arquitecto de Software Senior especializado en React 18+, TypeScript, Tailwind CSS y proyectos SaaS escalables. **OBLIGATORIO: Respeta y maximiza convenciones React para reusabilidad** (composition > inheritance, custom hooks para lógica, compound components, single responsibility, generics TS, shadcn/ui patterns con Tailwind utility-first, memo/useCallback, evita HOCs si hooks bastan). Analiza el proyecto, crea /docs/, audita priorizando reusabilidad perdida/ganada.`
3
+
4
+ `**OBJETIVO PRINCIPAL:**`
5
+ `Mismo que antes, pero **en TODAS secciones integra reusabilidad React**: scaffolding con componentes reutilizables (ej: ui/Button.tsx genérico), ejemplos muestran composition, auditoría mide % de código reusable.`
6
+
7
+ `**ESTRUCTURA /docs/:** Igual, + nueva sección **07-REUSABILIDAD-REACT.md** (convenciones aplicadas, métricas reusabilidad).`
8
+
9
+ `**INSTRUCCIONES DETALLADAS (actualizadas):**`
10
+
11
+ 1. `**Auditoría (AUDITORIA.md):**`
12
+ `Agrega columna | % Reusabilidad | (ej: "Components duplicados: 40% → refactor a hooks genéricos"). Plan acción: "Prioriza hooks como useFormInput reusable en orders/properties" .`
13
+
14
+ 2. `**Scaffolding (tree-scaffolding.txt):**`
15
+ `Enfatiza reusabilidad:`
16
+
17
+ `text`
18
+
19
+ `src/ ├── components/ │ └── ui/ (shadcn-style reutilizables: Button.tsx, Input.tsx, Card.tsx, index.ts exports) ├── hooks/ (useQueryProps.ts genérico, useAuth.ts, useFormReusable.ts) ├── features/properties/ (compone ui/Button + hooks)`
20
+
21
+ `Nombres: ui/DataTable.tsx (genérico con <T>), `hooks/useCRUD.ts<T>`.`
22
+
23
+ `3. **Ejemplos (correctos/incorrectos.md):**`
24
+
25
+ `- **Correcto (Reusabilidad):**`
26
+
27
+ `tsx`
28
+
29
+ ``// ui/Button.tsx (shadcn pattern, variants Tailwind) import { cva, type VariantProps } from 'class-variance-authority'; import { memo } from 'react'; const buttonVariants = cva("..."); // variants: primary, destructive interface ButtonProps extends VariantProps<typeof buttonVariants> { children: React.ReactNode; onClick?: () => void; } export const Button = memo<ButtonProps>(({ variant, ...props }) => <button className={buttonVariants({ variant })} {...props} />); // Uso reusable: <Button variant="primary" onClick={handleSave}>Guardar</Button> en forms/CRUD``
30
+
31
+ `Impacto: Reusable en 10+ lugares, composition con Card/Form.`
32
+
33
+ `- **Incorrecto:** God-component con 20 props/if-else. Fix: Split en hooks + ui primitives.`
34
+
35
+ `4. **Diccionario Variables:** Incluye | Reutilizable en | (ej: `buttonVariants` | ui/Button, Card | Afecta todos CTAs).`
36
+
37
+ `5. **Flujos:** Diagramas muestran composition: Page → Feature → ui/Hooks.`
38
+
39
+ `6. **Nueva 07-REUSABILIDAD-REACT.md:**`
40
+
41
+ `- Lista convenciones: Custom hooks genéricos, Compound (Select + Options), Memo para perf.[](https://dev.to/hasancse/best-practices-for-creating-reusable-custom-hooks-in-react-37nj)`
42
+
43
+ `- Métricas: Tabla | Componente | Lugares Reusado | Mejora Sugerida |.`
44
+
45
+ `- Ej: "useQuery → genérico<T> para Supabase en properties/orders".`
46
+
47
+ `7. **INDEX-MAESTRO.md:** Sección ## Reusabilidad [link a 07].`
48
+
49
+
50
+ `**VALIDACIÓN:** Confirma >70% componentes reutilizables post-refactor. Genera todo listo para copiar.`
@@ -0,0 +1,410 @@
1
+ # Convenciones de Base de Datos — Supabase / PostgreSQL
2
+
3
+ > Prácticas priorizadas por impacto en rendimiento, seguridad y escalabilidad para proyectos React + Supabase. Cada práctica incluye ejemplo correcto ✅ e incorrecto ❌.
4
+
5
+ ---
6
+
7
+ ## 1. SELECT con columnas específicas
8
+
9
+ Nunca uses `select(*)`. Reduce bandwidth 70-90%.
10
+
11
+ ```typescript
12
+ // ✅ Correcto
13
+ supabase.from('products').select('id, name, price, category_id')
14
+
15
+ // ❌ Incorrecto
16
+ supabase.from('products').select('*')
17
+ ```
18
+
19
+ **Por qué:** `*` trae columnas que no necesitas (JSONB grandes, texto largo), satura la red y ralentiza el render.
20
+
21
+ ---
22
+
23
+ ## 2. Keyset pagination (cursor-based)
24
+
25
+ Usa `WHERE id > last_id LIMIT n` en lugar de `offset`. Escala infinito sin degradación.
26
+
27
+ ```typescript
28
+ // ✅ Correcto — keyset pagination
29
+ async function getUsers(pageSize = 25, cursor?: string) {
30
+ let query = supabase.from('users').select('id, name, email').limit(pageSize).order('id', { ascending: true })
31
+ if (cursor) query = query.gt('id', cursor)
32
+ return query
33
+ }
34
+
35
+ // ❌ Incorrecto — offset based (se degrada con datos grandes)
36
+ supabase.from('users').select('id, name').range(offset, offset + 25)
37
+ ```
38
+
39
+ **Por qué:** `OFFSET` escanea filas descartadas en cada página. Keyset usa índices directamente.
40
+
41
+ ---
42
+
43
+ ## 3. RLS políticas granulares
44
+
45
+ Cada tabla debe tener Row Level Security activado con políticas `USING (auth.uid() = user_id)`.
46
+
47
+ ```sql
48
+ -- ✅ Correcto — RLS granular
49
+ CREATE POLICY "users_own_profile" ON profiles
50
+ FOR ALL USING (auth.uid() = id);
51
+
52
+ CREATE POLICY "select_own_orders" ON orders
53
+ FOR SELECT USING (auth.uid() = user_id);
54
+
55
+ -- ❌ Incorrecto — bucket público o sin RLS
56
+ -- (no deshabilitar RLS en tablas con datos de usuario)
57
+ ```
58
+
59
+ **En el código:**
60
+ ```typescript
61
+ // ✅ El frontend solo consulta, RLS filtra automáticamente
62
+ const { data } = await supabase.from('orders').select('id, total')
63
+
64
+ // ❌ Service Role Key en el cliente (NUNCA)
65
+ const serviceClient = createClient(url, process.env.SERVICE_ROLE_KEY) // PELIGRO
66
+ ```
67
+
68
+ **Por qué:** RLS es zero-trust: aunque el token sea válido, el usuario solo ve sus datos. No necesitas middleware de autorización.
69
+
70
+ ---
71
+
72
+ ## 4. RPC para lógica compleja (evitar N+1)
73
+
74
+ Operaciones multi-paso o joins pesados van en funciones Postgres, no en el cliente.
75
+
76
+ ```sql
77
+ -- ✅ Correcto — RPC en base de datos
78
+ CREATE OR REPLACE FUNCTION get_dashboard_stats(user_id UUID)
79
+ RETURNS JSONB LANGUAGE plpgsql SECURITY DEFINER AS $$
80
+ DECLARE
81
+ result JSONB;
82
+ BEGIN
83
+ SELECT jsonb_build_object(
84
+ 'total_orders', (SELECT count(*) FROM orders WHERE orders.user_id = get_dashboard_stats.user_id),
85
+ 'total_spent', (SELECT COALESCE(sum(total), 0) FROM orders WHERE orders.user_id = get_dashboard_stats.user_id)
86
+ ) INTO result;
87
+ RETURN result;
88
+ END;
89
+ $$;
90
+ ```
91
+
92
+ ```typescript
93
+ // ✅ Llamada desde el frontend
94
+ const { data } = await supabase.rpc('get_dashboard_stats', { user_id: userId })
95
+
96
+ // ❌ Múltiples queries desde el cliente (N+1)
97
+ const orders = await supabase.from('orders').select('id')
98
+ for (const order of orders.data) {
99
+ await supabase.from('order_items').select('*').eq('order_id', order.id)
100
+ }
101
+ ```
102
+
103
+ **Por qué:** RPC ejecuta lógica del lado de la DB, sin round-trips múltiples, con acceso directo a memoria.
104
+
105
+ ---
106
+
107
+ ## 5. Índices en columnas WHERE / JOIN / ORDER BY
108
+
109
+ Crea índices compuestos para los filtros más comunes de cada tabla.
110
+
111
+ ```sql
112
+ -- ✅ Correcto — índice compuesto para filtros frecuentes
113
+ CREATE INDEX idx_orders_user_status ON orders(user_id, status) WHERE status != 'cancelled';
114
+
115
+ -- ✅ Cubrir SELECT con INCLUDE
116
+ CREATE INDEX idx_orders_user_id ON orders(user_id) INCLUDE (total, created_at);
117
+
118
+ -- ❌ Sin índice en columna de filtro frecuente
119
+ -- SELECT * FROM orders WHERE user_id = '...' AND status = 'active' ← full scan
120
+ ```
121
+
122
+ **En migración:**
123
+ ```bash
124
+ supabase migration new add_orders_indexes
125
+ # Editar el archivo SQL generado
126
+ ```
127
+
128
+ **Por qué:** Los índices convierten scans secuenciales en búsquedas O(log n). Los partial indexes son 90% más pequeños.
129
+
130
+ ---
131
+
132
+ ## 6. Signed URLs para archivos (no buckets públicos)
133
+
134
+ ```typescript
135
+ // ✅ Correcto — Signed URL con expiración
136
+ const { data } = await supabase.storage
137
+ .from('avatars')
138
+ .createSignedUrl(`users/${userId}.jpg`, 3600) // expira en 1h
139
+
140
+ // ❌ Incorrecto — bucket público
141
+ // Bucket config: public = true ← cualquiera con la URL accede
142
+ ```
143
+
144
+ **Por qué:** Signed URLs limitan acceso temporal. Incluso con RLS en tablas, los archivos en buckets públicos son accesibles por cualquiera que tenga la URL.
145
+
146
+ ---
147
+
148
+ ## 7. Service Role Key solo en backend
149
+
150
+ ```typescript
151
+ // ✅ Correcto — Service Key solo en Edge Functions o backend
152
+ // (Nunca en código frontend)
153
+ const serviceClient = createClient(url, process.env.SERVICE_ROLE_KEY)
154
+
155
+ // ❌ Incorrecto — Service Key en frontend
156
+ // Si alguien extrae la key, tiene acceso total a tu BD
157
+ ```
158
+
159
+ **Regla:** En el frontend usa solo la `anon key` con RLS. Para operaciones admin usa RPC con `SECURITY DEFINER` o Edge Functions.
160
+
161
+ ---
162
+
163
+ ## 8. Batch operations
164
+
165
+ ```typescript
166
+ // ✅ Correcto — batch insert
167
+ const { error } = await supabase.from('products').insert([
168
+ { name: 'Pro A', price: 100 },
169
+ { name: 'Pro B', price: 200 },
170
+ { name: 'Pro C', price: 300 },
171
+ ])
172
+
173
+ // ❌ Incorrecto — inserts en loop
174
+ for (const product of products) {
175
+ await supabase.from('products').insert(product)
176
+ }
177
+ ```
178
+
179
+ **Por qué:** Un batch insert es ~10x más rápido que inserts individuales por el overhead de cada query.
180
+
181
+ ---
182
+
183
+ ## 9. Tipos precisos (UUID, TIMESTAMPTZ, JSONB)
184
+
185
+ ```sql
186
+ -- ✅ Correcto — tipos específicos
187
+ CREATE TABLE products (
188
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
189
+ name TEXT NOT NULL,
190
+ price NUMERIC(10,2) NOT NULL DEFAULT 0,
191
+ metadata JSONB DEFAULT '{}',
192
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
193
+ );
194
+
195
+ -- ❌ Incorrecto — tipos genéricos
196
+ CREATE TABLE products (
197
+ id TEXT PRIMARY KEY, -- UUID como TEXT desperdicia espacio e índices
198
+ price FLOAT, -- FLOAT tiene errores de redondeo
199
+ created_at TIMESTAMP -- Sin timezone = ambigüedad
200
+ );
201
+ ```
202
+
203
+ **Por qué:** `UUID` vs `TEXT`: 16 bytes vs variable. `TIMESTAMPTZ` evita ambigüedad de zona horaria. `NUMERIC` es exacto para dinero.
204
+
205
+ ---
206
+
207
+ ## 10. Types generados desde la DB
208
+
209
+ ```bash
210
+ # ✅ Correcto — tipos sincronizados automáticamente
211
+ supabase gen types typescript --local > src/types/supabase.ts
212
+
213
+ # ❌ Incorrecto — tipos escritos a mano (se desincronizan)
214
+ interface Product {
215
+ id: string
216
+ name: string
217
+ // ... se rompe cuando agregas columnas
218
+ }
219
+ ```
220
+
221
+ Luego úsalos:
222
+ ```typescript
223
+ import { Database } from '../types/supabase'
224
+ type Product = Database['public']['Tables']['products']['Row']
225
+ ```
226
+
227
+ ---
228
+
229
+ ## 11. Migraciones versionadas
230
+
231
+ ```bash
232
+ # ✅ Correcto — cada cambio de schema es una migración
233
+ supabase migration new add_product_categories
234
+
235
+ # Editar el SQL, luego:
236
+ supabase db push
237
+
238
+ # ❌ Incorrecto — cambios directos en tabla
239
+ ALTER TABLE products ADD COLUMN category_id UUID; -- sin migración
240
+ ```
241
+
242
+ **Por qué:** Las migraciones dan historial, rollback, y reproducción exacta en producción.
243
+
244
+ ---
245
+
246
+ ## 12. Error handling por código PostgreSQL
247
+
248
+ ```typescript
249
+ // ✅ Correcto — capturar errores por código
250
+ try {
251
+ const { error } = await supabase.from('users').insert({ email })
252
+ if (error?.code === '23505') {
253
+ // Unique violation — email ya existe
254
+ return { error: 'Este email ya está registrado' }
255
+ }
256
+ if (error?.code === '23503') {
257
+ // Foreign key violation
258
+ return { error: 'Referencia inválida' }
259
+ }
260
+ } catch (err) {
261
+ console.error('Error inesperado:', err)
262
+ }
263
+
264
+ // ❌ Incorrecto — error genérico
265
+ catch (err) {
266
+ showToast('Error de base de datos') // sin contexto para el usuario
267
+ }
268
+ ```
269
+
270
+ **Códigos comunes:** `23505` (unique), `23503` (foreign key), `42P01` (tabla no existe), `42501` (RLS denegado).
271
+
272
+ ---
273
+
274
+ ## 13. Soft deletes
275
+
276
+ ```sql
277
+ -- ✅ Correcto — borrado lógico con columna deleted_at
278
+ ALTER TABLE products ADD COLUMN deleted_at TIMESTAMPTZ;
279
+
280
+ -- RLS que excluye borrados
281
+ CREATE POLICY "select_active_products" ON products
282
+ FOR SELECT USING (deleted_at IS NULL);
283
+ ```
284
+
285
+ ```typescript
286
+ // ✅ Soft delete
287
+ await supabase.from('products').update({ deleted_at: new Date().toISOString() }).eq('id', id)
288
+
289
+ // ❌ Hard delete (irreversible)
290
+ await supabase.from('products').delete().eq('id', id)
291
+ ```
292
+
293
+ **Por qué:** Soft delete permite recuperación, auditoría, y evita "cascades" de FK que rompen datos relacionados.
294
+
295
+ ---
296
+
297
+ ## 14. Transacciones multi-paso vía RPC
298
+
299
+ Para operaciones que involucran múltiples tablas, usa una función RPC con transacción:
300
+
301
+ ```sql
302
+ -- ✅ Correcto — todo en una transacción
303
+ CREATE OR REPLACE FUNCTION create_order(p_user_id UUID, p_items JSONB)
304
+ RETURNS JSONB LANGUAGE plpgsql SECURITY DEFINER AS $$
305
+ DECLARE
306
+ v_order_id UUID;
307
+ v_total NUMERIC;
308
+ BEGIN
309
+ INSERT INTO orders (user_id, status) VALUES (p_user_id, 'pending') RETURNING id INTO v_order_id;
310
+ INSERT INTO order_items (order_id, product_id, quantity, price)
311
+ SELECT v_order_id, item->>'product_id', (item->>'quantity')::INT, (item->>'price')::NUMERIC
312
+ FROM jsonb_array_elements(p_items) AS item;
313
+ SELECT SUM(quantity * price) INTO v_total FROM order_items WHERE order_id = v_order_id;
314
+ UPDATE orders SET total = v_total WHERE id = v_order_id;
315
+ RETURN jsonb_build_object('order_id', v_order_id, 'total', v_total);
316
+ END;
317
+ $$;
318
+ ```
319
+
320
+ ```typescript
321
+ // ✅ Llamada única
322
+ const { data } = await supabase.rpc('create_order', { p_user_id: userId, p_items: cart })
323
+
324
+ // ❌ Múltiples queries sin transacción
325
+ const { data: order } = await supabase.from('orders').insert({ user_id: userId }).select()
326
+ // Si esto falla después, tienes datos huérfanos
327
+ await supabase.from('order_items').insert(items.map(i => ({ order_id: order.id, ...i })))
328
+ ```
329
+
330
+ ---
331
+
332
+ ## 15. Realtime channels con cleanup
333
+
334
+ ```typescript
335
+ // ✅ Correcto — unsubscribe en cleanup
336
+ useEffect(() => {
337
+ const channel = supabase
338
+ .channel('orders-feed')
339
+ .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'orders' }, payload => {
340
+ setOrders(prev => [...prev, payload.new])
341
+ })
342
+ .subscribe()
343
+
344
+ return () => { supabase.removeChannel(channel) } // cleanup!
345
+ }, [])
346
+
347
+ // ❌ Incorrecto — sin cleanup (fuga de conexiones)
348
+ useEffect(() => {
349
+ supabase.channel('orders-feed').on('postgres_changes', ...).subscribe()
350
+ // Sin return → se acumulan canales al remontar el componente
351
+ }, [])
352
+ ```
353
+
354
+ ---
355
+
356
+ ## 16. Unique constraints y Foreign Keys
357
+
358
+ ```sql
359
+ -- ✅ Correcto — constraints explícitas
360
+ CREATE TABLE products (
361
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
362
+ sku TEXT UNIQUE NOT NULL,
363
+ category_id UUID NOT NULL REFERENCES categories(id) ON DELETE RESTRICT
364
+ );
365
+
366
+ -- ❌ Incorrecto — validación solo en código
367
+ -- (dos usuarios pueden insertar el mismo SKU si la request llega al mismo tiempo)
368
+ ```
369
+
370
+ **Por qué:** Las constraints de base de datos son el último filtro de integridad. El código puede tener bugs, la base de datos no.
371
+
372
+ ---
373
+
374
+ ## 17. Partial indexes para filtros comunes
375
+
376
+ ```sql
377
+ -- ✅ Correcto — índice solo para filas activas (más pequeño, más rápido)
378
+ CREATE INDEX idx_products_active ON products(created_at) WHERE active = true;
379
+
380
+ -- ❌ Incorrecto — índice completo en tabla con 80% inactivos
381
+ CREATE INDEX idx_products_created ON products(created_at);
382
+ ```
383
+
384
+ **Por qué:** Un partial index es ~90% más pequeño que uno completo cuando filtras por un subconjunto.
385
+
386
+ ---
387
+
388
+ ## 18. Covering indexes (INCLUDE)
389
+
390
+ ```sql
391
+ -- ✅ Correcto — index-only scan
392
+ CREATE INDEX idx_orders_user ON orders(user_id) INCLUDE (total, status, created_at);
393
+
394
+ -- ❌ Incorrecto — necesita ir a la tabla para obtener columnas extra
395
+ CREATE INDEX idx_orders_user ON orders(user_id);
396
+ -- SELECT user_id, total, status FROM orders WHERE user_id = 'x' → necesita heap lookup
397
+ ```
398
+
399
+ **Por qué:** Con `INCLUDE`, la query se resuelve solo con el índice, sin tocar la tabla principal.
400
+
401
+ ---
402
+
403
+ ## Resumen: Prioridad por fase del proyecto
404
+
405
+ | Fase | Prácticas esenciales |
406
+ |---|---|
407
+ | MVP / Prototipo | 1 (SELECT), 3 (RLS), 9 (tipos), 10 (types gen), 16 (constraints) |
408
+ | Producción | + 4 (RPC), 5 (índices), 6 (signed URLs), 12 (error codes), 15 (realtime) |
409
+ | Escalando | + 2 (keyset), 8 (batch), 11 (migrations), 13 (soft delete), 14 (transacciones), 17 (partial), 18 (covering) |
410
+ | Auditoría/Seguridad | + 7 (service key), todo RLS revisado |