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.
- package/LICENSE +21 -0
- package/README.md +663 -0
- package/bin/cli.js +110 -0
- package/bin/lint.js +50 -0
- package/docs/COMMANDS.md +229 -0
- package/docs/COMMITS/INDEX.md +11 -0
- package/docs/COMMITS/v0.1.0-existing.md +31 -0
- package/docs/COMMITS/v0.1.0-inicial.md +50 -0
- package/docs/COMMITS/v0.1.0-readme.md +24 -0
- package/docs/COMMITS/v0.2.0-strict-db-templates.md +50 -0
- package/docs/COMMITS/v0.3.0-parser-fixes-vscode.md +67 -0
- package/docs/COMMITS/v0.3.0-versioning-component.md +44 -0
- package/docs/DEPENDENCIES.md +45 -0
- package/docs/FRAMEWORK.md +1741 -0
- package/docs/SYNTAX.md +359 -0
- package/docs/VERSIONING.md +150 -0
- package/docs/referencia-metodologia/Anexos Finales Documentos de Respaldo y Estandarizaci/303/263n.md" +90 -0
- package/docs/referencia-metodologia/Cotizaciones.md +84 -0
- package/docs/referencia-metodologia/Example.md +1 -0
- package/docs/referencia-metodologia/ExtractorInformacion.py +78 -0
- package/docs/referencia-metodologia/Fase - 1 .- Desarrollo de la Metodolog/303/255a.md" +67 -0
- package/docs/referencia-metodologia/Fase - 2 .- Levantamiento de requisitos generales y traduccion a la IA.md +64 -0
- package/docs/referencia-metodologia/Fase - 3 .- Prototipado visual con IA (Figma Maker o equivalentes).md +64 -0
- package/docs/referencia-metodologia/Fase - 4 .- Especificacion de requisitos e iteracion con el cliente.md +58 -0
- package/docs/referencia-metodologia/Fase - 5 .- Estructuracion y maquetado de funciones (Scaffolding).md +118 -0
- package/docs/referencia-metodologia/Fase - 6 .- Estructuracion del backlog y division de tareas.md +48 -0
- package/docs/referencia-metodologia/Fase - 7 .- Desarrollo activo, pruebas y control de versiones.md +98 -0
- package/docs/referencia-metodologia/Fase - 8 .- Entrega, capacitaci/303/263n y mantenimiento.md" +55 -0
- package/docs/referencia-metodologia/Figma prompt template.md +130 -0
- package/docs/referencia-metodologia/Framework de Desarrollo Asistido por IA.md +1741 -0
- package/docs/referencia-metodologia/Indice General.md +83 -0
- package/docs/referencia-metodologia/Prompt refactorizar o creacion desde cero.md +50 -0
- package/docs/referencia-metodologia/docs/CONVENCIONES_DB.md +410 -0
- package/docs/referencia-metodologia/docs/CONVENCIONES_DOCUMENTACION.md +209 -0
- package/docs/referencia-metodologia/docs/PROMPTS/INDEX.md +73 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/01-hook-supabase.md +79 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/02-componente-ui.md +82 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/03-pagina-feature.md +70 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/04-comando-tauri.md +56 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/05-store-zustand.md +74 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/06-servicio-supabase.md +74 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/07-formulario-validacion.md +63 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/08-hook-capacitor.md +65 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/09-refactor-division.md +51 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/10-scaffolding-inicial.md +79 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/11-supabase-crud-service.md +114 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/12-supabase-hook-usetable.md +143 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/13-tauri-command-rust.md +84 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/14-tauri-wrapper-typescript.md +92 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/15-documentar-tabla-db.md +50 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/16-diagrama-arquitectura.md +60 -0
- package/docs/referencia-metodologia/docs/PROMPTS/PLANTILLAS/17-documentar-api-rpc.md +56 -0
- package/docs/referencia-metodologia/docs/PROMPTS/STACK/ionic-capacitor.md +52 -0
- package/docs/referencia-metodologia/docs/PROMPTS/STACK/react-web-puro.md +46 -0
- package/docs/referencia-metodologia/docs/PROMPTS/STACK/tauri-desktop.md +53 -0
- package/package.json +56 -0
- package/schemas/prompt-lang.json +98 -0
- package/src/commands/component.js +326 -0
- package/src/commands/context.js +206 -0
- package/src/commands/figma.js +63 -0
- package/src/commands/init.js +373 -0
- package/src/commands/suggest.js +31 -0
- package/src/commands/validate.js +183 -0
- package/src/generators/figma-prompt.js +56 -0
- package/src/utils/ai.js +143 -0
- package/src/utils/annotations.js +510 -0
- package/src/utils/config.js +60 -0
- package/vscode-extension/README.md +31 -0
- package/vscode-extension/language-configuration.json +7 -0
- package/vscode-extension/package.json +62 -0
- package/vscode-extension/snippets/promptlang.json +105 -0
- package/vscode-extension/syntaxes/annotations.tmGrammar.json +39 -0
- package/vscode-extension/syntaxes/promptlang.tmGrammar.json +14 -0
|
@@ -0,0 +1,1741 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Framework de Desarrollo Asistido por IA (openPrompt-Lang)
|
|
3
|
+
tags: [react, ionic, capacitor, vite, tauri, tailwind, react-doctor, patrones, metodologia, prompt-lang]
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
framework: openPrompt-Lang
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Framework de Desarrollo Asistido por IA (openPrompt-Lang)
|
|
9
|
+
|
|
10
|
+
> Este documento es la especificación del framework **openPrompt-Lang**: un sistema de anotaciones y patrones para desarrollo asistido por IA. Combina un **lenguaje de anotaciones** (sección 0) para comunicar restricciones a la IA, con un **catálogo de patrones** para estructurar proyectos **React + TypeScript** (con o sin Ionic/Capacitor/Tauri). Cada proyecto aplica las secciones que necesita según su tipo y alcance.
|
|
11
|
+
>
|
|
12
|
+
> 🔗 **CLI:** `npx openPrompt-Lang` — Ver `docs/SYNTAX.md` para la especificación completa del lenguaje.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 0. Sintaxis del Lenguaje PromptLang
|
|
17
|
+
|
|
18
|
+
> Las anotaciones PromptLang permiten comunicar restricciones exactas a la IA directamente en el código, y ser validadas por el CLI `openPrompt-Lang validate`. Siguen el principio de **prompts deterministas** (sección 9) pero incrustados como comentarios.
|
|
19
|
+
|
|
20
|
+
### 0.1 Sistema de Imports
|
|
21
|
+
|
|
22
|
+
Todo archivo con anotaciones DEBE declarar los tags que usa:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
// @use(kind, contract, limit, deps, platform, scope, meta)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
| Uso | Significado |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `@use(*)` | Todos los tags disponibles |
|
|
31
|
+
| `@use(kind, contract)` | Solo los especificados |
|
|
32
|
+
| Sin `@use` | Modo legacy — sin validación de anotaciones |
|
|
33
|
+
|
|
34
|
+
### 0.2 Tags de Definición
|
|
35
|
+
|
|
36
|
+
| Tag | Sintaxis | Descripción |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `@kind` | `@kind(tipo)` | Define el tipo: `hook`, `component`, `page`, `service`, `store`, `util`, `type`, `layout`, `feature` |
|
|
39
|
+
| `@pattern` | `@pattern(nombre)` | Patrón de diseño: `compound`, `composition`, `generic`, `render-prop` |
|
|
40
|
+
|
|
41
|
+
### 0.3 Tags de Contrato
|
|
42
|
+
|
|
43
|
+
| Tag | Sintaxis | Descripción |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `@contract` | `@contract(in: tipos -> out: tipo @error: tipo)` | Interfaz de función (hooks/services) |
|
|
46
|
+
| `@props` | `@props({ name: tipo, name2?: tipo })` | Props de componente (JSON-like) |
|
|
47
|
+
| `@state` | `@state(loading, empty, error, success)` | Estados visuales del componente |
|
|
48
|
+
|
|
49
|
+
### 0.4 Tags de Restricción
|
|
50
|
+
|
|
51
|
+
| Tag | Sintaxis | Descripción |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| `@limit` | `@limit(lines: N, functions: N)` | Límites del archivo (defaults según @kind) |
|
|
54
|
+
| `@forbidden` | `@forbidden(any, css-modules)` | Prohibiciones explícitas |
|
|
55
|
+
|
|
56
|
+
### 0.5 Tags de Composición y Dependencias
|
|
57
|
+
|
|
58
|
+
| Tag | Sintaxis | Descripción |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| `@compose` | `@compose(CompA, useHookB)` | Dependencias internas del proyecto |
|
|
61
|
+
| `@deps` | `@deps(@external: [lib], @forbidden: [lib])` | Dependencias externas con sub-tags |
|
|
62
|
+
|
|
63
|
+
### 0.6 Tags de Entorno
|
|
64
|
+
|
|
65
|
+
| Tag | Sintaxis | Descripción |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| `@platform` | `@platform(web, mobile, desktop)` | Target de ejecución (con validación cruzada) |
|
|
68
|
+
| `@scope` | `@scope(module: X, affects: [Y], breaking: bool)` | Alcance e impacto del módulo |
|
|
69
|
+
|
|
70
|
+
### 0.7 Tags de Calidad
|
|
71
|
+
|
|
72
|
+
| Tag | Sintaxis | Descripción |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| `@test` | `@test(@unit, @coverage: 80)` | Requisitos de testing |
|
|
75
|
+
| `@meta` | `@meta(@version: "1.0", @tags: [auth])` | Metadatos del archivo |
|
|
76
|
+
|
|
77
|
+
### 0.8 Ejemplo completo
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// @use(kind, contract, limit, deps, platform, scope, meta)
|
|
81
|
+
// @kind(hook)
|
|
82
|
+
// @limit(lines: 75, params: 2)
|
|
83
|
+
// @contract(in: email, password -> out: user, token @error: AuthError)
|
|
84
|
+
// @deps(@external: [supabase], @forbidden: [axios])
|
|
85
|
+
// @platform(web)
|
|
86
|
+
// @scope(module: auth, affects: [login, session], breaking: false)
|
|
87
|
+
// @meta(@version: "1.0.0", @author: "dev", @tags: [auth, supabase])
|
|
88
|
+
export function useAuth() { ... }
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 0.9 Reglas de Validación Cruzada
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
@kind(hook) → @contract REQUERIDO, @props PROHIBIDO, @limit ≤80
|
|
95
|
+
@kind(component) → @props RECOMENDADO, @contract PROHIBIDO, @limit ≤120
|
|
96
|
+
@kind(page) → @compose REQUERIDO, @limit ≤200
|
|
97
|
+
@kind(service) → @contract REQUERIDO, @props/state PROHIBIDO, @limit ≤150
|
|
98
|
+
@kind(store) → @deps(zustand) RECOMENDADO, @limit ≤100
|
|
99
|
+
@kind(type) → @limit/state NO APLICAN
|
|
100
|
+
|
|
101
|
+
@platform(mobile) + @deps(@tauri-apps/*) → ERROR
|
|
102
|
+
@platform(desktop) + @deps(@capacitor/*) → ERROR
|
|
103
|
+
@scope(breaking: true) → commit debe ser breaking change (!)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
> 📖 **Especificación completa:** `docs/SYNTAX.md` en el repositorio del framework.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
### Guía de adaptación por tipo de proyecto
|
|
111
|
+
|
|
112
|
+
| Tipo de proyecto | Secciones esenciales | Secciones opcionales | Secciones recomendadas |
|
|
113
|
+
|---|---|---|---|
|
|
114
|
+
| **Prototipo / MVP rápido** (1-2 semanas, freelance) | 2, 6, 7, 9, 10 | 3, 4, 8, 11 | 5 (solo PHASE-1) |
|
|
115
|
+
| **Proyecto completo con cliente** (SaaS, app nativa) | 1, 2, 5, 6, 7, 9, 10, 12 | 3, 4, 8, 11, 13, 14 | Todo |
|
|
116
|
+
| **Web puro** (Sin Tauri/Ionic, solo React + Supabase) | 2, 5, 6, 7, 8, 9, 10 | 3, 4, 11, 12 | Ignorar referencias a Capacitor/Tauri |
|
|
117
|
+
| **Side project personal** | 2, 6, 7, 9 | 3, 5, 10 | 4 (solo ACTIVIDAD, sin ERRORES) |
|
|
118
|
+
| **App desktop** (Tauri sin mobile) | 1, 2, 6, 7, 9, 10 | 3, 4, 5, 8, 11 | Ignorar secciones de Ionic/Capacitor |
|
|
119
|
+
|
|
120
|
+
> **Regla práctica:** Si estás en fase de descubrimiento o prototipo, aplica solo secciones 2, 6, 7, 9 y 10. El resto se incorpora cuando el proyecto se formaliza con cliente o presupuesto.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Índice
|
|
125
|
+
|
|
126
|
+
0. [Sintaxis del Lenguaje PromptLang](#0-sintaxis-del-lenguaje-promptlang)
|
|
127
|
+
- [0.1 Sistema de Imports](#01-sistema-de-imports)
|
|
128
|
+
- [0.2 Tags de Definición](#02-tags-de-definición)
|
|
129
|
+
- [0.3 Tags de Contrato](#03-tags-de-contrato)
|
|
130
|
+
- [0.4 Tags de Restricción](#04-tags-de-restricción)
|
|
131
|
+
- [0.5 Tags de Composición y Dependencias](#05-tags-de-composición-y-dependencias)
|
|
132
|
+
- [0.6 Tags de Entorno](#06-tags-de-entorno)
|
|
133
|
+
- [0.7 Tags de Calidad](#07-tags-de-calidad)
|
|
134
|
+
- [0.8 Ejemplo completo](#08-ejemplo-completo)
|
|
135
|
+
- [0.9 Reglas de Validación Cruzada](#09-reglas-de-validación-cruzada)
|
|
136
|
+
0a. [Guía de adaptación por tipo de proyecto](#guía-de-adaptación-por-tipo-de-proyecto)
|
|
137
|
+
1. [Stack Tecnológico y Convenciones](#1-stack-tecnológico-y-convenciones)
|
|
138
|
+
2. [Estructura de Carpetas Universal](#2-estructura-de-carpetas-universal)
|
|
139
|
+
3. [Sistema de Commits y Bitácora](#3-sistema-de-commits-y-bitácora)
|
|
140
|
+
4. [Sistema de Logs de Errores y Actividad](#4-sistema-de-logs-de-errores-y-actividad)
|
|
141
|
+
- [4.1 Automatización de Logs con Scripts](#41-automatización-de-logs-con-scripts)
|
|
142
|
+
5. [Backlog por Prioridades y Fases](#5-backlog-por-prioridades-y-fases)
|
|
143
|
+
6. [Reglas de Componentes y Modularización](#6-reglas-de-componentes-y-modularización)
|
|
144
|
+
7. [Patrones React + Tailwind para Reutilización](#7-patrones-react--tailwind-para-reutilización)
|
|
145
|
+
8. [Integración con react-doctor](#8-integración-con-react-doctor)
|
|
146
|
+
9. [Estructura de Prompts — Correcto vs Incorrecto](#9-estructura-de-prompts--correcto-vs-incorrecto)
|
|
147
|
+
10. [Flujo de Trabajo Diario con IA](#10-flujo-de-trabajo-diario-con-ia)
|
|
148
|
+
11. [Pipeline de Validación Automática](#11-pipeline-de-validación-automática)
|
|
149
|
+
12. [Phase Gates — CheckList de Salida por Fase](#12-phase-gates--checklist-de-salida-por-fase)
|
|
150
|
+
13. [Retrospectiva por Iteración](#13-retrospectiva-por-iteración)
|
|
151
|
+
14. [Perfiles de Desarrollador](#14-perfiles-de-desarrollador)
|
|
152
|
+
15. [Biblioteca de Prompts (docs/PROMPTS/)](#15-biblioteca-de-prompts-docsprompts)
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 1. Stack Tecnológico y Convenciones
|
|
157
|
+
|
|
158
|
+
### Stack base
|
|
159
|
+
|
|
160
|
+
> ⚡ **Stack base obligatorio:** React + TypeScript + Vite + Tailwind. Ionic, Capacitor y Tauri son **opcionales** según el tipo de proyecto (web, mobile, desktop). Si tu proyecto es web puro, omite las secciones que referencien Capacitor/Tauri.
|
|
161
|
+
|
|
162
|
+
| Tecnología | Versión Objetivo | Propósito | Obligatorio |
|
|
163
|
+
|---|---|---|---|
|
|
164
|
+
| React 18+ | ^18.3 | UI declarativa con hooks | ✅ |
|
|
165
|
+
| TypeScript | ^5.4 | Tipado estricto | ✅ |
|
|
166
|
+
| Vite | ^5.x | Build tool / dev server | ✅ |
|
|
167
|
+
| Tailwind CSS | ^3.4 | Utility-first styling | ✅ |
|
|
168
|
+
| react-doctor | última | Auditoría de buenas prácticas React | Recomendado |
|
|
169
|
+
| Ionic Framework | ^8.x | Componentes nativos y UI mobile-first | Solo si hay mobile |
|
|
170
|
+
| Capacitor | ^6.x | Acceso nativo (cámara, GPS, etc.) | Solo si hay mobile |
|
|
171
|
+
| Tauri | ^2.x | Desktop nativo (Windows/Mac/Linux) | Solo si hay desktop |
|
|
172
|
+
|
|
173
|
+
### Convenciones generales del stack base (siempre aplican)
|
|
174
|
+
|
|
175
|
+
- **Tailwind utility-first**: Sin CSS personalizado. 100% clases de utilidad.
|
|
176
|
+
- **Componentes atómicos en `components/ui/`**: Primitivas reutilizables con variantes (cva).
|
|
177
|
+
- **Custom hooks para toda lógica reutilizable**: Nada de lógica en componentes.
|
|
178
|
+
- **Composition > Inheritance**: Usar children, render props y compound components.
|
|
179
|
+
|
|
180
|
+
### Convenciones para stacks extendidos (solo si aplican)
|
|
181
|
+
|
|
182
|
+
- **Ionic solo para UI mobile-first**: Usar componentes `<IonPage>`, `<IonContent>`, `<IonButton>`, etc. en vistas mobile. En desktop se renderizan con Tauri y se prefiere UI propia con Tailwind.
|
|
183
|
+
- **Capacitor como puente nativo**: Toda la lógica de plugins nativos (cámara, notificaciones, almacenamiento) va encapsulada en hooks con prefijo `useCapacitor*`.
|
|
184
|
+
- **Tauri para desktop**: Los comandos de Tauri (Rust) se llaman desde servicios en `src/services/tauri/`. NO mezclar lógica de Tauri con lógica de Capacitor en el mismo archivo.
|
|
185
|
+
- **Vite como orchestrator**: Vite configura tanto el build web como el de Tauri. No modificar `vite.config.ts` sin documentar el cambio.
|
|
186
|
+
|
|
187
|
+
### Configuración de react-doctor
|
|
188
|
+
|
|
189
|
+
> react-doctor analiza tu código React en busca de anti-patrones. Se ejecuta como parte del lint/pre-commit.
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"rules": {
|
|
194
|
+
"react-hooks/exhaustive-deps": "error",
|
|
195
|
+
"react/no-unused-prop-types": "warn",
|
|
196
|
+
"react/jsx-no-duplicate-props": "error",
|
|
197
|
+
"hooks-rules": "error",
|
|
198
|
+
"no-unnecessary-context": "warn",
|
|
199
|
+
"component-complexity": ["warn", { "max-lines": 120, "max-functions": 5 }],
|
|
200
|
+
"no-class-components": "error"
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Ejecutar react-doctor antes de cada commit:**
|
|
206
|
+
```bash
|
|
207
|
+
npx react-doctor check ./src
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## 2. Estructura de Carpetas Universal
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
/
|
|
216
|
+
├── src/
|
|
217
|
+
│ ├── components/
|
|
218
|
+
│ │ ├── ui/ # Primitive components (Button, Input, Card, Modal)
|
|
219
|
+
│ │ │ ├── Button.tsx
|
|
220
|
+
│ │ │ ├── Input.tsx
|
|
221
|
+
│ │ │ ├── index.ts # Barrel export
|
|
222
|
+
│ │ ├── layout/ # App shell (Navbar, Sidebar, Tabs)
|
|
223
|
+
│ │ │ ├── AppShell.tsx
|
|
224
|
+
│ │ │ ├── MobileNav.tsx
|
|
225
|
+
│ │ │ └── DesktopSidebar.tsx
|
|
226
|
+
│ │ └── shared/ # Shared domain components (UserAvatar, EmptyState)
|
|
227
|
+
│ ├── features/ # Feature modules, each is a domain
|
|
228
|
+
│ │ ├── auth/
|
|
229
|
+
│ │ │ ├── components/ # Feature-specific components
|
|
230
|
+
│ │ │ ├── hooks/ # Feature-specific hooks
|
|
231
|
+
│ │ │ ├── services/ # Feature API calls
|
|
232
|
+
│ │ │ ├── types/ # Feature-specific types
|
|
233
|
+
│ │ │ ├── LoginPage.tsx
|
|
234
|
+
│ │ │ └── RegisterPage.tsx
|
|
235
|
+
│ │ ├── dashboard/
|
|
236
|
+
│ │ └── products/
|
|
237
|
+
│ ├── hooks/ # Global reusable hooks
|
|
238
|
+
│ │ ├── useAuth.ts
|
|
239
|
+
│ │ ├── useCapacitorCamera.ts
|
|
240
|
+
│ │ ├── useTauriCommand.ts
|
|
241
|
+
│ │ ├── useLocalStorage.ts
|
|
242
|
+
│ │ └── useDebounce.ts
|
|
243
|
+
│ ├── services/ # API clients, external integrations
|
|
244
|
+
│ │ ├── api/
|
|
245
|
+
│ │ ├── supabase/
|
|
246
|
+
│ │ └── tauri/ # Tauri IPC commands
|
|
247
|
+
│ ├── store/ # Global state (Zustand recommended)
|
|
248
|
+
│ │ ├── authStore.ts
|
|
249
|
+
│ │ └── uiStore.ts
|
|
250
|
+
│ ├── types/ # Global TypeScript interfaces
|
|
251
|
+
│ │ └── global.d.ts
|
|
252
|
+
│ ├── utils/ # Pure utility functions
|
|
253
|
+
│ │ ├── formatDate.ts
|
|
254
|
+
│ │ ├── validators.ts
|
|
255
|
+
│ │ └── constants.ts
|
|
256
|
+
│ ├── views/ # Page-level components (routing targets)
|
|
257
|
+
│ │ ├── Home.tsx
|
|
258
|
+
│ │ └── Profile.tsx
|
|
259
|
+
│ ├── App.tsx
|
|
260
|
+
│ ├── main.tsx
|
|
261
|
+
│ └── router.tsx
|
|
262
|
+
├── docs/ # Project documentation
|
|
263
|
+
│ ├── COMMITS/ # Commit logs folder
|
|
264
|
+
│ ├── LOGS/ # Error and activity logs
|
|
265
|
+
│ ├── BACKLOG/ # Backlog and task distribution
|
|
266
|
+
│ └── ARCHITECTURE.md
|
|
267
|
+
├── tauri/ # Tauri Rust source (auto-generated)
|
|
268
|
+
├── capacitor/ # Capacitor platform configs (auto-generated)
|
|
269
|
+
├── android/
|
|
270
|
+
├── ios/
|
|
271
|
+
├── tailwind.config.ts
|
|
272
|
+
├── vite.config.ts
|
|
273
|
+
├── tsconfig.json
|
|
274
|
+
├── package.json
|
|
275
|
+
└── AGENTS.md # AI context file (resumen para prompts)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Regla de crecimiento de carpetas
|
|
279
|
+
|
|
280
|
+
- **/components/ui/**: Un archivo por componente. Máximo 150 líneas. Si supera, se divide en subcomponentes atómicos.
|
|
281
|
+
- **/features/**: Una carpeta por dominio de negocio. Si un feature supera 10 archivos, se evalúa dividirlo en subfeatures.
|
|
282
|
+
- **/hooks/**: Un hook por archivo. Máximo 80 líneas. Si un hook requiere más, se refactoriza en hooks más pequeños o se mueve lógica a utils.
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## 3. Sistema de Commits y Bitácora
|
|
287
|
+
|
|
288
|
+
> 💡 **Cuándo aplicar esta sección:** La bitácora detallada con archivos por versión es para **proyectos formales con cliente**. En prototipos y MVPs basta con commits convencionales bien escritos. Si el proyecto es personal o exploratorio, usa solo los tipos de commit y salta la carpeta `docs/COMMITS/`.
|
|
289
|
+
|
|
290
|
+
### Carpeta de Commits
|
|
291
|
+
|
|
292
|
+
Cada proyecto debe tener `docs/COMMITS/` con un archivo por versión o milestone:
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
docs/COMMITS/
|
|
296
|
+
├── INDEX.md # Índice cronológico de todos los commits
|
|
297
|
+
├── v0.1.0-inicial.md # Commit log de la versión inicial
|
|
298
|
+
├── v0.2.0-auth.md
|
|
299
|
+
└── v0.3.0-dashboard.md
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Formato de cada commit en el log
|
|
303
|
+
|
|
304
|
+
```markdown
|
|
305
|
+
## [v0.1.0] - 2026-05-13
|
|
306
|
+
|
|
307
|
+
### Commit: feat(auth): implementar registro de usuario con Supabase
|
|
308
|
+
**Hash:** a1b2c3d4e5f6...
|
|
309
|
+
**Fecha:** 2026-05-13 14:30
|
|
310
|
+
**Módulo:** auth
|
|
311
|
+
**Versión:** v0.1.0
|
|
312
|
+
|
|
313
|
+
#### Cambios realizados
|
|
314
|
+
- Se creó `AuthService.register()` con validación de email único
|
|
315
|
+
- Se agregó hook `useAuth` con estado de sesión
|
|
316
|
+
- Se integró componente `LoginForm` con validación en tiempo real
|
|
317
|
+
|
|
318
|
+
#### Archivos modificados
|
|
319
|
+
- `src/features/auth/services/AuthService.ts` (+45 líneas)
|
|
320
|
+
- `src/features/auth/hooks/useAuth.ts` (+32 líneas)
|
|
321
|
+
- `src/features/auth/components/LoginForm.tsx` (+78 líneas)
|
|
322
|
+
|
|
323
|
+
#### Criterios de aceptación cumplidos
|
|
324
|
+
- [x] Registro con email y contraseña funciona
|
|
325
|
+
- [x] Validación de email duplicado retorna error claro
|
|
326
|
+
- [x] Toast de éxito/error visible para el usuario
|
|
327
|
+
|
|
328
|
+
#### Notas
|
|
329
|
+
- Pendiente: agregar recovery de contraseña en siguiente iteración
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Template para crear un nuevo commit log
|
|
333
|
+
|
|
334
|
+
```markdown
|
|
335
|
+
## [v{version}] - {fecha}
|
|
336
|
+
|
|
337
|
+
### Commit: {tipo}({modulo}): {descripción breve}
|
|
338
|
+
**Hash:** {hash}
|
|
339
|
+
**Fecha:** {fecha-hora}
|
|
340
|
+
**Módulo:** {modulo}
|
|
341
|
+
**Versión:** v{version}
|
|
342
|
+
|
|
343
|
+
#### Cambios realizados
|
|
344
|
+
- {cambio 1}
|
|
345
|
+
- {cambio 2}
|
|
346
|
+
- {cambio 3}
|
|
347
|
+
|
|
348
|
+
#### Archivos modificados
|
|
349
|
+
- `{ruta}` (+{líneas} líneas)
|
|
350
|
+
- `{ruta}` (+{líneas} líneas)
|
|
351
|
+
|
|
352
|
+
#### Criterios de aceptación cumplidos
|
|
353
|
+
- [ ] {criterio 1}
|
|
354
|
+
- [ ] {criterio 2}
|
|
355
|
+
|
|
356
|
+
#### Notas
|
|
357
|
+
{notas}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Tipos de commit (Conventional Commits)
|
|
361
|
+
|
|
362
|
+
| Tipo | Cuándo usarlo |
|
|
363
|
+
|---|---|
|
|
364
|
+
| `feat` | Nueva funcionalidad |
|
|
365
|
+
| `fix` | Corrección de bug |
|
|
366
|
+
| `refactor` | Cambio de estructura sin cambiar comportamiento |
|
|
367
|
+
| `style` | Cambios de UI/CSS sin lógica nueva |
|
|
368
|
+
| `docs` | Documentación |
|
|
369
|
+
| `chore` | Configuración, dependencias, tooling |
|
|
370
|
+
| `perf` | Optimización de rendimiento |
|
|
371
|
+
| `test` | Agregar o modificar tests |
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
## 4. Sistema de Logs de Errores y Actividad
|
|
376
|
+
|
|
377
|
+
> 💡 **Cuándo aplicar esta sección:** Los logs detallados están pensados para **proyectos con cliente o producción**. En prototipos y MVPs rápidos, usa solo `ACTIVIDAD/` (log diario) y salta `ERRORES/` hasta que el proyecto se estabilice. El objetivo es ayudar, no frenar.
|
|
378
|
+
|
|
379
|
+
### Estructura de carpetas
|
|
380
|
+
|
|
381
|
+
```
|
|
382
|
+
docs/LOGS/
|
|
383
|
+
├── INDEX.md # Índice de todos los logs
|
|
384
|
+
├── ERRORES/ # Errores organizados por tipo
|
|
385
|
+
│ ├── AUTENTICACION/ # Errores de auth
|
|
386
|
+
│ │ └── 2026-05-13-login-401.md
|
|
387
|
+
│ ├── API/ # Errores de peticiones HTTP
|
|
388
|
+
│ │ └── 2026-05-13-supabase-timeout.md
|
|
389
|
+
│ ├── UI/ # Errores de renderizado / componentes
|
|
390
|
+
│ │ └── 2026-05-13-modal-no-cierra.md
|
|
391
|
+
│ ├── NATIVO/ # Errores de Capacitor / Tauri
|
|
392
|
+
│ │ └── 2026-05-13-camara-permiso-denegado.md
|
|
393
|
+
│ ├── ESTADO/ # Errores de estado global (Zustand/Redux)
|
|
394
|
+
│ │ └── 2026-05-13-store-reset.md
|
|
395
|
+
│ └── COMPILACION/ # Errores de build / TypeScript
|
|
396
|
+
│ └── 2026-05-13-type-mismatch.md
|
|
397
|
+
├── ACTIVIDAD/ # Registro de actividad general
|
|
398
|
+
│ ├── 2026-05/
|
|
399
|
+
│ │ ├── 2026-05-13.md
|
|
400
|
+
│ │ └── 2026-05-14.md
|
|
401
|
+
│ └── INDEX.md
|
|
402
|
+
└── FUNCIONALIDADES/ # Registro de funcionalidades implementadas
|
|
403
|
+
├── modulo-auth.md
|
|
404
|
+
├── modulo-dashboard.md
|
|
405
|
+
└── INDEX.md
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Formato para registro de error
|
|
409
|
+
|
|
410
|
+
```markdown
|
|
411
|
+
# Error: {Título descriptivo}
|
|
412
|
+
|
|
413
|
+
**Fecha:** 2026-05-13 15:45
|
|
414
|
+
**Tipo:** API / UI / NATIVO / ESTADO / COMPILACION
|
|
415
|
+
**Severidad:** CRITICAL / HIGH / MEDIUM / LOW
|
|
416
|
+
**Módulo:** auth / dashboard / products
|
|
417
|
+
**Contexto:** {qué estaba haciendo el usuario o el sistema}
|
|
418
|
+
|
|
419
|
+
## Descripción
|
|
420
|
+
{Descripción clara del error}
|
|
421
|
+
|
|
422
|
+
## Traza / Log
|
|
423
|
+
```
|
|
424
|
+
{stack trace o mensaje de error relevante}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
## Causa raíz
|
|
428
|
+
{qué lo provocó}
|
|
429
|
+
|
|
430
|
+
## Solución aplicada
|
|
431
|
+
{cómo se solucionó, con referencias a commits si aplica}
|
|
432
|
+
|
|
433
|
+
## Prevención
|
|
434
|
+
{cómo evitar que vuelva a ocurrir}
|
|
435
|
+
|
|
436
|
+
## Archivos relacionados
|
|
437
|
+
- `src/features/auth/services/AuthService.ts:45`
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Formato para registro de actividad
|
|
441
|
+
|
|
442
|
+
```markdown
|
|
443
|
+
# Actividad — 2026-05-13
|
|
444
|
+
|
|
445
|
+
## Sesión de trabajo: Implementación de autenticación
|
|
446
|
+
**Duración:** 14:00 - 17:30 (3.5h)
|
|
447
|
+
**Objetivo:** Completar flujo de registro + login
|
|
448
|
+
|
|
449
|
+
### Tareas realizadas
|
|
450
|
+
1. ✅ Hook `useAuth` — lógica de sesión completa
|
|
451
|
+
2. ✅ Componente `LoginForm` — validación y submit
|
|
452
|
+
3. ⏳ `PasswordRecovery` — pendiente
|
|
453
|
+
4. ❌ Tests de auth — pospuesto por error en mock
|
|
454
|
+
|
|
455
|
+
### Errores encontrados
|
|
456
|
+
- **Error #001** — Supabase timeout en registro (API)
|
|
457
|
+
→ Solución: agregar retry con exponential backoff
|
|
458
|
+
|
|
459
|
+
### Decisiones tomadas
|
|
460
|
+
- Se usa Zustand en lugar de Context para auth state (mejor performance)
|
|
461
|
+
|
|
462
|
+
### Próxima sesión
|
|
463
|
+
- Completar `PasswordRecovery`
|
|
464
|
+
- Escribir tests con Vitest
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
### 4.1 Automatización de Logs con Scripts
|
|
470
|
+
|
|
471
|
+
Para reducir la fricción y evitar que los logs se abandonen, se proveen scripts que automatizan parte del registro.
|
|
472
|
+
|
|
473
|
+
#### Script: `scripts/log-error.sh`
|
|
474
|
+
|
|
475
|
+
Genera un archivo de error con la estructura pre-llenada. Ubicar en `scripts/log-error.sh`:
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
#!/bin/bash
|
|
479
|
+
# Uso: ./scripts/log-error.sh "Título del error" API HIGH auth
|
|
480
|
+
|
|
481
|
+
TITLE="$1"
|
|
482
|
+
TYPE="$2"
|
|
483
|
+
SEVERITY="$3"
|
|
484
|
+
MODULE="$4"
|
|
485
|
+
DATE=$(date +%Y-%m-%d)
|
|
486
|
+
TIME=$(date +%H:%M)
|
|
487
|
+
FILENAME="docs/LOGS/ERRORES/${TYPE}/$(date +%Y-%m-%d)-$(echo $TITLE | tr '[:upper:]' '[:lower:]' | tr ' ' '-').md"
|
|
488
|
+
|
|
489
|
+
mkdir -p "docs/LOGS/ERRORES/${TYPE}"
|
|
490
|
+
|
|
491
|
+
cat > "$FILENAME" << EOF
|
|
492
|
+
# Error: ${TITLE}
|
|
493
|
+
|
|
494
|
+
**Fecha:** ${DATE} ${TIME}
|
|
495
|
+
**Tipo:** ${TYPE}
|
|
496
|
+
**Severidad:** ${SEVERITY}
|
|
497
|
+
**Módulo:** ${MODULE}
|
|
498
|
+
**Contexto:**
|
|
499
|
+
|
|
500
|
+
## Descripción
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
## Traza / Log
|
|
504
|
+
\`\`\`
|
|
505
|
+
|
|
506
|
+
\`\`\`
|
|
507
|
+
|
|
508
|
+
## Causa raíz
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
## Solución aplicada
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
## Prevención
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
## Archivos relacionados
|
|
518
|
+
|
|
519
|
+
EOF
|
|
520
|
+
|
|
521
|
+
echo "Log creado: $FILENAME"
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
#### Script: `scripts/log-commit.sh`
|
|
525
|
+
|
|
526
|
+
Toma el último commit de git y genera la entrada en `docs/COMMITS/`:
|
|
527
|
+
|
|
528
|
+
```bash
|
|
529
|
+
#!/bin/bash
|
|
530
|
+
# Uso: ./scripts/log-commit.sh
|
|
531
|
+
|
|
532
|
+
HASH=$(git log -1 --format="%H")
|
|
533
|
+
DATE=$(git log -1 --format="%ad" --date=short)
|
|
534
|
+
MSG=$(git log -1 --format="%s")
|
|
535
|
+
FILES=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || git diff --name-only HEAD)
|
|
536
|
+
VERSION=$(git tag --points-at HEAD | head -1)
|
|
537
|
+
|
|
538
|
+
FILENAME="docs/COMMITS/${VERSION:-sin-version}-$(date +%Y%m%d).md"
|
|
539
|
+
|
|
540
|
+
cat > "$FILENAME" << EOF
|
|
541
|
+
## [${VERSION:-sin-version}] - ${DATE}
|
|
542
|
+
|
|
543
|
+
### Commit: ${MSG}
|
|
544
|
+
**Hash:** ${HASH}
|
|
545
|
+
**Fecha:** ${DATE}
|
|
546
|
+
**Módulo:**
|
|
547
|
+
**Versión:** ${VERSION:-sin-version}
|
|
548
|
+
|
|
549
|
+
#### Cambios realizados
|
|
550
|
+
- $(echo "$MSG" | sed 's/^/\n- /')
|
|
551
|
+
|
|
552
|
+
#### Archivos modificados
|
|
553
|
+
$(echo "$FILES" | sed 's/^/- `/' | sed 's/$/`/')
|
|
554
|
+
|
|
555
|
+
#### Criterios de aceptación cumplidos
|
|
556
|
+
- [ ]
|
|
557
|
+
|
|
558
|
+
#### Notas
|
|
559
|
+
|
|
560
|
+
EOF
|
|
561
|
+
|
|
562
|
+
echo "Commit log creado: $FILENAME"
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
#### Script: `scripts/log-actividad.sh`
|
|
566
|
+
|
|
567
|
+
Inicia o continúa el log de actividad diaria:
|
|
568
|
+
|
|
569
|
+
```bash
|
|
570
|
+
#!/bin/bash
|
|
571
|
+
# Uso: ./scripts/log-actividad.sh "Objetivo de la sesión"
|
|
572
|
+
|
|
573
|
+
DATE=$(date +%Y-%m-%d)
|
|
574
|
+
DIR="docs/LOGS/ACTIVIDAD/$(date +%Y-%m)"
|
|
575
|
+
mkdir -p "$DIR"
|
|
576
|
+
FILENAME="${DIR}/${DATE}.md"
|
|
577
|
+
|
|
578
|
+
if [ ! -f "$FILENAME" ]; then
|
|
579
|
+
cat > "$FILENAME" << EOF
|
|
580
|
+
# Actividad — ${DATE}
|
|
581
|
+
|
|
582
|
+
## Sesión de trabajo: $1
|
|
583
|
+
**Duración:**
|
|
584
|
+
**Objetivo:** $1
|
|
585
|
+
|
|
586
|
+
### Tareas realizadas
|
|
587
|
+
1.
|
|
588
|
+
|
|
589
|
+
### Errores encontrados
|
|
590
|
+
|
|
591
|
+
### Decisiones tomadas
|
|
592
|
+
|
|
593
|
+
### Próxima sesión
|
|
594
|
+
|
|
595
|
+
EOF
|
|
596
|
+
echo "Log de actividad creado: $FILENAME"
|
|
597
|
+
else
|
|
598
|
+
echo "Log ya existe: $FILENAME"
|
|
599
|
+
echo "Agrega manualmente las tareas al final del archivo."
|
|
600
|
+
fi
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
> **Dar permisos de ejecución:** `chmod +x scripts/*.sh`
|
|
604
|
+
|
|
605
|
+
### Estructura del backlog
|
|
606
|
+
|
|
607
|
+
Cada proyecto debe tener `docs/BACKLOG/` con:
|
|
608
|
+
|
|
609
|
+
```
|
|
610
|
+
docs/BACKLOG/
|
|
611
|
+
├── INDEX.md # Estado general del proyecto
|
|
612
|
+
├── PHASE-1-core.md # Fase 1: Funcionalidades núcleo
|
|
613
|
+
├── PHASE-2-enhancement.md # Fase 2: Mejoras
|
|
614
|
+
├── PHASE-3-polish.md # Fase 3: Pulido y optimización
|
|
615
|
+
├── icebox.md # Ideas futuras (congeladas)
|
|
616
|
+
└── progreso.json # Tracking automatizado
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
### Distribución de prioridades por fase
|
|
620
|
+
|
|
621
|
+
| Fase | Enfoque | % del proyecto | Prioridades |
|
|
622
|
+
|---|---|---|---|
|
|
623
|
+
| **PHASE-1 Core** | MVP funcional — lo mínimo indispensable | 50% | P0 (Crítico) |
|
|
624
|
+
| **PHASE-2 Enhancement** | Características secundarias y UX | 30% | P1 (Importante) |
|
|
625
|
+
| **PHASE-3 Polish** | Optimización, tests, accesibilidad | 20% | P2 (Deseable) |
|
|
626
|
+
|
|
627
|
+
### Formato de tarea en backlog
|
|
628
|
+
|
|
629
|
+
```markdown
|
|
630
|
+
### [P0] TASK-001: Implementar login con email y contraseña
|
|
631
|
+
**Módulo:** auth
|
|
632
|
+
**Estimación:** 4h
|
|
633
|
+
**Dependencias:** Ninguna
|
|
634
|
+
**Criterios de aceptación:**
|
|
635
|
+
- [ ] Formulario con validación de email (regex) y contraseña (mín 8 chars)
|
|
636
|
+
- [ ] Llamada a Supabase Auth.signInWithPassword()
|
|
637
|
+
- [ ] Manejo de error: "Credenciales inválidas" en rojo
|
|
638
|
+
- [ ] Redirección a dashboard tras login exitoso
|
|
639
|
+
- [ ] Perspectiva de testing: Vitest con mocks de Supabase
|
|
640
|
+
|
|
641
|
+
**Notas:** Usar hook `useAuth` ya creado en scaffolding
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
### Regla de granularidad (Micro-Tasking)
|
|
645
|
+
|
|
646
|
+
> **Cada tarea individual NO debe requerir más de 1-2 prompts a la IA.**
|
|
647
|
+
> Si una tarea requiere más de 3 prompts, está mal dividida.
|
|
648
|
+
|
|
649
|
+
Señales de que una tarea es demasiado grande:
|
|
650
|
+
- La descripción tiene más de 3 criterios de aceptación
|
|
651
|
+
- Involucra 3 o más archivos por crear
|
|
652
|
+
- Mezcla UI + lógica de negocio + API
|
|
653
|
+
- Requiere cambios en más de un módulo/feature
|
|
654
|
+
|
|
655
|
+
---
|
|
656
|
+
|
|
657
|
+
## 6. Reglas de Componentes y Modularización
|
|
658
|
+
|
|
659
|
+
### Límites estrictos por archivo
|
|
660
|
+
|
|
661
|
+
| Tipo de archivo | Límite máximo | Acción al superarlo |
|
|
662
|
+
|---|---|---|
|
|
663
|
+
| Componente UI (tsx) | **120 líneas** | Dividir en subcomponentes y extraer lógica a hooks |
|
|
664
|
+
| Hook (ts/tsx) | **80 líneas** | Dividir en hooks más pequeños o mover lógica a utils |
|
|
665
|
+
| Servicio (ts) | **150 líneas** | Separar por entidad o método |
|
|
666
|
+
| Utilidad (ts) | **100 líneas** | Mover a archivo dedicado por función |
|
|
667
|
+
| Feature Page (tsx) | **200 líneas** | Extraer secciones a componentes en `components/` |
|
|
668
|
+
| Store (ts) | **100 líneas** | Dividir en slices por dominio |
|
|
669
|
+
| Test (ts/tsx) | **150 líneas** | Separar por funcionalidad probada |
|
|
670
|
+
|
|
671
|
+
### Reglas de separación automática
|
|
672
|
+
|
|
673
|
+
Cuando un archivo supera el límite, se aplica este protocolo:
|
|
674
|
+
|
|
675
|
+
1. **Identificar secciones claras**: Buscar bloques de código que puedan vivir independientemente (funciones, componentes hijos, tipos).
|
|
676
|
+
2. **Extraer a archivo dedicado**: Mover a la carpeta correspondiente.
|
|
677
|
+
3. **Actualizar imports**: El archivo original importa desde el nuevo archivo.
|
|
678
|
+
4. **Registrar en commit log**: Documentar la refactorización.
|
|
679
|
+
|
|
680
|
+
### Señales de que un componente debe dividirse
|
|
681
|
+
|
|
682
|
+
- ✅ El componente tiene más de 3 estados visuales distintos
|
|
683
|
+
- ✅ El JSX tiene más de 3 niveles de anidación profunda
|
|
684
|
+
- ✅ Hay lógica condicional extensa (> 3 if/switch)
|
|
685
|
+
- ✅ Se mezclan preocupaciones de negocio con presentación
|
|
686
|
+
- ✅ El nombre del archivo incluye "Utils" o "Helpers" dentro del mismo componente
|
|
687
|
+
- ✅ Hay fragmentos JSX que se repiten con variaciones menores
|
|
688
|
+
|
|
689
|
+
### Ejemplo de mala vs buena modularización
|
|
690
|
+
|
|
691
|
+
**INCORRECTO** — Todo en un archivo de 540 líneas:
|
|
692
|
+
```tsx
|
|
693
|
+
// ProfilePage.tsx — 540 líneas
|
|
694
|
+
function ProfilePage() {
|
|
695
|
+
// 120 líneas de lógica de usuario
|
|
696
|
+
// 80 líneas de subcomponente de avatar
|
|
697
|
+
// 90 líneas de formulario de edición
|
|
698
|
+
// 70 líneas de listado de órdenes
|
|
699
|
+
// 180 líneas de JSX combinado
|
|
700
|
+
}
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
**CORRECTO** — Separado en varios archivos:
|
|
704
|
+
```tsx
|
|
705
|
+
// features/profile/ProfilePage.tsx — 80 líneas (solo composición)
|
|
706
|
+
// features/profile/components/ProfileHeader.tsx — 50 líneas
|
|
707
|
+
// features/profile/components/ProfileForm.tsx — 90 líneas
|
|
708
|
+
// features/profile/components/OrderList.tsx — 70 líneas
|
|
709
|
+
// features/profile/hooks/useProfile.ts — 60 líneas
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
---
|
|
713
|
+
|
|
714
|
+
## 7. Patrones React + Tailwind para Reutilización
|
|
715
|
+
|
|
716
|
+
### Principios de reutilización
|
|
717
|
+
|
|
718
|
+
1. **Composition > Inheritance**: Usar children, render props y compound components.
|
|
719
|
+
2. **Custom hooks para lógica**: Extraer lógica repetitiva a hooks.
|
|
720
|
+
3. **Componentes UI atómicos**: Crear primitivas en `components/ui/` con variantes (cva).
|
|
721
|
+
4. **Tailwind utility-first**: Sin CSS personalizado. 100% Tailwind clases.
|
|
722
|
+
5. **Tipado genérico**: Usar `<T>` en componentes de datos (tablas, listas, selects).
|
|
723
|
+
|
|
724
|
+
### Patrón de componente UI reutilizable (shadcn-style)
|
|
725
|
+
|
|
726
|
+
```tsx
|
|
727
|
+
// components/ui/Button.tsx
|
|
728
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
729
|
+
import { memo } from "react"
|
|
730
|
+
|
|
731
|
+
const buttonVariants = cva(
|
|
732
|
+
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
733
|
+
{
|
|
734
|
+
variants: {
|
|
735
|
+
variant: {
|
|
736
|
+
primary: "bg-blue-600 text-white hover:bg-blue-700",
|
|
737
|
+
secondary: "bg-gray-100 text-gray-900 hover:bg-gray-200",
|
|
738
|
+
destructive: "bg-red-600 text-white hover:bg-red-700",
|
|
739
|
+
ghost: "hover:bg-gray-100 hover:text-gray-900",
|
|
740
|
+
},
|
|
741
|
+
size: {
|
|
742
|
+
default: "h-10 px-4 py-2",
|
|
743
|
+
sm: "h-9 rounded-md px-3",
|
|
744
|
+
lg: "h-11 rounded-md px-8",
|
|
745
|
+
icon: "h-10 w-10",
|
|
746
|
+
},
|
|
747
|
+
},
|
|
748
|
+
defaultVariants: {
|
|
749
|
+
variant: "primary",
|
|
750
|
+
size: "default",
|
|
751
|
+
},
|
|
752
|
+
}
|
|
753
|
+
)
|
|
754
|
+
|
|
755
|
+
interface ButtonProps
|
|
756
|
+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
757
|
+
VariantProps<typeof buttonVariants> {}
|
|
758
|
+
|
|
759
|
+
const Button = memo<ButtonProps>(({ className, variant, size, ...props }) => (
|
|
760
|
+
<button className={buttonVariants({ variant, size, className })} {...props} />
|
|
761
|
+
))
|
|
762
|
+
Button.displayName = "Button"
|
|
763
|
+
|
|
764
|
+
export { Button, buttonVariants }
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
### Patrón de custom hook genérico
|
|
768
|
+
|
|
769
|
+
```tsx
|
|
770
|
+
// hooks/useSupabaseTable.ts
|
|
771
|
+
import { useState, useEffect } from "react"
|
|
772
|
+
import { supabase } from "@/services/supabase/client"
|
|
773
|
+
|
|
774
|
+
interface UseTableOptions<T> {
|
|
775
|
+
table: string
|
|
776
|
+
select?: string
|
|
777
|
+
filters?: Record<string, unknown>
|
|
778
|
+
order?: { column: string; ascending?: boolean }
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
interface UseTableResult<T> {
|
|
782
|
+
data: T[]
|
|
783
|
+
loading: boolean
|
|
784
|
+
error: string | null
|
|
785
|
+
refetch: () => void
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
export function useSupabaseTable<T>({
|
|
789
|
+
table,
|
|
790
|
+
select = "*",
|
|
791
|
+
filters,
|
|
792
|
+
order,
|
|
793
|
+
}: UseTableOptions<T>): UseTableResult<T> {
|
|
794
|
+
const [data, setData] = useState<T[]>([])
|
|
795
|
+
const [loading, setLoading] = useState(true)
|
|
796
|
+
const [error, setError] = useState<string | null>(null)
|
|
797
|
+
|
|
798
|
+
const fetchData = async () => {
|
|
799
|
+
setLoading(true)
|
|
800
|
+
setError(null)
|
|
801
|
+
|
|
802
|
+
let query = supabase.from(table).select(select)
|
|
803
|
+
|
|
804
|
+
if (filters) {
|
|
805
|
+
Object.entries(filters).forEach(([key, value]) => {
|
|
806
|
+
query = query.eq(key, value)
|
|
807
|
+
})
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
if (order) {
|
|
811
|
+
query = query.order(order.column, { ascending: order.ascending ?? true })
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
const { data: result, error: err } = await query
|
|
815
|
+
|
|
816
|
+
if (err) {
|
|
817
|
+
setError(err.message)
|
|
818
|
+
} else {
|
|
819
|
+
setData((result ?? []) as T[])
|
|
820
|
+
}
|
|
821
|
+
setLoading(false)
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
useEffect(() => { fetchData() }, [table, JSON.stringify(filters)])
|
|
825
|
+
|
|
826
|
+
return { data, loading, error, refetch: fetchData }
|
|
827
|
+
}
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
### Patrón compound component (Select)
|
|
831
|
+
|
|
832
|
+
```tsx
|
|
833
|
+
// components/ui/Select.tsx
|
|
834
|
+
import { createContext, useContext, useState, type ReactNode } from "react"
|
|
835
|
+
|
|
836
|
+
interface SelectContextType {
|
|
837
|
+
value: string
|
|
838
|
+
onChange: (value: string) => void
|
|
839
|
+
open: boolean
|
|
840
|
+
setOpen: (open: boolean) => void
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
const SelectContext = createContext<SelectContextType | null>(null)
|
|
844
|
+
|
|
845
|
+
function Select({ children, value, onChange }: { children: ReactNode; value: string; onChange: (v: string) => void }) {
|
|
846
|
+
const [open, setOpen] = useState(false)
|
|
847
|
+
return (
|
|
848
|
+
<SelectContext.Provider value={{ value, onChange, open, setOpen }}>
|
|
849
|
+
<div className="relative">{children}</div>
|
|
850
|
+
</SelectContext.Provider>
|
|
851
|
+
)
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
function Trigger({ children }: { children: ReactNode }) {
|
|
855
|
+
const ctx = useContext(SelectContext)!
|
|
856
|
+
return (
|
|
857
|
+
<button onClick={() => ctx.setOpen(!ctx.open)} className="flex h-10 w-full items-center justify-between rounded-md border px-3">
|
|
858
|
+
{children}
|
|
859
|
+
<span className="ml-2">{ctx.open ? "▲" : "▼"}</span>
|
|
860
|
+
</button>
|
|
861
|
+
)
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
function Options({ children }: { children: ReactNode }) {
|
|
865
|
+
const ctx = useContext(SelectContext)!
|
|
866
|
+
if (!ctx.open) return null
|
|
867
|
+
return (
|
|
868
|
+
<div className="absolute z-50 mt-1 w-full rounded-md border bg-white shadow-lg">
|
|
869
|
+
{children}
|
|
870
|
+
</div>
|
|
871
|
+
)
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
function Option({ value, children }: { value: string; children: ReactNode }) {
|
|
875
|
+
const ctx = useContext(SelectContext)!
|
|
876
|
+
return (
|
|
877
|
+
<button
|
|
878
|
+
onClick={() => { ctx.onChange(value); ctx.setOpen(false) }}
|
|
879
|
+
className={`w-full px-3 py-2 text-left hover:bg-gray-100 ${ctx.value === value ? "bg-blue-50 font-medium" : ""}`}
|
|
880
|
+
>
|
|
881
|
+
{children}
|
|
882
|
+
</button>
|
|
883
|
+
)
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
Select.Trigger = Trigger
|
|
887
|
+
Select.Options = Options
|
|
888
|
+
Select.Option = Option
|
|
889
|
+
export { Select }
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
### Reglas de exportación (Barrel)
|
|
893
|
+
|
|
894
|
+
Siempre usar archivos `index.ts` en cada carpeta para exportar solo lo público:
|
|
895
|
+
|
|
896
|
+
```ts
|
|
897
|
+
// components/ui/index.ts
|
|
898
|
+
export { Button, buttonVariants } from "./Button"
|
|
899
|
+
export { Input } from "./Input"
|
|
900
|
+
export { Select } from "./Select"
|
|
901
|
+
export { Card } from "./Card"
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
### Anti-patrones a evitar
|
|
905
|
+
|
|
906
|
+
| ❌ Incorrecto | ✅ Correcto |
|
|
907
|
+
|---|---|
|
|
908
|
+
| `const MyComponent = (props: any)` | Tipar explícitamente con interfaz |
|
|
909
|
+
| 3+ `useEffect` en un mismo componente | Unificar efectos o extraer a hook |
|
|
910
|
+
| CSS modules o archivos `.css` sueltos | 100% Tailwind utility classes |
|
|
911
|
+
| Props booleanas opcionales sin default | Usar defaultProps o valores por defecto |
|
|
912
|
+
| Componente de 300+ líneas | Dividir en ≤120 líneas |
|
|
913
|
+
| Funciones helper dentro del componente | Mover a `utils/` o al hook correspondiente |
|
|
914
|
+
| `useState` para lógica compleja | Usar `useReducer` o Zustand |
|
|
915
|
+
| Mezclar lógica de Capacitor y Tauri en mismo archivo | Separar por servicio |
|
|
916
|
+
|
|
917
|
+
---
|
|
918
|
+
|
|
919
|
+
## 8. Integración con react-doctor
|
|
920
|
+
|
|
921
|
+
### ¿Qué es react-doctor?
|
|
922
|
+
|
|
923
|
+
Es una herramienta de análisis estático que revisa tu código React en busca de:
|
|
924
|
+
- Violaciones de reglas de hooks
|
|
925
|
+
- Componentes demasiado grandes
|
|
926
|
+
- Problemas de accesibilidad
|
|
927
|
+
- Props no utilizadas
|
|
928
|
+
- Renderizados innecesarios
|
|
929
|
+
- Mejores prácticas de React
|
|
930
|
+
|
|
931
|
+
### Integración en el flujo de trabajo
|
|
932
|
+
|
|
933
|
+
```bash
|
|
934
|
+
# Paso 1: Instalar
|
|
935
|
+
npm install --save-dev react-doctor
|
|
936
|
+
|
|
937
|
+
# Paso 2: Agregar script en package.json
|
|
938
|
+
# "scripts": { "doctor": "react-doctor check ./src" }
|
|
939
|
+
|
|
940
|
+
# Paso 3: Ejecutar antes de cada commit
|
|
941
|
+
npm run doctor
|
|
942
|
+
```
|
|
943
|
+
|
|
944
|
+
### Configuración recomendada (.reactdoctorrc.json)
|
|
945
|
+
|
|
946
|
+
```json
|
|
947
|
+
{
|
|
948
|
+
"rules": {
|
|
949
|
+
"max-component-lines": { "severity": "warn", "limit": 120 },
|
|
950
|
+
"max-hook-lines": { "severity": "warn", "limit": 80 },
|
|
951
|
+
"no-complex-conditional-render": "error",
|
|
952
|
+
"no-unnecessary-fragment": "warn",
|
|
953
|
+
"prefer-early-return": "warn",
|
|
954
|
+
"no-large-bundles": "warn",
|
|
955
|
+
"hook-rules": "error",
|
|
956
|
+
"no-direct-mutation-state": "error",
|
|
957
|
+
"prefer-custom-hooks": { "severity": "warn", "min-usage": 2 }
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
```
|
|
961
|
+
|
|
962
|
+
### Acción correctiva ante advertencias de react-doctor
|
|
963
|
+
|
|
964
|
+
| Advertencia | Acción |
|
|
965
|
+
|---|---|
|
|
966
|
+
| "Component exceeds 120 lines" | Dividir en subcomponentes |
|
|
967
|
+
| "Hook logic should be extracted" | Crear custom hook |
|
|
968
|
+
| "Complex conditional render" | Extraer a variable o componente |
|
|
969
|
+
| "Unused prop" | Eliminar o implementar |
|
|
970
|
+
| "Hook usage outside rules" | Revisar orden y condiciones de hooks |
|
|
971
|
+
|
|
972
|
+
---
|
|
973
|
+
|
|
974
|
+
## 9. Estructura de Prompts — Correcto vs Incorrecto
|
|
975
|
+
|
|
976
|
+
### Plantilla universal de prompt
|
|
977
|
+
|
|
978
|
+
```
|
|
979
|
+
## Contexto del proyecto
|
|
980
|
+
{stack tecnológico, arquitectura, enlace a patrones de trabajo}
|
|
981
|
+
|
|
982
|
+
## Objetivo específico
|
|
983
|
+
{qué se necesita crear/modificar, una sola cosa}
|
|
984
|
+
|
|
985
|
+
## Especificaciones técnicas
|
|
986
|
+
{qué archivos crear, qué patrones usar, límites}
|
|
987
|
+
|
|
988
|
+
## Reglas estrictas (must have)
|
|
989
|
+
- [regla 1]
|
|
990
|
+
- [regla 2]
|
|
991
|
+
|
|
992
|
+
## Anti-patrones (prohibido)
|
|
993
|
+
- [anti-patrón 1]
|
|
994
|
+
- [anti-patrón 2]
|
|
995
|
+
|
|
996
|
+
## Ejemplo correcto
|
|
997
|
+
{código que sigue los patrones}
|
|
998
|
+
|
|
999
|
+
## Ejemplo incorrecto
|
|
1000
|
+
{código que NO debe generarse}
|
|
1001
|
+
|
|
1002
|
+
## Formato de salida esperado
|
|
1003
|
+
{estructura del output}
|
|
1004
|
+
```
|
|
1005
|
+
|
|
1006
|
+
### Ejemplos de prompts correctos e incorrectos
|
|
1007
|
+
|
|
1008
|
+
#### Contexto: Crear un hook de cámara con Capacitor
|
|
1009
|
+
|
|
1010
|
+
**INCORRECTO (ambiguo):**
|
|
1011
|
+
```
|
|
1012
|
+
"Crea un hook para usar la cámara en React."
|
|
1013
|
+
```
|
|
1014
|
+
|
|
1015
|
+
**CORRECTO (determinista):**
|
|
1016
|
+
```
|
|
1017
|
+
## Contexto
|
|
1018
|
+
Stack: React 18 + TypeScript + Capacitor 6 + Ionic 8.
|
|
1019
|
+
Convenciones: hooks en src/hooks/, un hook por archivo, máximo 80 líneas.
|
|
1020
|
+
Referencia: seguir patrón de hooks en docs/Framework de Desarrollo Asistido por IA.md.
|
|
1021
|
+
|
|
1022
|
+
## Objetivo
|
|
1023
|
+
Crear el hook `useCapacitorCamera` que permita tomar fotos y obtener la URL de la imagen.
|
|
1024
|
+
|
|
1025
|
+
## Especificaciones técnicas
|
|
1026
|
+
- Archivo: `src/hooks/useCapacitorCamera.ts`
|
|
1027
|
+
- Usar `@capacitor/camera` plugin
|
|
1028
|
+
- Retornar: `{ photo: string | null; takePhoto: () => Promise<void>; error: string | null }`
|
|
1029
|
+
- Manejar permisos denegados con mensaje claro
|
|
1030
|
+
- Máximo 60 líneas
|
|
1031
|
+
|
|
1032
|
+
## Reglas estrictas
|
|
1033
|
+
- Tipar con TypeScript todas las funciones y estados
|
|
1034
|
+
- Manejar error si el permiso de cámara está denegado
|
|
1035
|
+
- Usar `Camera.getPhoto()` con opción `resultType: CameraResultType.Uri`
|
|
1036
|
+
|
|
1037
|
+
## Anti-patrones (prohibido)
|
|
1038
|
+
- NO usar any
|
|
1039
|
+
- NO poner lógica de UI en el hook
|
|
1040
|
+
- NO mezclar con lógica de Tauri
|
|
1041
|
+
|
|
1042
|
+
## Ejemplo correcto (parcial)
|
|
1043
|
+
```typescript
|
|
1044
|
+
interface UseCameraResult {
|
|
1045
|
+
photo: string | null
|
|
1046
|
+
takePhoto: () => Promise<void>
|
|
1047
|
+
error: string | null
|
|
1048
|
+
}
|
|
1049
|
+
```
|
|
1050
|
+
|
|
1051
|
+
## Ejemplo incorrecto
|
|
1052
|
+
```typescript
|
|
1053
|
+
// ❌ Sin tipos, sin manejo de errores, any por todos lados
|
|
1054
|
+
const useCamera = () => {
|
|
1055
|
+
const [photo, setPhoto] = useState<any>(null)
|
|
1056
|
+
const takePhoto = async () => {
|
|
1057
|
+
const image = await Camera.getPhoto({ quality: 90 })
|
|
1058
|
+
setPhoto(image)
|
|
1059
|
+
}
|
|
1060
|
+
return { photo, takePhoto }
|
|
1061
|
+
}
|
|
1062
|
+
```
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
#### Contexto: Crear un comando de Tauri para leer archivos
|
|
1066
|
+
|
|
1067
|
+
**INCORRECTO (ambiguo):**
|
|
1068
|
+
```
|
|
1069
|
+
"Crea un comando de Tauri para leer archivos del sistema."
|
|
1070
|
+
```
|
|
1071
|
+
|
|
1072
|
+
**CORRECTO (determinista):**
|
|
1073
|
+
```
|
|
1074
|
+
## Contexto
|
|
1075
|
+
Stack: Tauri v2 + Rust + React.
|
|
1076
|
+
Convenciones: comandos Tauri en src-tauri/src/commands/, llamados desde src/services/tauri/.
|
|
1077
|
+
|
|
1078
|
+
## Objetivo
|
|
1079
|
+
Crear un comando Tauri `read_file_content` que lea un archivo de texto y devuelva su contenido.
|
|
1080
|
+
|
|
1081
|
+
## Especificaciones técnicas
|
|
1082
|
+
- Comando Rust: `#[tauri::command] fn read_file_content(path: String) -> Result<String, String>`
|
|
1083
|
+
- Llamada desde frontend: `invoke('read_file_content', { path })`
|
|
1084
|
+
- Validar que el archivo existe antes de leer
|
|
1085
|
+
- Manejar error de permisos
|
|
1086
|
+
|
|
1087
|
+
## Reglas estrictas
|
|
1088
|
+
- Tipado estricto en Rust (String, no &str)
|
|
1089
|
+
- No permitir path traversal (restringir a directorio de trabajo)
|
|
1090
|
+
- Devolver error legible en español
|
|
1091
|
+
|
|
1092
|
+
## Anti-patrones (prohibido)
|
|
1093
|
+
- NO usar `std::fs::read_to_string` sin validar path
|
|
1094
|
+
- NO exponer comandos inseguros sin validación
|
|
1095
|
+
```
|
|
1096
|
+
|
|
1097
|
+
### Trucos de comunicación con IA
|
|
1098
|
+
|
|
1099
|
+
| Comando | Efecto | Cuándo usarlo |
|
|
1100
|
+
|---|---|---|
|
|
1101
|
+
| `/humano` | Hace que la IA responda de forma coloquial | Cuando necesitas explicaciones comprensibles |
|
|
1102
|
+
| `tldr` al final | Respuesta ultra concisa | Para obtener resumen ejecutivo |
|
|
1103
|
+
| `ELI5` | Explicación como si tuvieras 5 años | Conceptos complejos para principiantes |
|
|
1104
|
+
| `Listify` | Respuesta en formato de lista | Para pasos, requisitos, tareas |
|
|
1105
|
+
| `/sin-alucinar` | Fuerza a la IA a no inventar APIs que no existen | Cuando pides código que debe ser exacto |
|
|
1106
|
+
| `/validar` | Pide a la IA que valide su propia respuesta | Para verificar consistencia |
|
|
1107
|
+
| `formato: json` | Respuesta en JSON estructurado | Para exportar a sistemas externos |
|
|
1108
|
+
|
|
1109
|
+
---
|
|
1110
|
+
|
|
1111
|
+
## 10. Flujo de Trabajo Diario con IA
|
|
1112
|
+
|
|
1113
|
+
### Ciclo de trabajo estándar
|
|
1114
|
+
|
|
1115
|
+
```
|
|
1116
|
+
1. LEER → docs/Framework de Desarrollo Asistido por IA.md + docs/AGENTS.md
|
|
1117
|
+
2. PLANIFICAR → Revisar backlog (docs/BACKLOG/PHASE-*.md)
|
|
1118
|
+
3. PROMPTEAR → Usar plantilla de prompt (sección 9)
|
|
1119
|
+
4. IMPLEMENTAR → Aplicar código generado
|
|
1120
|
+
5. VERIFICAR → Ejecutar react-doctor + linter + tests
|
|
1121
|
+
6. DOCUMENTAR → Registrar en docs/COMMITS/ + docs/LOGS/ACTIVIDAD/
|
|
1122
|
+
7. REPETIR → Siguiente tarea del backlog
|
|
1123
|
+
```
|
|
1124
|
+
|
|
1125
|
+
### CheckList pre-prompt
|
|
1126
|
+
|
|
1127
|
+
Antes de enviar un prompt a la IA, verificar:
|
|
1128
|
+
|
|
1129
|
+
- [ ] ¿El prompt incluye el stack tecnológico?
|
|
1130
|
+
- [ ] ¿La tarea es una sola funcionalidad atómica?
|
|
1131
|
+
- [ ] ¿Se especificaron los archivos a crear/modificar?
|
|
1132
|
+
- [ ] ¿Se dieron ejemplos correctos e incorrectos?
|
|
1133
|
+
- [ ] ¿Se listaron los anti-patrones a evitar?
|
|
1134
|
+
- [ ] ¿El prompt referencia este archivo como guía?
|
|
1135
|
+
|
|
1136
|
+
### CheckList post-implementación
|
|
1137
|
+
|
|
1138
|
+
- [ ] ¿Corre el pipeline de validación? (`./scripts/validate.sh`)
|
|
1139
|
+
- [ ] ¿El código pasa `npm run doctor`?
|
|
1140
|
+
- [ ] ¿El componente está dentro del límite de líneas?
|
|
1141
|
+
- [ ] ¿Los tipos TypeScript están correctos?
|
|
1142
|
+
- [ ] ¿Se documentó en el commit log?
|
|
1143
|
+
- [ ] ¿Se registró en el log de actividad (o se usó `scripts/log-actividad.sh`)?
|
|
1144
|
+
- [ ] ¿Se actualizó el progreso en el backlog?
|
|
1145
|
+
|
|
1146
|
+
### Integración con el ecosistema de la metodología
|
|
1147
|
+
|
|
1148
|
+
Esta guía se complementa con las fases definidas en el índice general:
|
|
1149
|
+
|
|
1150
|
+
| Si estás en... | Usa este archivo para... |
|
|
1151
|
+
|---|---|---|
|
|
1152
|
+
| Fase 5 (Scaffolding) | Estructura de carpetas y creación de esqueletos |
|
|
1153
|
+
| Fase 6 (Backlog) | Distribución de prioridades, micro-tasking y asignación de perfil |
|
|
1154
|
+
| Fase 7 (Desarrollo activo) | Commits, logs, react-doctor, pipeline de validación y modularización |
|
|
1155
|
+
| Fase 8 (Entrega) | Phase Gates y retrospectiva |
|
|
1156
|
+
| Cualquier fase | Estructura de prompts y ejemplos correctos/incorrectos |
|
|
1157
|
+
|
|
1158
|
+
---
|
|
1159
|
+
|
|
1160
|
+
## 11. Pipeline de Validación Automática
|
|
1161
|
+
|
|
1162
|
+
> 💡 **Cuándo aplicar esta sección:** Recomendado para todo proyecto que pase a producción. En prototipos rápidos, basta con ejecutar lint + typecheck manualmente. El pipeline completo (con tests y build) se activa cuando el proyecto tiene clientes o usuarios reales.
|
|
1163
|
+
|
|
1164
|
+
### Propósito
|
|
1165
|
+
|
|
1166
|
+
Garantizar que todo el código generado por IA pase filtros automáticos antes de llegar al repositorio. Esto evita que errores de tipo, lógica o estilo se acumulen.
|
|
1167
|
+
|
|
1168
|
+
### Pipeline mínimo pre-commit
|
|
1169
|
+
|
|
1170
|
+
Ejecutar en orden antes de cada commit:
|
|
1171
|
+
|
|
1172
|
+
```bash
|
|
1173
|
+
# 1. Linter (ESLint con reglas estrictas)
|
|
1174
|
+
npm run lint -- --max-warnings=0
|
|
1175
|
+
|
|
1176
|
+
# 2. TypeScript check (strict mode)
|
|
1177
|
+
npx tsc --noEmit
|
|
1178
|
+
|
|
1179
|
+
# 3. react-doctor (auditoría de buenas prácticas)
|
|
1180
|
+
npx react-doctor check ./src
|
|
1181
|
+
|
|
1182
|
+
# 4. Tests rápidos (solo unitarios, sin build)
|
|
1183
|
+
npm run test -- --run
|
|
1184
|
+
|
|
1185
|
+
# 5. Build seco (verifica que compila)
|
|
1186
|
+
npm run build
|
|
1187
|
+
```
|
|
1188
|
+
|
|
1189
|
+
### Script de validación unificado
|
|
1190
|
+
|
|
1191
|
+
Crear `scripts/validate.sh`:
|
|
1192
|
+
|
|
1193
|
+
```bash
|
|
1194
|
+
#!/bin/bash
|
|
1195
|
+
set -e
|
|
1196
|
+
|
|
1197
|
+
echo "=== Pipeline de Validación ==="
|
|
1198
|
+
|
|
1199
|
+
echo "[1/5] Linting..."
|
|
1200
|
+
npm run lint -- --max-warnings=0 || { echo "❌ Lint falló"; exit 1; }
|
|
1201
|
+
|
|
1202
|
+
echo "[2/5] TypeScript check..."
|
|
1203
|
+
npx tsc --noEmit || { echo "❌ TypeScript falló"; exit 1; }
|
|
1204
|
+
|
|
1205
|
+
echo "[3/5] react-doctor..."
|
|
1206
|
+
npx react-doctor check ./src || { echo "❌ react-doctor encontró problemas"; exit 1; }
|
|
1207
|
+
|
|
1208
|
+
echo "[4/5] Tests..."
|
|
1209
|
+
npm run test -- --run || { echo "❌ Tests fallaron"; exit 1; }
|
|
1210
|
+
|
|
1211
|
+
echo "[5/5] Build..."
|
|
1212
|
+
npm run build || { echo "❌ Build falló"; exit 1; }
|
|
1213
|
+
|
|
1214
|
+
echo "=== ✅ Pipeline completo — Código válido ==="
|
|
1215
|
+
```
|
|
1216
|
+
|
|
1217
|
+
```bash
|
|
1218
|
+
chmod +x scripts/validate.sh
|
|
1219
|
+
# Ejecutar antes de cada commit:
|
|
1220
|
+
./scripts/validate.sh
|
|
1221
|
+
```
|
|
1222
|
+
|
|
1223
|
+
### Integración con husky (opcional)
|
|
1224
|
+
|
|
1225
|
+
```bash
|
|
1226
|
+
npm install --save-dev husky lint-staged
|
|
1227
|
+
npx husky init
|
|
1228
|
+
```
|
|
1229
|
+
|
|
1230
|
+
Crear `.husky/pre-commit`:
|
|
1231
|
+
|
|
1232
|
+
```bash
|
|
1233
|
+
#!/usr/bin/env sh
|
|
1234
|
+
./scripts/validate.sh
|
|
1235
|
+
```
|
|
1236
|
+
|
|
1237
|
+
### Archivo de referencia `docs/PIPELINE.md`
|
|
1238
|
+
|
|
1239
|
+
Crear este archivo como documentación del pipeline para que la IA lo referencie:
|
|
1240
|
+
|
|
1241
|
+
```markdown
|
|
1242
|
+
# Pipeline de Validación
|
|
1243
|
+
|
|
1244
|
+
Este proyecto ejecuta validación automática antes de cada commit.
|
|
1245
|
+
|
|
1246
|
+
## Pasos
|
|
1247
|
+
1. ESLint (0 warnings tolerados)
|
|
1248
|
+
2. TypeScript strict check
|
|
1249
|
+
3. react-doctor
|
|
1250
|
+
4. Vitest (unit tests)
|
|
1251
|
+
5. Build seco
|
|
1252
|
+
|
|
1253
|
+
## Script
|
|
1254
|
+
`./scripts/validate.sh`
|
|
1255
|
+
|
|
1256
|
+
## Reglas
|
|
1257
|
+
- Si cualquier paso falla, el commit se rechaza
|
|
1258
|
+
- No usar `--force` ni `--no-verify` sin autorización explícita
|
|
1259
|
+
- Si el pipeline es muy lento (>30s), dividir en pre-commit (lint+typecheck) y CI (tests+build)
|
|
1260
|
+
```
|
|
1261
|
+
|
|
1262
|
+
---
|
|
1263
|
+
|
|
1264
|
+
## 12. Phase Gates — CheckList de Salida por Fase
|
|
1265
|
+
|
|
1266
|
+
> 💡 **Cuándo aplicar esta sección:** Exclusivo para **proyectos con cliente y presupuesto definido**. En prototipos o proyectos personales, los phase gates son overkill. Úsalos cuando necesites controlar alcance y evitar que el cliente se desvíe.
|
|
1267
|
+
|
|
1268
|
+
### Propósito
|
|
1269
|
+
|
|
1270
|
+
Cada fase de la metodología debe completarse al 100% antes de avanzar a la siguiente. Estos checklists evitan arrastrar deuda técnica entre fases.
|
|
1271
|
+
|
|
1272
|
+
### Fase 1 → Fase 2 (Discovery → Historias de Usuario)
|
|
1273
|
+
|
|
1274
|
+
- [ ] Se identificó el dolor principal del negocio
|
|
1275
|
+
- [ ] Se definieron los límites del alcance inicial
|
|
1276
|
+
- [ ] Se decidió ruta: desarrollo desde cero vs refactorización
|
|
1277
|
+
- [ ] El cliente aceptó la propuesta preliminar
|
|
1278
|
+
|
|
1279
|
+
### Fase 2 → Fase 3 (Historias de Usuario → Prototipado)
|
|
1280
|
+
|
|
1281
|
+
- [ ] Todas las historias de usuario siguen el formato determinista
|
|
1282
|
+
- [ ] Cada historia tiene actor, disparador, lógica, resultado esperado y resultado fallido
|
|
1283
|
+
- [ ] Las funciones críticas tienen su contrato de método definido
|
|
1284
|
+
- [ ] No hay ambigüedad en las reglas de negocio
|
|
1285
|
+
|
|
1286
|
+
### Fase 3 → Fase 4 (Prototipado → Especificación con Cliente)
|
|
1287
|
+
|
|
1288
|
+
- [ ] El prototipo visual es navegable (no solo imágenes estáticas)
|
|
1289
|
+
- [ ] Los componentes están modularizados para React (no páginas monolíticas)
|
|
1290
|
+
- [ ] 100% del diseño usa Tailwind (sin CSS personalizado)
|
|
1291
|
+
- [ ] Mobile-first probado en al menos 2 resoluciones
|
|
1292
|
+
|
|
1293
|
+
### Fase 4 → Fase 5 (Especificación → Scaffolding)
|
|
1294
|
+
|
|
1295
|
+
- [ ] **Go/No-Go completado** (checklist de aprobación de Fase 4)
|
|
1296
|
+
- [ ] Alcance congelado: no hay requerimientos nuevos sin cotizar
|
|
1297
|
+
- [ ] Presupuesto final aceptado por el cliente
|
|
1298
|
+
- [ ] Bibliotecas necesarias validadas técnicamente
|
|
1299
|
+
|
|
1300
|
+
### Fase 5 → Fase 6 (Scaffolding → Backlog)
|
|
1301
|
+
|
|
1302
|
+
- [ ] Estructura de carpetas creada según el estándar (sección 2)
|
|
1303
|
+
- [ ] Todos los archivos del scaffolding tienen `throw new Error("pendiente")` o equivalente
|
|
1304
|
+
- [ ] Los contratos de método (inputs/outputs/flujo) están completos en cada función esqueleto
|
|
1305
|
+
- [ ] El proyecto compila sin errores (`npm run build` pasa)
|
|
1306
|
+
- [ ] Los types/interfaces globales están definidos
|
|
1307
|
+
- [ ] Existe un `README.md` o `AGENTS.md` con el contexto del proyecto
|
|
1308
|
+
- [ ] `docs/COMMITS/INDEX.md` creado
|
|
1309
|
+
- [ ] `docs/LOGS/` estructura de carpetas creada
|
|
1310
|
+
- [ ] `docs/BACKLOG/` estructura de carpetas creada
|
|
1311
|
+
|
|
1312
|
+
### Fase 6 → Fase 7 (Backlog → Desarrollo Activo)
|
|
1313
|
+
|
|
1314
|
+
- [ ] Cada tarea P0 sigue el formato estándar (sección 5)
|
|
1315
|
+
- [ ] Ninguna tarea supera los límites de micro-tasking
|
|
1316
|
+
- [ ] Las dependencias entre tareas están mapeadas
|
|
1317
|
+
- [ ] Las tareas están ordenadas por capa: Datos → Backend → Frontend
|
|
1318
|
+
- [ ] No hay tareas sin criterios de aceptación claros
|
|
1319
|
+
- [ ] `progreso.json` creado y funcional
|
|
1320
|
+
|
|
1321
|
+
### Fase 7 → Fase 8 (Desarrollo Activo → Entrega)
|
|
1322
|
+
|
|
1323
|
+
- [ ] Todas las tareas P0 y P1 están completadas
|
|
1324
|
+
- [ ] Pipeline de validación pasa sin errores (sección 11)
|
|
1325
|
+
- [ ] react-doctor reporta 0 warnings críticos
|
|
1326
|
+
- [ ] Coverage de tests mínimo: 70%
|
|
1327
|
+
- [ ] Todos los errores CRITICAL y HIGH están documentados en `docs/LOGS/ERRORES/`
|
|
1328
|
+
- [ ] Commit logs están actualizados hasta el último cambio
|
|
1329
|
+
- [ ] Versión semántica actualizada según SemVer checklist
|
|
1330
|
+
- [ ] Se realizó la retrospectiva de la iteración (sección 13)
|
|
1331
|
+
|
|
1332
|
+
### Fase 8 → Cierre (Entrega → Mantenimiento)
|
|
1333
|
+
|
|
1334
|
+
- [ ] Acta de entrega firmada por el cliente
|
|
1335
|
+
- [ ] Manual de usuario entregado
|
|
1336
|
+
- [ ] Capacitación realizada
|
|
1337
|
+
- [ ] Políticas de soporte definidas y comunicadas
|
|
1338
|
+
- [ ] Repositorio limpiado (sin ramas muertas, sin archivos temporales)
|
|
1339
|
+
- [ ] Documentación final actualizada
|
|
1340
|
+
|
|
1341
|
+
---
|
|
1342
|
+
|
|
1343
|
+
## 13. Retrospectiva por Iteración
|
|
1344
|
+
|
|
1345
|
+
> 💡 **Cuándo aplicar esta sección:** Útil después de **milestones importantes o entregas a cliente**. No la apliques después de cada sesión de código — solo cuando cierres una versión o fase completa. En side projects, la retrospectiva exprés de 4 preguntas basta.
|
|
1346
|
+
|
|
1347
|
+
### Propósito
|
|
1348
|
+
|
|
1349
|
+
Después de cada milestone o versión, se realiza una retrospectiva para ajustar la metodología de forma continua. Esto cierra el ciclo de mejora y evita repetir errores.
|
|
1350
|
+
|
|
1351
|
+
### Template de retrospectiva
|
|
1352
|
+
|
|
1353
|
+
Crear `docs/RETROSPECTIVA.md` y completarlo al cerrar cada versión:
|
|
1354
|
+
|
|
1355
|
+
```markdown
|
|
1356
|
+
# Retrospectiva — v{x.x.x}
|
|
1357
|
+
|
|
1358
|
+
**Fecha:** {dd/mm/aaaa}
|
|
1359
|
+
**Duración del ciclo:** {fecha inicio} → {fecha fin}
|
|
1360
|
+
**Participantes:** {quien trabajó en el ciclo}
|
|
1361
|
+
|
|
1362
|
+
---
|
|
1363
|
+
|
|
1364
|
+
### 1. ¿Qué funcionó bien?
|
|
1365
|
+
- {ej: el micro-tasking evitó que la IA alucinara}
|
|
1366
|
+
- {ej: los phase gates detectaron scaffolding incompleto a tiempo}
|
|
1367
|
+
|
|
1368
|
+
### 2. ¿Qué no funcionó o costó más de lo esperado?
|
|
1369
|
+
- {ej: los prompts para el hook de cámara requirieron 4 intentos}
|
|
1370
|
+
- {ej: el pipeline de validación tardaba demasiado}
|
|
1371
|
+
|
|
1372
|
+
### 3. ¿Hubo algo que la IA alucinó repetidamente?
|
|
1373
|
+
- {ej: inventó APIs de Capacitor que no existen}
|
|
1374
|
+
- {ej: no respetó el límite de 120 líneas en componentes}
|
|
1375
|
+
|
|
1376
|
+
### 4. ¿Qué ajuste harías en la metodología para la próxima iteración?
|
|
1377
|
+
- {ej: agregar un anti-patrón explícito para ese caso en la sección 9}
|
|
1378
|
+
- {ej: reducir el límite de líneas a 100 para hooks}
|
|
1379
|
+
|
|
1380
|
+
### 5. Acción concreta para el próximo ciclo
|
|
1381
|
+
- [ ] {acción 1: ej: actualizar Framework de Desarrollo Asistido por IA.md con el nuevo anti-patrón}
|
|
1382
|
+
- [ ] {acción 2: ej: crear un prompt template específico para hooks de Capacitor}
|
|
1383
|
+
- [ ] {acción 3: ej: optimizar el pipeline para que corra en paralelo}
|
|
1384
|
+
```
|
|
1385
|
+
|
|
1386
|
+
### Recordatorio en el backlog
|
|
1387
|
+
|
|
1388
|
+
Agregar al final de cada milestone en `docs/BACKLOG/PHASE-*.md`:
|
|
1389
|
+
|
|
1390
|
+
```markdown
|
|
1391
|
+
### 🎯 Post-milestone
|
|
1392
|
+
- [ ] Ejecutar retrospectiva → `docs/RETROSPECTIVA.md`
|
|
1393
|
+
- [ ] Actualizar `Framework de Desarrollo Asistido por IA.md` según hallazgos
|
|
1394
|
+
- [ ] Ajustar `progreso.json` con métricas reales vs estimadas
|
|
1395
|
+
```
|
|
1396
|
+
|
|
1397
|
+
### Preguntas rápidas para retrospectivas exprés
|
|
1398
|
+
|
|
1399
|
+
Cuando no hay tiempo para la retrospectiva completa:
|
|
1400
|
+
|
|
1401
|
+
| Pregunta | Respuesta |
|
|
1402
|
+
|---|---|
|
|
1403
|
+
| ¿Qué repetirías? | |
|
|
1404
|
+
| ¿Qué no repetirías? | |
|
|
1405
|
+
| ¿Qué harías diferente? | |
|
|
1406
|
+
| ¿Qué aprendiste sobre la IA? | |
|
|
1407
|
+
|
|
1408
|
+
---
|
|
1409
|
+
|
|
1410
|
+
## 14. Perfiles de Desarrollador
|
|
1411
|
+
|
|
1412
|
+
> 💡 **Cuándo aplicar esta sección:** Si trabajas solo, ignora esta sección y define tu perfil como **Senior** en `AGENTS.md`. Los niveles Junior/Mid están pensados para **equipos** o para cuando delegas tareas a otro desarrollador. Si eres el único dev, las reglas extra de perfiles no agregan valor.
|
|
1413
|
+
|
|
1414
|
+
### Propósito
|
|
1415
|
+
|
|
1416
|
+
No todos los desarrolladores tienen el mismo nivel de experiencia. Esta sección adapta el nivel de detalle de los prompts, scaffolds y reglas según el perfil.
|
|
1417
|
+
|
|
1418
|
+
### Tabla de perfiles
|
|
1419
|
+
|
|
1420
|
+
| Perfil | Descripción | Detalle en prompts | Scaffolding | Autonomía |
|
|
1421
|
+
|---|---|---|---|---|
|
|
1422
|
+
| **Junior** | Poca experiencia con el stack o con IA | Máximo detalle: ejemplos completos, prohibiciones explícitas, estructura archivo por archivo | Templates completos con 80% del código escrito | Revisión obligatoria de cada archivo generado |
|
|
1423
|
+
| **Mid** | Experiencia moderada (1-2 años con el stack) | Detalle medio: firma de funciones + reglas, ejemplos parciales | Contratos de método + interfaces + firmas vacías | Revisión por lotes (cada 3-4 archivos) |
|
|
1424
|
+
| **Senior** | Domina el stack y la metodología | Mínimo necesario: objetivo + restricciones + anti-patrones | Solo contratos de alto nivel, sin código base | Confianza para revisar al final del módulo |
|
|
1425
|
+
|
|
1426
|
+
### Nivel Junior — Reglas adicionales
|
|
1427
|
+
|
|
1428
|
+
```
|
|
1429
|
+
## Reglas para perfil Junior
|
|
1430
|
+
|
|
1431
|
+
### En los prompts:
|
|
1432
|
+
- Incluir SIEMPRE ejemplos correctos E incorrectos completos
|
|
1433
|
+
- Especificar la ruta exacta de cada archivo a crear
|
|
1434
|
+
- Definir tipos e interfaces antes de pedir la implementación
|
|
1435
|
+
- Incluir los imports necesarios en los ejemplos
|
|
1436
|
+
- Pedir a la IA que explique cada decisión con comentarios
|
|
1437
|
+
|
|
1438
|
+
### En el scaffolding:
|
|
1439
|
+
Usar el nivel máximo de detalle:
|
|
1440
|
+
```tsx
|
|
1441
|
+
// components/ui/Button.tsx
|
|
1442
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
1443
|
+
// + todo el código completo del ejemplo en sección 7
|
|
1444
|
+
|
|
1445
|
+
// hooks/useAuth.ts
|
|
1446
|
+
export function useAuth() {
|
|
1447
|
+
// 1. Obtener sesión de Supabase
|
|
1448
|
+
// 2. Retornar { user, login, logout, loading }
|
|
1449
|
+
// 3. Manejar error de sesión expirada
|
|
1450
|
+
throw new Error("Lógica pendiente")
|
|
1451
|
+
}
|
|
1452
|
+
```
|
|
1453
|
+
|
|
1454
|
+
### En la validación:
|
|
1455
|
+
- Ejecutar el pipeline completo (sección 11) después de CADA archivo
|
|
1456
|
+
- No avanzar hasta que react-doctor dé 0 warnings
|
|
1457
|
+
- Documentar cada error en `docs/LOGS/ERRORES/` inmediatamente
|
|
1458
|
+
```
|
|
1459
|
+
|
|
1460
|
+
### Nivel Mid — Reglas adicionales
|
|
1461
|
+
|
|
1462
|
+
```
|
|
1463
|
+
## Reglas para perfil Mid
|
|
1464
|
+
|
|
1465
|
+
### En los prompts:
|
|
1466
|
+
- Incluir firma completa de funciones (tipos de entrada y salida)
|
|
1467
|
+
- Especificar archivos pero no rutas exactas (el desarrollador decide)
|
|
1468
|
+
- Incluir anti-patrones pero no ejemplos completos de código incorrecto
|
|
1469
|
+
|
|
1470
|
+
### En el scaffolding:
|
|
1471
|
+
Usar nivel medio:
|
|
1472
|
+
```tsx
|
|
1473
|
+
// features/auth/services/AuthService.ts
|
|
1474
|
+
interface RegisterDTO { email: string; password: string; name: string }
|
|
1475
|
+
interface LoginDTO { email: string; password: string }
|
|
1476
|
+
interface AuthResult { token: string; user: UserProfile }
|
|
1477
|
+
|
|
1478
|
+
export async function register(dto: RegisterDTO): Promise<AuthResult>
|
|
1479
|
+
export async function login(dto: LoginDTO): Promise<AuthResult>
|
|
1480
|
+
export async function logout(): Promise<void>
|
|
1481
|
+
// + contrato de método con flujo esperado
|
|
1482
|
+
```
|
|
1483
|
+
|
|
1484
|
+
### En la validación:
|
|
1485
|
+
- Ejecutar pipeline por feature completa (no archivo por archivo)
|
|
1486
|
+
- react-doctor: 0 errors, warnings tolerados si están justificados
|
|
1487
|
+
- Revisar logs de errores al final del día
|
|
1488
|
+
```
|
|
1489
|
+
|
|
1490
|
+
### Nivel Senior — Reglas adicionales
|
|
1491
|
+
|
|
1492
|
+
```
|
|
1493
|
+
## Reglas para perfil Senior
|
|
1494
|
+
|
|
1495
|
+
### En los prompts:
|
|
1496
|
+
- Solo objetivo + contexto + restricciones técnicas
|
|
1497
|
+
- La IA recibe libertad para sugerir estructuras y patrones
|
|
1498
|
+
- El desarrollador corrige sobre la marcha sin necesidad de ejemplos
|
|
1499
|
+
|
|
1500
|
+
### En el scaffolding:
|
|
1501
|
+
Usar nivel mínimo:
|
|
1502
|
+
```tsx
|
|
1503
|
+
// features/payments/services/PaymentService.ts
|
|
1504
|
+
// Contrato:
|
|
1505
|
+
// - registerPayment(dto) → valida tarjeta, cobra, registra transacción, notifica
|
|
1506
|
+
// - refund(transactionId) → valida estado, revierte cargo, actualiza BD
|
|
1507
|
+
// Impacto: fallo aquí bloquea checkout y reportes contables
|
|
1508
|
+
```
|
|
1509
|
+
|
|
1510
|
+
### En la validación:
|
|
1511
|
+
- Pipeline completo solo al final del módulo
|
|
1512
|
+
- react-doctor como referencia, no como gatekeeper
|
|
1513
|
+
- Los errores se documentan solo si son recurrentes
|
|
1514
|
+
```
|
|
1515
|
+
|
|
1516
|
+
### Asignación de perfil por proyecto
|
|
1517
|
+
|
|
1518
|
+
Al iniciar un proyecto, definir el perfil en `AGENTS.md`:
|
|
1519
|
+
|
|
1520
|
+
```markdown
|
|
1521
|
+
## Perfil del desarrollador
|
|
1522
|
+
Senior / Mid / Junior
|
|
1523
|
+
```
|
|
1524
|
+
|
|
1525
|
+
Esto le indica a la IA qué nivel de detalle usar en sus respuestas sin necesidad de cambiar el prompt cada vez.
|
|
1526
|
+
|
|
1527
|
+
### Progresión de perfiles
|
|
1528
|
+
|
|
1529
|
+
A medida que el desarrollador gana confianza, puede subir de perfil:
|
|
1530
|
+
|
|
1531
|
+
```
|
|
1532
|
+
Junior → Mid: Cuando completa 3 features sin errores críticos
|
|
1533
|
+
Mid → Senior: Cuando completa 1 proyecto completo y comienza a ajustar la metodología
|
|
1534
|
+
```
|
|
1535
|
+
|
|
1536
|
+
---
|
|
1537
|
+
|
|
1538
|
+
## 15. Biblioteca de Prompts (docs/PROMPTS/)
|
|
1539
|
+
|
|
1540
|
+
> 💡 **Cuándo aplicar:** Siempre que inicies un nuevo archivo o feature. La biblioteca contiene prompts pre-armados para tareas recurrentes. Copia, pega y ajusta los `{placeholders}`.
|
|
1541
|
+
|
|
1542
|
+
### Estructura de la biblioteca
|
|
1543
|
+
|
|
1544
|
+
```
|
|
1545
|
+
docs/PROMPTS/
|
|
1546
|
+
├── INDEX.md ← Índice completo con metadatos
|
|
1547
|
+
├── PLANTILLAS/ ← Prompts genéricos reutilizables
|
|
1548
|
+
│ ├── 01-hook-supabase.md ← useSupabaseTable<T>
|
|
1549
|
+
│ ├── 02-componente-ui.md ← Button con cva
|
|
1550
|
+
│ ├── 03-pagina-feature.md ← FeaturePage por composición
|
|
1551
|
+
│ ├── 04-comando-tauri.md ← Comando Tauri Rust + TS
|
|
1552
|
+
│ ├── 05-store-zustand.md ← Store con Zustand
|
|
1553
|
+
│ ├── 06-servicio-supabase.md ← CRUD service con errores
|
|
1554
|
+
│ ├── 07-formulario-validacion.md ← react-hook-form + zod
|
|
1555
|
+
│ ├── 08-hook-capacitor.md ← useCapacitorCamera
|
|
1556
|
+
│ ├── 09-refactor-division.md ← Split componente grande
|
|
1557
|
+
│ └── 10-scaffolding-inicial.md ← Setup feature completo
|
|
1558
|
+
├── STACK/ ← Contextos por tecnología
|
|
1559
|
+
│ ├── react-web-puro.md ← Web React + Supabase
|
|
1560
|
+
│ ├── ionic-capacitor.md ← Mobile Ionic + Capacitor
|
|
1561
|
+
│ └── tauri-desktop.md ← Desktop Tauri v2
|
|
1562
|
+
└── HISTORIAL/ ← Prompts archivados post-uso
|
|
1563
|
+
```
|
|
1564
|
+
|
|
1565
|
+
### Cómo usar
|
|
1566
|
+
|
|
1567
|
+
Cada prompt sigue el formato determinista de la sección 9:
|
|
1568
|
+
|
|
1569
|
+
<details>
|
|
1570
|
+
<summary>📁 Ejemplo: 01-hook-supabase.md</summary>
|
|
1571
|
+
|
|
1572
|
+
```
|
|
1573
|
+
## Contexto
|
|
1574
|
+
Stack: React 18 + TypeScript + Vite + Supabase.
|
|
1575
|
+
Convenciones: hooks en src/hooks/, un hook por archivo, máximo 80 líneas.
|
|
1576
|
+
Patrón: hook genérico con <T> para tipado dinámico.
|
|
1577
|
+
Referencia: docs/Framework de Desarrollo Asistido por IA.md sección 7.
|
|
1578
|
+
|
|
1579
|
+
## Objetivo
|
|
1580
|
+
Crear el hook `useSupabaseTable<T>` que haga CRUD a una tabla de Supabase.
|
|
1581
|
+
|
|
1582
|
+
## Especificaciones técnicas
|
|
1583
|
+
- Archivo: `src/hooks/useSupabaseTable.ts`
|
|
1584
|
+
- Retornar: `{ data: T[]; loading: boolean; error: string | null; refetch: () => void }`
|
|
1585
|
+
- Máximo 65 líneas
|
|
1586
|
+
|
|
1587
|
+
## Reglas estrictas
|
|
1588
|
+
- Tipar con genéricos `<T>`
|
|
1589
|
+
- `loading` debe iniciar en `true`
|
|
1590
|
+
- `error` debe ser `string | null`
|
|
1591
|
+
|
|
1592
|
+
## Anti-patrones
|
|
1593
|
+
- NO usar any
|
|
1594
|
+
- NO mezclar UI en el hook
|
|
1595
|
+
- NO hacer fetch en el render
|
|
1596
|
+
|
|
1597
|
+
## Ejemplo incorrecto
|
|
1598
|
+
```typescript
|
|
1599
|
+
function useTable(table: string) {
|
|
1600
|
+
const [data, setData] = useState<any[]>([])
|
|
1601
|
+
useEffect(() => { supabase.from(table).select("*").then(setData) }, [])
|
|
1602
|
+
return data
|
|
1603
|
+
}
|
|
1604
|
+
```
|
|
1605
|
+
|
|
1606
|
+
## Formato de salida
|
|
1607
|
+
Archivo completo listo para copiar a `src/hooks/useSupabaseTable.ts`.
|
|
1608
|
+
```
|
|
1609
|
+
</details>
|
|
1610
|
+
|
|
1611
|
+
<details>
|
|
1612
|
+
<summary>📁 Ejemplo: 05-store-zustand.md</summary>
|
|
1613
|
+
|
|
1614
|
+
```
|
|
1615
|
+
## Contexto
|
|
1616
|
+
Stack: React 18 + TypeScript + Zustand.
|
|
1617
|
+
Convenciones: stores en src/store/, un store por dominio, máx 100 líneas.
|
|
1618
|
+
Referencia: docs/Framework de Desarrollo Asistido por IA.md sección 2.
|
|
1619
|
+
|
|
1620
|
+
## Objetivo
|
|
1621
|
+
Crear el store Zustand `{name}Store` para {descripción del dominio}.
|
|
1622
|
+
|
|
1623
|
+
## Especificaciones técnicas
|
|
1624
|
+
- Archivo: `src/store/{name}Store.ts`
|
|
1625
|
+
- Estado: {propiedades del estado}
|
|
1626
|
+
- Acciones: {set, reset, fetch, etc.}
|
|
1627
|
+
- Integrar con {servicio externo si aplica}
|
|
1628
|
+
|
|
1629
|
+
## Reglas estrictas
|
|
1630
|
+
- Tipar todo con interfaces
|
|
1631
|
+
- Acciones inmutables (spread o immer)
|
|
1632
|
+
- Acciones async deben manejar loading/error
|
|
1633
|
+
|
|
1634
|
+
## Anti-patrones
|
|
1635
|
+
- NO mutar estado directamente
|
|
1636
|
+
- NO poner lógica de UI en el store
|
|
1637
|
+
- NO duplicar estado que ya existe en BD
|
|
1638
|
+
|
|
1639
|
+
## Ejemplo parcial
|
|
1640
|
+
```typescript
|
|
1641
|
+
interface AuthState {
|
|
1642
|
+
user: User | null
|
|
1643
|
+
loading: boolean
|
|
1644
|
+
login: (email: string, password: string) => Promise<void>
|
|
1645
|
+
logout: () => void
|
|
1646
|
+
}
|
|
1647
|
+
```
|
|
1648
|
+
|
|
1649
|
+
## Formato de salida
|
|
1650
|
+
Archivo completo listo para `src/store/{name}Store.ts`.
|
|
1651
|
+
```
|
|
1652
|
+
</details>
|
|
1653
|
+
|
|
1654
|
+
<details>
|
|
1655
|
+
<summary>📁 Ejemplo: 04-comando-tauri.md</summary>
|
|
1656
|
+
|
|
1657
|
+
```
|
|
1658
|
+
## Contexto
|
|
1659
|
+
Stack: Tauri v2 + Rust + React + TypeScript.
|
|
1660
|
+
Convenciones: comandos Rust en src-tauri/src/commands/, wrappers en src/services/tauri/.
|
|
1661
|
+
Referencia: docs/Framework de Desarrollo Asistido por IA.md sección 1.
|
|
1662
|
+
|
|
1663
|
+
## Objetivo
|
|
1664
|
+
Crear el comando Tauri `{command_name}` que {descripción}.
|
|
1665
|
+
|
|
1666
|
+
## Especificaciones técnicas
|
|
1667
|
+
Archivos:
|
|
1668
|
+
- `src-tauri/src/commands/{command_name}.rs` (Rust)
|
|
1669
|
+
- `src-tauri/src/main.rs` (registrar comando)
|
|
1670
|
+
- `src/services/tauri/{command_name}.ts` (wrapper TS)
|
|
1671
|
+
|
|
1672
|
+
Comando Rust:
|
|
1673
|
+
- #[tauri::command]
|
|
1674
|
+
- fn {name}({params}) -> Result<{output}, String>
|
|
1675
|
+
- Validar inputs antes de ejecutar
|
|
1676
|
+
|
|
1677
|
+
## Reglas estrictas
|
|
1678
|
+
- Tipado estricto (String, no &str)
|
|
1679
|
+
- No permitir path traversal
|
|
1680
|
+
- Devolver error específico en español
|
|
1681
|
+
|
|
1682
|
+
## Anti-patrones
|
|
1683
|
+
- NO std::fs::read_to_string sin validar path
|
|
1684
|
+
- NO exponer comandos inseguros
|
|
1685
|
+
|
|
1686
|
+
## Formato de salida
|
|
1687
|
+
Código Rust + wrapper TypeScript + instrucción de registro.
|
|
1688
|
+
```
|
|
1689
|
+
</details>
|
|
1690
|
+
|
|
1691
|
+
### Reglas de la biblioteca
|
|
1692
|
+
|
|
1693
|
+
1. **Un prompt por archivo.** Si cubre dos cosas distintas, se divide.
|
|
1694
|
+
2. **Metadatos** (title, tags, usado_en, fecha) al inicio de cada archivo.
|
|
1695
|
+
3. **Solo se archiva lo probado.** Si no se usó en un proyecto real, no se agrega.
|
|
1696
|
+
4. **Los fallos también se guardan** en `HISTORIAL/` con nota de por qué no funcionó.
|
|
1697
|
+
5. **Para crear un nuevo prompt:** copia cualquier PLANTILLA, ajusta el contenido, renómbralo y agrega la entrada en `docs/PROMPTS/INDEX.md`.
|
|
1698
|
+
|
|
1699
|
+
> 📌 **Referencia rápida:** `docs/PROMPTS/INDEX.md` tiene el índice completo con descripciones y metadatos de cada prompt disponible.
|
|
1700
|
+
|
|
1701
|
+
---
|
|
1702
|
+
|
|
1703
|
+
```markdown
|
|
1704
|
+
# AGENTS.md — Contexto para IA
|
|
1705
|
+
|
|
1706
|
+
## Stack
|
|
1707
|
+
- React 18 + TypeScript + Vite
|
|
1708
|
+
- Ionic 8 + Capacitor 6 (mobile)
|
|
1709
|
+
- Tauri v2 (desktop)
|
|
1710
|
+
- Tailwind CSS 3.4
|
|
1711
|
+
- Zustand (estado global)
|
|
1712
|
+
- Supabase (backend)
|
|
1713
|
+
|
|
1714
|
+
## Convenciones
|
|
1715
|
+
- Un componente por archivo, máximo 120 líneas
|
|
1716
|
+
- Un hook por archivo, máximo 80 líneas
|
|
1717
|
+
- 100% Tailwind utility classes (sin CSS personalizado)
|
|
1718
|
+
- Barrel exports en cada carpeta
|
|
1719
|
+
- Commits: conventional commits + log en docs/COMMITS/
|
|
1720
|
+
- Errores: registrar en docs/LOGS/ERRORES/
|
|
1721
|
+
- Backlog: docs/BACKLOG/PHASE-*.md
|
|
1722
|
+
- Prompt library: docs/PROMPTS/INDEX.md (usar para tareas comunes)
|
|
1723
|
+
|
|
1724
|
+
## Perfil del desarrollador
|
|
1725
|
+
{Junior / Mid / Senior}
|
|
1726
|
+
|
|
1727
|
+
## Reglas críticas
|
|
1728
|
+
- NO mezclar lógica de Capacitor con Tauri en el mismo archivo
|
|
1729
|
+
- NO usar any
|
|
1730
|
+
- NO superar límites de líneas sin refactorizar
|
|
1731
|
+
- Ejecutar pipeline de validación antes de cada commit (./scripts/validate.sh)
|
|
1732
|
+
|
|
1733
|
+
## Referencias
|
|
1734
|
+
- Patrones detallados: docs/Framework de Desarrollo Asistido por IA.md
|
|
1735
|
+
- Prompt library: docs/PROMPTS/INDEX.md
|
|
1736
|
+
- Pipeline: docs/PIPELINE.md
|
|
1737
|
+
- Retrospectiva: docs/RETROSPECTIVA.md
|
|
1738
|
+
- Metodología completa: Metodologia_De_Desarrollo_IA_Asisted/
|
|
1739
|
+
```
|
|
1740
|
+
|
|
1741
|
+
> **Este archivo es el punto de entrada para la IA.** Cada prompt debe comenzar con "Revisa AGENTS.md y Framework de Desarrollo Asistido por IA.md antes de responder."
|