claude-agent-framework 1.0.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 (111) hide show
  1. package/README.md +128 -0
  2. package/bin/claude-framework +3 -0
  3. package/framework/agents/design-lead.md +240 -0
  4. package/framework/agents/product-owner.md +179 -0
  5. package/framework/agents/tech-lead.md +226 -0
  6. package/framework/commands/ayuda.md +127 -0
  7. package/framework/commands/a/303/261adir.md +98 -0
  8. package/framework/commands/backup.md +397 -0
  9. package/framework/commands/cambiar.md +110 -0
  10. package/framework/commands/cloud.md +457 -0
  11. package/framework/commands/code.md +142 -0
  12. package/framework/commands/debug.md +334 -0
  13. package/framework/commands/deploy.md +383 -0
  14. package/framework/commands/deshacer.md +120 -0
  15. package/framework/commands/estado.md +218 -0
  16. package/framework/commands/explica.md +227 -0
  17. package/framework/commands/feature.md +120 -0
  18. package/framework/commands/git.md +427 -0
  19. package/framework/commands/historial.md +202 -0
  20. package/framework/commands/learn.md +408 -0
  21. package/framework/commands/movil.md +245 -0
  22. package/framework/commands/nuevo.md +118 -0
  23. package/framework/commands/plan.md +134 -0
  24. package/framework/commands/prd.md +113 -0
  25. package/framework/commands/probar.md +148 -0
  26. package/framework/commands/revisar.md +208 -0
  27. package/framework/commands/seeds.md +230 -0
  28. package/framework/commands/seguridad.md +226 -0
  29. package/framework/commands/tasks.md +157 -0
  30. package/framework/skills/architecture/algorithms.md +970 -0
  31. package/framework/skills/architecture/clean-code.md +1080 -0
  32. package/framework/skills/architecture/design-patterns.md +1984 -0
  33. package/framework/skills/architecture/functional-programming.md +972 -0
  34. package/framework/skills/architecture/solid.md +991 -0
  35. package/framework/skills/cloud/cloud-aws.md +848 -0
  36. package/framework/skills/cloud/cloud-azure.md +931 -0
  37. package/framework/skills/cloud/cloud-gcp.md +848 -0
  38. package/framework/skills/cloud/message-queues.md +1229 -0
  39. package/framework/skills/core/accessibility.md +401 -0
  40. package/framework/skills/core/api.md +474 -0
  41. package/framework/skills/core/authentication.md +306 -0
  42. package/framework/skills/core/authorization.md +388 -0
  43. package/framework/skills/core/background-jobs.md +341 -0
  44. package/framework/skills/core/caching.md +473 -0
  45. package/framework/skills/core/code-review.md +341 -0
  46. package/framework/skills/core/controllers.md +290 -0
  47. package/framework/skills/core/cua.md +285 -0
  48. package/framework/skills/core/documentation.md +472 -0
  49. package/framework/skills/core/file-uploads.md +351 -0
  50. package/framework/skills/core/hotwire-native.md +296 -0
  51. package/framework/skills/core/hotwire.md +278 -0
  52. package/framework/skills/core/i18n.md +334 -0
  53. package/framework/skills/core/imports-exports.md +750 -0
  54. package/framework/skills/core/infrastructure.md +337 -0
  55. package/framework/skills/core/models.md +228 -0
  56. package/framework/skills/core/notifications.md +672 -0
  57. package/framework/skills/core/payments.md +581 -0
  58. package/framework/skills/core/performance.md +361 -0
  59. package/framework/skills/core/rails-scaffold.md +131 -0
  60. package/framework/skills/core/search.md +518 -0
  61. package/framework/skills/core/security.md +565 -0
  62. package/framework/skills/core/seeds.md +307 -0
  63. package/framework/skills/core/seo.md +542 -0
  64. package/framework/skills/core/testing.md +393 -0
  65. package/framework/skills/core/views.md +260 -0
  66. package/framework/skills/core/websockets.md +564 -0
  67. package/framework/skills/data/advanced-sql.md +1204 -0
  68. package/framework/skills/data/nosql.md +1141 -0
  69. package/framework/skills/devops/containers-advanced.md +1237 -0
  70. package/framework/skills/devops/debugging.md +834 -0
  71. package/framework/skills/devops/git-workflow.md +752 -0
  72. package/framework/skills/devops/networking.md +932 -0
  73. package/framework/skills/devops/shell-scripting.md +1132 -0
  74. package/framework/sub-agents/architecture-patterns-agent.md +1450 -0
  75. package/framework/sub-agents/cloud-agent.md +677 -0
  76. package/framework/sub-agents/data.md +504 -0
  77. package/framework/sub-agents/debugging-agent.md +554 -0
  78. package/framework/sub-agents/devops.md +483 -0
  79. package/framework/sub-agents/docs.md +176 -0
  80. package/framework/sub-agents/frontend-dev.md +349 -0
  81. package/framework/sub-agents/git-workflow-agent.md +697 -0
  82. package/framework/sub-agents/integrations.md +630 -0
  83. package/framework/sub-agents/native-dev.md +434 -0
  84. package/framework/sub-agents/qa.md +138 -0
  85. package/framework/sub-agents/rails-dev.md +375 -0
  86. package/framework/sub-agents/security.md +526 -0
  87. package/framework/sub-agents/ui.md +437 -0
  88. package/framework/sub-agents/ux.md +284 -0
  89. package/framework/templates/api-spec.md +500 -0
  90. package/framework/templates/component-spec.md +248 -0
  91. package/framework/templates/feature.json +13 -0
  92. package/framework/templates/model-spec.md +318 -0
  93. package/framework/templates/prd-template.md +80 -0
  94. package/framework/templates/task-plan.md +122 -0
  95. package/framework/templates/task-user-story.md +52 -0
  96. package/framework/templates/technical-spec.md +260 -0
  97. package/framework/templates/user-story.md +95 -0
  98. package/package.json +42 -0
  99. package/project-templates/CLAUDE.md +42 -0
  100. package/project-templates/contexts/architecture.md +25 -0
  101. package/project-templates/contexts/conventions.md +46 -0
  102. package/project-templates/contexts/design-system.md +47 -0
  103. package/project-templates/contexts/requirements.md +38 -0
  104. package/project-templates/contexts/stack.md +30 -0
  105. package/project-templates/history/active/models.md +11 -0
  106. package/project-templates/history/changelog.md +15 -0
  107. package/project-templates/workspace/.gitkeep +0 -0
  108. package/src/cli.js +52 -0
  109. package/src/init.js +104 -0
  110. package/src/status.js +75 -0
  111. package/src/update.js +88 -0
@@ -0,0 +1,397 @@
1
+ # Comando: /backup
2
+
3
+ ## Descripción
4
+
5
+ Gestiona backups de la base de datos y archivos de la aplicación.
6
+
7
+ ## Uso
8
+
9
+ ```
10
+ /backup [acción] [opciones]
11
+ ```
12
+
13
+ ## Acciones
14
+
15
+ | Acción | Descripción |
16
+ |--------|-------------|
17
+ | `crear` | Crea un backup completo (default) |
18
+ | `listar` | Lista backups disponibles |
19
+ | `restaurar` | Restaura un backup específico |
20
+ | `limpiar` | Elimina backups antiguos |
21
+
22
+ ## Proceso
23
+
24
+ ### 1. Backup de SQLite
25
+
26
+ ```bash
27
+ #!/bin/bash
28
+ # bin/backup
29
+
30
+ set -e
31
+
32
+ TIMESTAMP=$(date +%Y%m%d_%H%M%S)
33
+ BACKUP_DIR="backups"
34
+ DB_PATH="storage/production.sqlite3"
35
+
36
+ mkdir -p $BACKUP_DIR
37
+
38
+ echo "📦 Creando backup..."
39
+
40
+ # Método 1: sqlite3 .backup (recomendado - consistente)
41
+ sqlite3 $DB_PATH ".backup '$BACKUP_DIR/db_$TIMESTAMP.sqlite3'"
42
+
43
+ # Comprimir
44
+ gzip "$BACKUP_DIR/db_$TIMESTAMP.sqlite3"
45
+
46
+ echo "✅ Backup creado: $BACKUP_DIR/db_$TIMESTAMP.sqlite3.gz"
47
+
48
+ # Limpiar backups antiguos (mantener últimos 7 días)
49
+ find $BACKUP_DIR -name "*.gz" -mtime +7 -delete
50
+
51
+ echo "🧹 Backups antiguos eliminados"
52
+ ```
53
+
54
+ ### 2. Rake tasks completas
55
+
56
+ ```ruby
57
+ # lib/tasks/backup.rake
58
+ namespace :backup do
59
+ desc "Crear backup de base de datos"
60
+ task db: :environment do
61
+ require "fileutils"
62
+
63
+ timestamp = Time.current.strftime("%Y%m%d_%H%M%S")
64
+ backup_dir = Rails.root.join("backups")
65
+ FileUtils.mkdir_p(backup_dir)
66
+
67
+ db_config = ActiveRecord::Base.connection_db_config
68
+ db_path = db_config.database
69
+
70
+ backup_file = backup_dir.join("db_#{timestamp}.sqlite3")
71
+
72
+ puts "📦 Creando backup de base de datos..."
73
+
74
+ # Usar sqlite3 .backup para consistencia
75
+ system("sqlite3 #{db_path} '.backup #{backup_file}'")
76
+
77
+ # Comprimir
78
+ system("gzip #{backup_file}")
79
+
80
+ puts "✅ Backup creado: #{backup_file}.gz"
81
+ puts " Tamaño: #{File.size("#{backup_file}.gz") / 1024} KB"
82
+ end
83
+
84
+ desc "Crear backup de archivos (Active Storage)"
85
+ task files: :environment do
86
+ require "fileutils"
87
+
88
+ timestamp = Time.current.strftime("%Y%m%d_%H%M%S")
89
+ backup_dir = Rails.root.join("backups")
90
+ storage_dir = Rails.root.join("storage")
91
+
92
+ backup_file = backup_dir.join("files_#{timestamp}.tar.gz")
93
+
94
+ puts "📦 Creando backup de archivos..."
95
+
96
+ system("tar -czf #{backup_file} -C #{storage_dir} .")
97
+
98
+ puts "✅ Backup de archivos creado: #{backup_file}"
99
+ puts " Tamaño: #{File.size(backup_file) / 1024 / 1024} MB"
100
+ end
101
+
102
+ desc "Crear backup completo (BD + archivos)"
103
+ task full: [:db, :files] do
104
+ puts "✅ Backup completo finalizado"
105
+ end
106
+
107
+ desc "Listar backups disponibles"
108
+ task list: :environment do
109
+ backup_dir = Rails.root.join("backups")
110
+
111
+ unless backup_dir.exist?
112
+ puts "No hay backups disponibles"
113
+ return
114
+ end
115
+
116
+ puts "\n📋 Backups disponibles:\n\n"
117
+
118
+ Dir.glob(backup_dir.join("*.gz")).sort.reverse.each do |file|
119
+ name = File.basename(file)
120
+ size = File.size(file) / 1024
121
+ date = File.mtime(file).strftime("%Y-%m-%d %H:%M")
122
+
123
+ puts " #{name}"
124
+ puts " Fecha: #{date}"
125
+ puts " Tamaño: #{size} KB"
126
+ puts ""
127
+ end
128
+ end
129
+
130
+ desc "Restaurar backup de base de datos"
131
+ task :restore, [:filename] => :environment do |t, args|
132
+ unless args[:filename]
133
+ puts "❌ Especifica el archivo: rake backup:restore[db_20240101_120000.sqlite3.gz]"
134
+ exit 1
135
+ end
136
+
137
+ backup_file = Rails.root.join("backups", args[:filename])
138
+
139
+ unless File.exist?(backup_file)
140
+ puts "❌ Archivo no encontrado: #{backup_file}"
141
+ exit 1
142
+ end
143
+
144
+ db_config = ActiveRecord::Base.connection_db_config
145
+ db_path = db_config.database
146
+
147
+ puts "⚠️ ADVERTENCIA: Esto reemplazará la base de datos actual"
148
+ puts " Base de datos: #{db_path}"
149
+ puts " Backup: #{backup_file}"
150
+ print "\n¿Continuar? (yes/no): "
151
+
152
+ confirmation = STDIN.gets.chomp
153
+ unless confirmation == "yes"
154
+ puts "Cancelado"
155
+ exit 0
156
+ end
157
+
158
+ puts "\n🔄 Restaurando..."
159
+
160
+ # Crear backup del estado actual
161
+ current_backup = "#{db_path}.before_restore"
162
+ FileUtils.cp(db_path, current_backup)
163
+ puts " Backup actual guardado en: #{current_backup}"
164
+
165
+ # Descomprimir si es necesario
166
+ if backup_file.to_s.end_with?(".gz")
167
+ system("gunzip -k #{backup_file}")
168
+ backup_file = backup_file.to_s.gsub(".gz", "")
169
+ end
170
+
171
+ # Restaurar
172
+ FileUtils.cp(backup_file, db_path)
173
+
174
+ # Limpiar archivo descomprimido temporal
175
+ FileUtils.rm(backup_file) if File.exist?(backup_file) && backup_file != args[:filename]
176
+
177
+ puts "✅ Base de datos restaurada"
178
+ puts "\n💡 Si hay problemas, el backup anterior está en: #{current_backup}"
179
+ end
180
+
181
+ desc "Limpiar backups antiguos"
182
+ task :clean, [:days] => :environment do |t, args|
183
+ days = (args[:days] || 7).to_i
184
+ backup_dir = Rails.root.join("backups")
185
+
186
+ puts "🧹 Eliminando backups de más de #{days} días..."
187
+
188
+ count = 0
189
+ Dir.glob(backup_dir.join("*.gz")).each do |file|
190
+ if File.mtime(file) < days.days.ago
191
+ FileUtils.rm(file)
192
+ count += 1
193
+ puts " Eliminado: #{File.basename(file)}"
194
+ end
195
+ end
196
+
197
+ puts "✅ #{count} backups eliminados"
198
+ end
199
+ end
200
+ ```
201
+
202
+ ### 3. Backup automático con cron
203
+
204
+ ```ruby
205
+ # config/schedule.rb (con whenever gem)
206
+ every 1.day, at: "3:00 am" do
207
+ rake "backup:full"
208
+ end
209
+
210
+ every :sunday, at: "4:00 am" do
211
+ rake "backup:clean[30]"
212
+ end
213
+ ```
214
+
215
+ ### 4. Backup a S3/R2
216
+
217
+ ```ruby
218
+ # lib/tasks/backup.rake
219
+ namespace :backup do
220
+ desc "Subir backup a S3"
221
+ task upload: :environment do
222
+ require "aws-sdk-s3"
223
+
224
+ backup_dir = Rails.root.join("backups")
225
+ latest_backup = Dir.glob(backup_dir.join("db_*.gz")).max_by { |f| File.mtime(f) }
226
+
227
+ unless latest_backup
228
+ puts "❌ No hay backups para subir"
229
+ exit 1
230
+ end
231
+
232
+ s3 = Aws::S3::Resource.new(
233
+ region: Rails.application.credentials.dig(:aws, :region),
234
+ access_key_id: Rails.application.credentials.dig(:aws, :access_key_id),
235
+ secret_access_key: Rails.application.credentials.dig(:aws, :secret_access_key)
236
+ )
237
+
238
+ bucket = s3.bucket(Rails.application.credentials.dig(:aws, :backup_bucket))
239
+ filename = File.basename(latest_backup)
240
+
241
+ puts "📤 Subiendo #{filename} a S3..."
242
+
243
+ obj = bucket.object("backups/#{filename}")
244
+ obj.upload_file(latest_backup)
245
+
246
+ puts "✅ Backup subido exitosamente"
247
+ end
248
+
249
+ desc "Backup completo con upload a S3"
250
+ task remote: [:full, :upload] do
251
+ puts "✅ Backup remoto completado"
252
+ end
253
+ end
254
+ ```
255
+
256
+ ### 5. Backup en Fly.io
257
+
258
+ ```bash
259
+ #!/bin/bash
260
+ # bin/backup-fly
261
+
262
+ # Crear backup en la máquina
263
+ fly ssh console -C "bin/rails backup:db"
264
+
265
+ # Descargar backup
266
+ fly ssh sftp get /rails/backups/$(fly ssh console -C "ls -t /rails/backups | head -1")
267
+ ```
268
+
269
+ ### 6. Modelo de auditoría de backups
270
+
271
+ ```ruby
272
+ # app/models/backup_log.rb
273
+ class BackupLog < ApplicationRecord
274
+ enum :status, { started: 0, completed: 1, failed: 2 }
275
+ enum :backup_type, { database: 0, files: 1, full: 2 }
276
+
277
+ validates :backup_type, presence: true
278
+
279
+ def self.log_backup(type:, &block)
280
+ log = create!(backup_type: type, status: :started, started_at: Time.current)
281
+
282
+ begin
283
+ result = yield
284
+ log.update!(
285
+ status: :completed,
286
+ completed_at: Time.current,
287
+ file_path: result[:file_path],
288
+ file_size: result[:file_size]
289
+ )
290
+ rescue => e
291
+ log.update!(
292
+ status: :failed,
293
+ completed_at: Time.current,
294
+ error_message: e.message
295
+ )
296
+ raise
297
+ end
298
+
299
+ log
300
+ end
301
+ end
302
+
303
+ # Uso en rake task
304
+ BackupLog.log_backup(type: :database) do
305
+ # ... crear backup ...
306
+ { file_path: backup_file, file_size: File.size(backup_file) }
307
+ end
308
+ ```
309
+
310
+ ## Ejemplo de salida
311
+
312
+ ### /backup crear
313
+
314
+ ```
315
+ 📦 Iniciando backup completo...
316
+
317
+ 🗃️ Base de datos:
318
+ → Archivo: db_20240115_143022.sqlite3.gz
319
+ → Tamaño: 2.3 MB
320
+ → ✅ Completado
321
+
322
+ 📁 Archivos (Active Storage):
323
+ → Archivo: files_20240115_143022.tar.gz
324
+ → Tamaño: 156 MB
325
+ → ✅ Completado
326
+
327
+ ✅ Backup completo finalizado
328
+
329
+ 📍 Ubicación: /backups/
330
+ - db_20240115_143022.sqlite3.gz
331
+ - files_20240115_143022.tar.gz
332
+ ```
333
+
334
+ ### /backup listar
335
+
336
+ ```
337
+ 📋 Backups disponibles:
338
+
339
+ db_20240115_143022.sqlite3.gz
340
+ Fecha: 2024-01-15 14:30
341
+ Tamaño: 2.3 MB
342
+
343
+ db_20240114_030000.sqlite3.gz
344
+ Fecha: 2024-01-14 03:00
345
+ Tamaño: 2.1 MB
346
+
347
+ db_20240113_030000.sqlite3.gz
348
+ Fecha: 2024-01-13 03:00
349
+ Tamaño: 2.0 MB
350
+
351
+ Total: 3 backups (6.4 MB)
352
+ ```
353
+
354
+ ### /backup restaurar
355
+
356
+ ```
357
+ ⚠️ RESTAURAR BACKUP
358
+
359
+ Esto reemplazará la base de datos actual con:
360
+ db_20240114_030000.sqlite3.gz (2024-01-14 03:00)
361
+
362
+ ¿Estás seguro? (sí/no): sí
363
+
364
+ 🔄 Restaurando...
365
+ → Backup actual guardado en: production.sqlite3.before_restore
366
+ → Descomprimiendo backup...
367
+ → Reemplazando base de datos...
368
+
369
+ ✅ Base de datos restaurada exitosamente
370
+
371
+ 💡 Si hay problemas, ejecuta:
372
+ cp storage/production.sqlite3.before_restore storage/production.sqlite3
373
+ ```
374
+
375
+ ## Respuesta del agente
376
+
377
+ Al ejecutar `/backup`, el agente:
378
+
379
+ 1. **Determina acción**
380
+ - Si no se especifica, asume "crear"
381
+ - Parsea opciones adicionales
382
+
383
+ 2. **Ejecuta backup**
384
+ - Verifica espacio disponible
385
+ - Crea backup consistente de SQLite
386
+ - Comprime archivos
387
+ - Opcionalmente sube a storage remoto
388
+
389
+ 3. **Registra resultado**
390
+ - Guarda log de backup
391
+ - Muestra ubicación y tamaño
392
+ - Limpia backups antiguos si está configurado
393
+
394
+ 4. **Maneja restauración**
395
+ - Pide confirmación explícita
396
+ - Crea backup del estado actual antes de restaurar
397
+ - Proporciona instrucciones de rollback
@@ -0,0 +1,110 @@
1
+ # Comando: /cambiar
2
+
3
+ Modifica algo existente en el proyecto.
4
+
5
+ ## Flujo de trabajo
6
+
7
+ ### Paso 1: Entender el cambio
8
+
9
+ 1. Escucha qué quiere cambiar el usuario
10
+ 2. Identifica el tipo de cambio:
11
+ - **Visual**: Colores, tamaños, disposición
12
+ - **Funcional**: Comportamiento, lógica
13
+ - **Estructural**: Modelos, relaciones
14
+ - **Contenido**: Textos, etiquetas
15
+
16
+ 3. Pregunta para clarificar:
17
+ - ¿Qué está mal con cómo funciona ahora?
18
+ - ¿Cómo debería funcionar/verse en su lugar?
19
+ - ¿Esto afecta a otras partes de la app?
20
+
21
+ ### Paso 2: Localizar el código
22
+
23
+ 1. Busca los archivos afectados
24
+ 2. Lee el código actual para entender cómo funciona
25
+ 3. Identifica todas las dependencias y efectos secundarios
26
+
27
+ ### Paso 3: Planificar el cambio
28
+
29
+ 1. Explica al usuario qué archivos se modificarán
30
+ 2. Describe el impacto del cambio
31
+ 3. Si hay riesgos, adviértelos
32
+ 4. Confirma antes de proceder
33
+
34
+ ### Paso 4: Hacer backup (si es cambio mayor)
35
+
36
+ Si el cambio es significativo:
37
+
38
+ 1. Guarda el estado actual en `.claude/history/legacy/`:
39
+ ```
40
+ .claude/history/legacy/[timestamp]_[descripción]/
41
+ ├── archivos_modificados/
42
+ └── descripción.md
43
+ ```
44
+
45
+ ### Paso 5: Implementar el cambio
46
+
47
+ 1. Realiza las modificaciones necesarias
48
+ 2. Mantén los tests actualizados
49
+ 3. Verifica que nada más se rompa
50
+
51
+ ### Paso 6: Verificar
52
+
53
+ 1. Ejecuta los tests: `bundle exec rspec`
54
+ 2. Revisa visualmente si es un cambio de UI
55
+ 3. Prueba flujos relacionados
56
+
57
+ ### Paso 7: Documentar
58
+
59
+ Actualiza `.claude/history/changelog.md`:
60
+ ```markdown
61
+ ## [Fecha] - Modificado: [Qué se cambió]
62
+
63
+ ### Motivo
64
+ [Por qué se hizo el cambio]
65
+
66
+ ### Cambios realizados
67
+ - Archivo: [ruta] - [descripción del cambio]
68
+
69
+ ### Estado anterior
70
+ [Breve descripción de cómo era antes]
71
+ ```
72
+
73
+ ### Paso 8: Confirmar
74
+
75
+ Muestra al usuario:
76
+ - Qué se cambió
77
+ - Antes vs después (si aplica)
78
+ - Cómo verificar el cambio
79
+
80
+ ## Tipos comunes de cambios
81
+
82
+ ### Cambios visuales
83
+ - Colores: Modificar variables en Tailwind o clases
84
+ - Tamaños: Ajustar clases de Tailwind
85
+ - Layout: Reorganizar estructura HTML
86
+
87
+ ### Cambios funcionales
88
+ - Validaciones: Modificar modelos
89
+ - Comportamiento: Ajustar controladores o Stimulus
90
+ - Flujos: Cambiar redirecciones o lógica
91
+
92
+ ### Cambios de datos
93
+ - Campos: Crear migración para añadir/modificar/eliminar
94
+ - Relaciones: Actualizar modelos y migraciones
95
+
96
+ ## Ejemplos de uso
97
+
98
+ - "El botón debería ser verde, no azul"
99
+ - "Quiero que el título sea más grande"
100
+ - "El formulario debería tener un campo más"
101
+ - "Los artículos deberían ordenarse por fecha, no alfabéticamente"
102
+ - "Cambia el texto de 'Enviar' a 'Publicar'"
103
+
104
+ ## Notas importantes
105
+
106
+ - Siempre lee el código antes de modificarlo
107
+ - Haz backup de cambios importantes
108
+ - Actualiza los tests si cambia el comportamiento
109
+ - Confirma cambios grandes antes de implementarlos
110
+ - Si el cambio es muy complejo, sugiere dividirlo en pasos