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,248 @@
1
+ # Component Specification Template
2
+
3
+ ## Información General
4
+
5
+ | Campo | Valor |
6
+ |-------|-------|
7
+ | Nombre | [Nombre del componente] |
8
+ | Tipo | UI / Funcional / Layout |
9
+ | Ubicación | `app/views/shared/_component.html.erb` |
10
+ | Estado | Diseño / Desarrollo / Completado |
11
+
12
+ ## Descripción
13
+
14
+ [Breve descripción del propósito del componente]
15
+
16
+ ## Vista Previa
17
+
18
+ ```
19
+ ┌─────────────────────────────────────┐
20
+ │ [Representación ASCII del diseño] │
21
+ │ │
22
+ │ ┌───────────────────────────────┐ │
23
+ │ │ Contenido │ │
24
+ │ └───────────────────────────────┘ │
25
+ │ │
26
+ │ [ Botón ] │
27
+ │ │
28
+ └─────────────────────────────────────┘
29
+ ```
30
+
31
+ ## Variantes
32
+
33
+ ### Variante Default
34
+ [Descripción y cuándo usar]
35
+
36
+ ### Variante [Nombre]
37
+ [Descripción y cuándo usar]
38
+
39
+ ### Variante [Nombre]
40
+ [Descripción y cuándo usar]
41
+
42
+ ## Props / Parámetros
43
+
44
+ | Nombre | Tipo | Requerido | Default | Descripción |
45
+ |--------|------|-----------|---------|-------------|
46
+ | `title` | String | Sí | - | Título principal |
47
+ | `description` | String | No | nil | Texto descriptivo |
48
+ | `variant` | Symbol | No | :default | Estilo visual |
49
+ | `data` | Hash | No | {} | Data attributes adicionales |
50
+
51
+ ## Uso
52
+
53
+ ### Básico
54
+ ```erb
55
+ <%= render "shared/component", title: "Mi Título" %>
56
+ ```
57
+
58
+ ### Con todas las opciones
59
+ ```erb
60
+ <%= render "shared/component",
61
+ title: "Mi Título",
62
+ description: "Descripción opcional",
63
+ variant: :outlined,
64
+ data: { controller: "my-controller" } %>
65
+ ```
66
+
67
+ ### Con bloque
68
+ ```erb
69
+ <%= render "shared/component", title: "Mi Título" do %>
70
+ <p>Contenido personalizado</p>
71
+ <% end %>
72
+ ```
73
+
74
+ ## Implementación
75
+
76
+ ### ERB Template
77
+ ```erb
78
+ <%# app/views/shared/_component.html.erb %>
79
+ <%# locals: (title:, description: nil, variant: :default, data: {}) %>
80
+ <%
81
+ base_classes = "rounded-lg shadow"
82
+ variant_classes = case variant
83
+ when :outlined then "border-2 border-gray-200"
84
+ when :filled then "bg-gray-100"
85
+ else "bg-white"
86
+ end
87
+ classes = "#{base_classes} #{variant_classes}"
88
+ %>
89
+
90
+ <div class="<%= classes %>"
91
+ <%= tag.attributes(data) %>>
92
+ <h3 class="text-lg font-semibold text-gray-900">
93
+ <%= title %>
94
+ </h3>
95
+
96
+ <% if description.present? %>
97
+ <p class="mt-2 text-gray-600">
98
+ <%= description %>
99
+ </p>
100
+ <% end %>
101
+
102
+ <% if block_given? %>
103
+ <div class="mt-4">
104
+ <%= yield %>
105
+ </div>
106
+ <% end %>
107
+ </div>
108
+ ```
109
+
110
+ ### Stimulus Controller (si aplica)
111
+ ```javascript
112
+ // app/javascript/controllers/component_controller.js
113
+ import { Controller } from "@hotwired/stimulus"
114
+
115
+ export default class extends Controller {
116
+ static targets = ["content"]
117
+ static values = {
118
+ expanded: { type: Boolean, default: false }
119
+ }
120
+ static classes = ["hidden"]
121
+
122
+ toggle() {
123
+ this.expandedValue = !this.expandedValue
124
+ }
125
+
126
+ expandedValueChanged() {
127
+ this.contentTarget.classList.toggle(this.hiddenClass, !this.expandedValue)
128
+ }
129
+ }
130
+ ```
131
+
132
+ ## Estilos
133
+
134
+ ### Clases de Tailwind utilizadas
135
+
136
+ | Clase | Propósito |
137
+ |-------|-----------|
138
+ | `rounded-lg` | Bordes redondeados |
139
+ | `shadow` | Sombra sutil |
140
+ | `p-4` | Padding interno |
141
+ | `text-lg` | Tamaño de texto título |
142
+ | `font-semibold` | Peso de fuente título |
143
+
144
+ ### Customización
145
+ ```erb
146
+ <%# Añadir clases adicionales %>
147
+ <%= render "shared/component",
148
+ title: "Título",
149
+ class: "my-custom-class" %>
150
+ ```
151
+
152
+ ## Estados
153
+
154
+ ### Default
155
+ [Descripción del estado normal]
156
+
157
+ ### Hover
158
+ [Comportamiento al pasar el mouse]
159
+
160
+ ### Focus
161
+ [Comportamiento al recibir foco]
162
+
163
+ ### Disabled
164
+ [Comportamiento cuando está deshabilitado]
165
+
166
+ ### Loading
167
+ [Comportamiento durante carga]
168
+
169
+ ## Accesibilidad
170
+
171
+ | Aspecto | Implementación |
172
+ |---------|---------------|
173
+ | Rol ARIA | `role="[rol]"` |
174
+ | Labels | `aria-label="[descripción]"` |
175
+ | Focus | Orden lógico, visible |
176
+ | Keyboard | [Teclas soportadas] |
177
+
178
+ ### Ejemplo accesible
179
+ ```erb
180
+ <div role="region"
181
+ aria-labelledby="component-title-<%= id %>">
182
+ <h3 id="component-title-<%= id %>">
183
+ <%= title %>
184
+ </h3>
185
+ </div>
186
+ ```
187
+
188
+ ## Responsive
189
+
190
+ | Breakpoint | Comportamiento |
191
+ |------------|----------------|
192
+ | Mobile (< 640px) | [Descripción] |
193
+ | Tablet (640-1024px) | [Descripción] |
194
+ | Desktop (> 1024px) | [Descripción] |
195
+
196
+ ## Tests
197
+
198
+ ```ruby
199
+ # spec/views/shared/_component.html.erb_spec.rb
200
+ require "rails_helper"
201
+
202
+ RSpec.describe "shared/_component", type: :view do
203
+ it "renders title" do
204
+ render partial: "shared/component", locals: { title: "Test" }
205
+ expect(rendered).to have_text("Test")
206
+ end
207
+
208
+ it "renders description when provided" do
209
+ render partial: "shared/component",
210
+ locals: { title: "Test", description: "Desc" }
211
+ expect(rendered).to have_text("Desc")
212
+ end
213
+
214
+ it "renders block content" do
215
+ render partial: "shared/component", locals: { title: "Test" } do
216
+ "Custom content"
217
+ end
218
+ expect(rendered).to have_text("Custom content")
219
+ end
220
+ end
221
+ ```
222
+
223
+ ## Ejemplos de Uso Real
224
+
225
+ ### En página de artículos
226
+ ```erb
227
+ <%= render "shared/component",
228
+ title: @article.title,
229
+ description: @article.excerpt %>
230
+ ```
231
+
232
+ ### En dashboard
233
+ ```erb
234
+ <%= render "shared/component", title: "Estadísticas" do %>
235
+ <%= render "dashboard/stats_chart" %>
236
+ <% end %>
237
+ ```
238
+
239
+ ## Notas de Implementación
240
+
241
+ - [Nota importante 1]
242
+ - [Nota importante 2]
243
+
244
+ ## Changelog
245
+
246
+ | Versión | Fecha | Cambios |
247
+ |---------|-------|---------|
248
+ | 1.0 | [Fecha] | Versión inicial |
@@ -0,0 +1,13 @@
1
+ {
2
+ "version": "1.0",
3
+ "id": "{YYYY-MM-DD-hhmmss}-{slug}",
4
+ "title": "{título inferido}",
5
+ "description": "{descripción}",
6
+ "original_request": "{texto exacto del usuario}",
7
+ "created_at": "{ISO timestamp}",
8
+ "updated_at": "{ISO timestamp}",
9
+ "status": "created",
10
+ "progress": 0,
11
+ "current_phase": "initial",
12
+ "tasks": []
13
+ }
@@ -0,0 +1,318 @@
1
+ # Model Specification Template
2
+
3
+ ## Información General
4
+
5
+ | Campo | Valor |
6
+ |-------|-------|
7
+ | Nombre | [NombreModelo] |
8
+ | Tabla | [nombre_modelos] |
9
+ | Archivo | `app/models/nombre_modelo.rb` |
10
+ | Estado | Diseño / Implementado |
11
+
12
+ ## Descripción
13
+
14
+ [Descripción del propósito del modelo y su rol en el dominio]
15
+
16
+ ## Diagrama de Relaciones
17
+
18
+ ```
19
+ ┌─────────────┐
20
+ │ User │
21
+ └──────┬──────┘
22
+
23
+ │ has_many
24
+
25
+ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
26
+ │ Category │◄────│ Article │────►│ Comment │
27
+ └─────────────┘ └─────────────┘ └─────────────┘
28
+
29
+ │ has_many_attached
30
+
31
+ ┌─────────────┐
32
+ │ Images │
33
+ └─────────────┘
34
+ ```
35
+
36
+ ## Atributos
37
+
38
+ | Nombre | Tipo | Null | Default | Descripción |
39
+ |--------|------|------|---------|-------------|
40
+ | `id` | bigint | No | auto | Primary key |
41
+ | `field_name` | string | No | - | Descripción del campo |
42
+ | `description` | text | Sí | nil | Descripción larga |
43
+ | `status` | string | No | 'draft' | Estado del registro |
44
+ | `published` | boolean | No | false | Si está publicado |
45
+ | `amount` | decimal | Sí | nil | Valor monetario |
46
+ | `user_id` | bigint | No | - | FK a users |
47
+ | `created_at` | datetime | No | auto | Fecha creación |
48
+ | `updated_at` | datetime | No | auto | Fecha actualización |
49
+
50
+ ## Migración
51
+
52
+ ```ruby
53
+ class CreateModelNames < ActiveRecord::Migration[8.0]
54
+ def change
55
+ create_table :model_names do |t|
56
+ t.string :field_name, null: false
57
+ t.text :description
58
+ t.string :status, null: false, default: 'draft'
59
+ t.boolean :published, null: false, default: false
60
+ t.decimal :amount, precision: 10, scale: 2
61
+ t.references :user, null: false, foreign_key: true
62
+
63
+ t.timestamps
64
+ end
65
+
66
+ add_index :model_names, :status
67
+ add_index :model_names, :published
68
+ add_index :model_names, [:user_id, :status]
69
+ end
70
+ end
71
+ ```
72
+
73
+ ## Asociaciones
74
+
75
+ | Tipo | Modelo | Opciones | Descripción |
76
+ |------|--------|----------|-------------|
77
+ | `belongs_to` | `:user` | - | Usuario propietario |
78
+ | `has_many` | `:comments` | `dependent: :destroy` | Comentarios |
79
+ | `has_many` | `:tags` | `through: :taggings` | Tags asociadas |
80
+ | `has_one_attached` | `:image` | - | Imagen principal |
81
+ | `has_many_attached` | `:documents` | - | Documentos adjuntos |
82
+
83
+ ## Validaciones
84
+
85
+ | Campo | Validación | Opciones | Mensaje |
86
+ |-------|------------|----------|---------|
87
+ | `field_name` | `presence` | - | "no puede estar vacío" |
88
+ | `field_name` | `length` | `maximum: 255` | "máximo 255 caracteres" |
89
+ | `field_name` | `uniqueness` | `scope: :user_id` | "ya existe" |
90
+ | `status` | `inclusion` | `in: STATUSES` | "estado inválido" |
91
+ | `amount` | `numericality` | `greater_than: 0` | "debe ser mayor a 0" |
92
+
93
+ ## Callbacks
94
+
95
+ | Tipo | Método | Descripción |
96
+ |------|--------|-------------|
97
+ | `before_validation` | `:normalize_data` | Limpia y normaliza datos |
98
+ | `before_save` | `:generate_slug` | Genera slug del título |
99
+ | `after_create` | `:send_notification` | Envía notificación |
100
+ | `after_commit` | `:update_search_index` | Actualiza índice (on create/update) |
101
+
102
+ ## Scopes
103
+
104
+ | Nombre | Query | Descripción |
105
+ |--------|-------|-------------|
106
+ | `published` | `where(published: true)` | Solo publicados |
107
+ | `draft` | `where(published: false)` | Solo borradores |
108
+ | `recent` | `order(created_at: :desc)` | Ordenados por fecha |
109
+ | `by_status` | `where(status: status)` | Filtrar por status |
110
+ | `search` | `where("title LIKE ?", "%#{q}%")` | Búsqueda por título |
111
+
112
+ ## Métodos de Clase
113
+
114
+ ### `self.search(query)`
115
+ ```ruby
116
+ def self.search(query)
117
+ return all if query.blank?
118
+ where("field_name ILIKE ?", "%#{query}%")
119
+ end
120
+ ```
121
+
122
+ ### `self.statistics`
123
+ ```ruby
124
+ def self.statistics
125
+ {
126
+ total: count,
127
+ published: published.count,
128
+ draft: draft.count
129
+ }
130
+ end
131
+ ```
132
+
133
+ ## Métodos de Instancia
134
+
135
+ ### `#publish!`
136
+ ```ruby
137
+ def publish!
138
+ update!(published: true, published_at: Time.current)
139
+ end
140
+ ```
141
+ Publica el registro y guarda la fecha.
142
+
143
+ ### `#owned_by?(user)`
144
+ ```ruby
145
+ def owned_by?(user)
146
+ self.user == user
147
+ end
148
+ ```
149
+ Verifica si el usuario es propietario.
150
+
151
+ ### `#status_label`
152
+ ```ruby
153
+ def status_label
154
+ I18n.t("model_name.status.#{status}")
155
+ end
156
+ ```
157
+ Devuelve etiqueta traducida del status.
158
+
159
+ ## Enums / Constantes
160
+
161
+ ```ruby
162
+ STATUSES = %w[draft pending published archived].freeze
163
+
164
+ # O usando enum de Rails (si aplica)
165
+ enum :status, {
166
+ draft: 'draft',
167
+ pending: 'pending',
168
+ published: 'published',
169
+ archived: 'archived'
170
+ }, default: :draft
171
+ ```
172
+
173
+ ## Implementación Completa
174
+
175
+ ```ruby
176
+ # app/models/model_name.rb
177
+ class ModelName < ApplicationRecord
178
+ # Constants
179
+ STATUSES = %w[draft pending published archived].freeze
180
+
181
+ # Associations
182
+ belongs_to :user
183
+ has_many :comments, dependent: :destroy
184
+ has_many :taggings, dependent: :destroy
185
+ has_many :tags, through: :taggings
186
+ has_one_attached :image
187
+
188
+ # Validations
189
+ validates :field_name, presence: true,
190
+ length: { maximum: 255 },
191
+ uniqueness: { scope: :user_id }
192
+ validates :status, inclusion: { in: STATUSES }
193
+ validates :amount, numericality: { greater_than: 0 }, allow_nil: true
194
+
195
+ # Callbacks
196
+ before_validation :normalize_data
197
+ before_save :generate_slug
198
+
199
+ # Scopes
200
+ scope :published, -> { where(published: true) }
201
+ scope :draft, -> { where(published: false) }
202
+ scope :recent, -> { order(created_at: :desc) }
203
+ scope :by_status, ->(status) { where(status: status) }
204
+
205
+ # Class methods
206
+ def self.search(query)
207
+ return all if query.blank?
208
+ where("field_name ILIKE ?", "%#{query}%")
209
+ end
210
+
211
+ # Instance methods
212
+ def publish!
213
+ update!(published: true, published_at: Time.current)
214
+ end
215
+
216
+ def owned_by?(user)
217
+ self.user == user
218
+ end
219
+
220
+ private
221
+
222
+ def normalize_data
223
+ self.field_name = field_name&.strip
224
+ end
225
+
226
+ def generate_slug
227
+ self.slug = field_name.parameterize if slug.blank?
228
+ end
229
+ end
230
+ ```
231
+
232
+ ## Factory
233
+
234
+ ```ruby
235
+ # spec/factories/model_names.rb
236
+ FactoryBot.define do
237
+ factory :model_name do
238
+ user
239
+ field_name { Faker::Lorem.sentence(word_count: 3) }
240
+ description { Faker::Lorem.paragraph }
241
+ status { ModelName::STATUSES.sample }
242
+ published { false }
243
+
244
+ trait :published do
245
+ published { true }
246
+ published_at { Time.current }
247
+ end
248
+
249
+ trait :with_image do
250
+ after(:build) do |record|
251
+ record.image.attach(
252
+ io: File.open(Rails.root.join("spec/fixtures/files/test.jpg")),
253
+ filename: "test.jpg"
254
+ )
255
+ end
256
+ end
257
+ end
258
+ end
259
+ ```
260
+
261
+ ## Tests
262
+
263
+ ```ruby
264
+ # spec/models/model_name_spec.rb
265
+ require "rails_helper"
266
+
267
+ RSpec.describe ModelName, type: :model do
268
+ describe "validations" do
269
+ it { should validate_presence_of(:field_name) }
270
+ it { should validate_length_of(:field_name).is_at_most(255) }
271
+ it { should validate_inclusion_of(:status).in_array(ModelName::STATUSES) }
272
+ end
273
+
274
+ describe "associations" do
275
+ it { should belong_to(:user) }
276
+ it { should have_many(:comments).dependent(:destroy) }
277
+ end
278
+
279
+ describe "scopes" do
280
+ describe ".published" do
281
+ it "returns only published records" do
282
+ published = create(:model_name, :published)
283
+ draft = create(:model_name, published: false)
284
+
285
+ expect(ModelName.published).to include(published)
286
+ expect(ModelName.published).not_to include(draft)
287
+ end
288
+ end
289
+ end
290
+
291
+ describe "#publish!" do
292
+ it "marks record as published" do
293
+ record = create(:model_name, published: false)
294
+
295
+ record.publish!
296
+
297
+ expect(record.reload).to be_published
298
+ expect(record.published_at).to be_present
299
+ end
300
+ end
301
+ end
302
+ ```
303
+
304
+ ## Consideraciones
305
+
306
+ ### Seguridad
307
+ - [ ] Autorización implementada en controlador/policy
308
+ - [ ] Strong parameters definidos
309
+ - [ ] Validaciones de usuario
310
+
311
+ ### Rendimiento
312
+ - [ ] Índices en columnas frecuentemente consultadas
313
+ - [ ] Eager loading configurado donde sea necesario
314
+ - [ ] Counter caches si hay conteos frecuentes
315
+
316
+ ### Notas
317
+ - [Nota adicional 1]
318
+ - [Nota adicional 2]
@@ -0,0 +1,80 @@
1
+ # {Título del Feature}
2
+
3
+ ## Metadata
4
+ feature_id: `{feature_id}`
5
+ created_at: `{timestamp}`
6
+ status: `prd_created`
7
+
8
+ ## Análisis de PRDs Existentes
9
+
10
+ ### PRDs Revisados
11
+ {Lista de PRDs existentes que se revisaron}
12
+
13
+ ### Matriz de Solapamiento
14
+
15
+ | Aspecto | Este PRD | PRD Existente | Conflicto? |
16
+ |---------|----------|---------------|------------|
17
+ | {aspecto 1} | {RF-XX} | {feature/RF-XX} | SÍ/NO |
18
+ | {aspecto 2} | {RF-XX} | {feature/RF-XX} | SÍ/NO |
19
+
20
+ **Solapamientos Encontrados**: {count} (Si > 0, documentar resolución)
21
+
22
+ ### Resolución de Solapamientos
23
+ {Si hay solapamientos, cómo se resuelven:
24
+ - Referenciar PRD existente en vez de duplicar
25
+ - Extender funcionalidad existente
26
+ - Coordinar con otro feature}
27
+
28
+ ## Resumen
29
+ {Descripción clara de qué es este feature y por qué es valioso para los usuarios}
30
+
31
+ ## Problema
32
+ {Describe el problema específico que este feature resuelve}
33
+
34
+ ## Usuarios
35
+ {Quién usará esta funcionalidad y cómo les beneficia}
36
+
37
+ ## Alcance
38
+
39
+ ### Incluido
40
+ - {Funcionalidad 1 que SÍ se implementará}
41
+ - {Funcionalidad 2 que SÍ se implementará}
42
+ - {Funcionalidad 3 que SÍ se implementará}
43
+
44
+ ### Excluido (por ahora)
45
+ - {Funcionalidad futura 1}
46
+ - {Funcionalidad futura 2}
47
+
48
+ ## Requisitos
49
+
50
+ ### Funcionales
51
+ - **RF-01**: {Requisito funcional 1}
52
+ - **RF-02**: {Requisito funcional 2}
53
+ - **RF-03**: {Requisito funcional 3}
54
+
55
+ ### No Funcionales
56
+ - **RNF-01 Rendimiento**: {Requisitos de velocidad/capacidad}
57
+ - **RNF-02 Seguridad**: {Requisitos de seguridad}
58
+ - **RNF-03 Usabilidad**: {Requisitos de facilidad de uso}
59
+
60
+ ## Flujo de Usuario
61
+ 1. El usuario {acción 1}
62
+ 2. El sistema {respuesta 1}
63
+ 3. El usuario {acción 2}
64
+ 4. El sistema {respuesta 2}
65
+ 5. Resultado: {estado final}
66
+
67
+ ## Dependencias
68
+
69
+ ### Con Otros Features
70
+ {Lista de features relacionados y cómo interactúan}
71
+ - Feature X: {relación}
72
+ - Feature Y: {relación}
73
+
74
+ ### Técnicas
75
+ - {Librerías o recursos necesarios}
76
+ - {APIs externas}
77
+ - {Modelos existentes a usar}
78
+
79
+ ## Notas
80
+ {Cualquier consideración adicional, riesgos, o decisiones pendientes}