swl-ses 3.3.2

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 (177) hide show
  1. package/CLAUDE.md +425 -0
  2. package/_userland/agentes/.gitkeep +0 -0
  3. package/_userland/habilidades/.gitkeep +0 -0
  4. package/agentes/accesibilidad-wcag-swl.md +683 -0
  5. package/agentes/arquitecto-swl.md +210 -0
  6. package/agentes/auto-evolucion-swl.md +408 -0
  7. package/agentes/backend-api-swl.md +442 -0
  8. package/agentes/backend-node-swl.md +439 -0
  9. package/agentes/backend-python-swl.md +469 -0
  10. package/agentes/backend-workers-swl.md +444 -0
  11. package/agentes/cloud-infra-swl.md +466 -0
  12. package/agentes/consolidador-swl.md +487 -0
  13. package/agentes/datos-swl.md +568 -0
  14. package/agentes/depurador-swl.md +301 -0
  15. package/agentes/devops-ci-swl.md +352 -0
  16. package/agentes/disenador-ui-swl.md +546 -0
  17. package/agentes/documentador-swl.md +323 -0
  18. package/agentes/frontend-angular-swl.md +603 -0
  19. package/agentes/frontend-css-swl.md +700 -0
  20. package/agentes/frontend-react-swl.md +672 -0
  21. package/agentes/frontend-swl.md +483 -0
  22. package/agentes/frontend-tailwind-swl.md +808 -0
  23. package/agentes/implementador-swl.md +235 -0
  24. package/agentes/investigador-swl.md +274 -0
  25. package/agentes/investigador-ux-swl.md +482 -0
  26. package/agentes/migrador-swl.md +389 -0
  27. package/agentes/mobile-android-swl.md +473 -0
  28. package/agentes/mobile-cross-swl.md +501 -0
  29. package/agentes/mobile-ios-swl.md +464 -0
  30. package/agentes/notificador-swl.md +886 -0
  31. package/agentes/observabilidad-swl.md +408 -0
  32. package/agentes/orquestador-swl.md +490 -0
  33. package/agentes/planificador-swl.md +222 -0
  34. package/agentes/producto-prd-swl.md +565 -0
  35. package/agentes/release-manager-swl.md +545 -0
  36. package/agentes/rendimiento-swl.md +691 -0
  37. package/agentes/revisor-codigo-swl.md +254 -0
  38. package/agentes/revisor-seguridad-swl.md +316 -0
  39. package/agentes/tdd-qa-swl.md +323 -0
  40. package/agentes/ux-disenador-swl.md +498 -0
  41. package/bin/swl-ses.js +119 -0
  42. package/comandos/swl/actualizar.md +117 -0
  43. package/comandos/swl/aprender.md +348 -0
  44. package/comandos/swl/auditar-deps.md +390 -0
  45. package/comandos/swl/autoresearch.md +346 -0
  46. package/comandos/swl/checkpoint.md +296 -0
  47. package/comandos/swl/compactar.md +283 -0
  48. package/comandos/swl/crear-skill.md +609 -0
  49. package/comandos/swl/discutir-fase.md +230 -0
  50. package/comandos/swl/ejecutar-fase.md +302 -0
  51. package/comandos/swl/evolucionar.md +377 -0
  52. package/comandos/swl/instalar.md +220 -0
  53. package/comandos/swl/mapear-codebase.md +205 -0
  54. package/comandos/swl/nuevo-proyecto.md +154 -0
  55. package/comandos/swl/planear-fase.md +221 -0
  56. package/comandos/swl/release.md +405 -0
  57. package/comandos/swl/salud.md +382 -0
  58. package/comandos/swl/verificar.md +292 -0
  59. package/habilidades/accesibilidad-a11y/SKILL.md +584 -0
  60. package/habilidades/angular-avanzado/SKILL.md +491 -0
  61. package/habilidades/angular-moderno/SKILL.md +326 -0
  62. package/habilidades/api-rest-diseno/SKILL.md +302 -0
  63. package/habilidades/api-rest-diseno/recursos/openapi-template.yaml +506 -0
  64. package/habilidades/aprendizaje-continuo/SKILL.md +369 -0
  65. package/habilidades/async-python/SKILL.md +474 -0
  66. package/habilidades/auth-patrones/SKILL.md +488 -0
  67. package/habilidades/auto-evolucion-protocolo/SKILL.md +376 -0
  68. package/habilidades/autoresearch/SKILL.md +248 -0
  69. package/habilidades/autoresearch/recursos/checklist-template.md +191 -0
  70. package/habilidades/autoresearch/scripts/calcular-score.js +88 -0
  71. package/habilidades/checklist-calidad/SKILL.md +247 -0
  72. package/habilidades/checklist-calidad/recursos/quality-report-template.md +148 -0
  73. package/habilidades/checklist-seguridad/SKILL.md +224 -0
  74. package/habilidades/checkpoints-verificacion/SKILL.md +309 -0
  75. package/habilidades/checkpoints-verificacion/recursos/checkpoint-templates.md +360 -0
  76. package/habilidades/ci-cd-pipelines/SKILL.md +583 -0
  77. package/habilidades/ci-cd-pipelines/recursos/github-actions-template.yaml +403 -0
  78. package/habilidades/cloud-aws/SKILL.md +497 -0
  79. package/habilidades/compactacion-contexto/SKILL.md +201 -0
  80. package/habilidades/contenedores-docker/SKILL.md +453 -0
  81. package/habilidades/contenedores-docker/recursos/dockerfile-template.dockerfile +160 -0
  82. package/habilidades/css-moderno/SKILL.md +463 -0
  83. package/habilidades/datos-etl/SKILL.md +486 -0
  84. package/habilidades/dependencias-auditoria/SKILL.md +293 -0
  85. package/habilidades/deprecacion-migracion/SKILL.md +485 -0
  86. package/habilidades/design-tokens/SKILL.md +519 -0
  87. package/habilidades/discutir-fase/SKILL.md +167 -0
  88. package/habilidades/diseno-responsivo/SKILL.md +326 -0
  89. package/habilidades/django-experto/SKILL.md +395 -0
  90. package/habilidades/doc-sync/SKILL.md +259 -0
  91. package/habilidades/ejecutar-fase/SKILL.md +199 -0
  92. package/habilidades/estructura-proyecto-claude/SKILL.md +459 -0
  93. package/habilidades/estructura-proyecto-claude/recursos/claude-md-template.md +261 -0
  94. package/habilidades/estructura-proyecto-claude/recursos/frontmatter-y-hooks-referencia.md +213 -0
  95. package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +77 -0
  96. package/habilidades/estructura-proyecto-claude/recursos/variantes-por-stack.md +177 -0
  97. package/habilidades/event-driven/SKILL.md +580 -0
  98. package/habilidades/extractor-de-aprendizajes/SKILL.md +234 -0
  99. package/habilidades/fastapi-experto/SKILL.md +368 -0
  100. package/habilidades/frontend-avanzado/SKILL.md +555 -0
  101. package/habilidades/git-worktrees-paralelo/SKILL.md +246 -0
  102. package/habilidades/iam-secretos/SKILL.md +511 -0
  103. package/habilidades/instalar-sistema/SKILL.md +140 -0
  104. package/habilidades/kubernetes-orquestacion/SKILL.md +549 -0
  105. package/habilidades/manejo-errores/SKILL.md +512 -0
  106. package/habilidades/mapear-codebase/SKILL.md +199 -0
  107. package/habilidades/microservicios/SKILL.md +473 -0
  108. package/habilidades/mobile-flutter/SKILL.md +566 -0
  109. package/habilidades/mobile-react-native/SKILL.md +493 -0
  110. package/habilidades/monitoring-alertas/SKILL.md +447 -0
  111. package/habilidades/node-experto/SKILL.md +521 -0
  112. package/habilidades/notificaciones-multicanal/SKILL.md +448 -0
  113. package/habilidades/notificaciones-multicanal/recursos/config-template.json +115 -0
  114. package/habilidades/nuevo-proyecto/SKILL.md +183 -0
  115. package/habilidades/patrones-python/SKILL.md +381 -0
  116. package/habilidades/performance-baseline/SKILL.md +243 -0
  117. package/habilidades/planear-fase/SKILL.md +184 -0
  118. package/habilidades/postgresql-experto/SKILL.md +379 -0
  119. package/habilidades/react-experto/SKILL.md +434 -0
  120. package/habilidades/react-optimizacion/SKILL.md +328 -0
  121. package/habilidades/release-semver/SKILL.md +226 -0
  122. package/habilidades/release-semver/scripts/generar-changelog.sh +238 -0
  123. package/habilidades/sql-optimizacion/SKILL.md +314 -0
  124. package/habilidades/tailwind-experto/SKILL.md +412 -0
  125. package/habilidades/tdd-workflow/SKILL.md +267 -0
  126. package/habilidades/testing-python/SKILL.md +350 -0
  127. package/habilidades/threat-model-lite/SKILL.md +218 -0
  128. package/habilidades/typescript-avanzado/SKILL.md +454 -0
  129. package/habilidades/ux-diseno/SKILL.md +488 -0
  130. package/habilidades/validacion-ci-sistema/SKILL.md +543 -0
  131. package/habilidades/validacion-ci-sistema/scripts/validar-sistema.sh +286 -0
  132. package/habilidades/verificar-trabajo/SKILL.md +208 -0
  133. package/habilidades/wireframes-flujos/SKILL.md +396 -0
  134. package/habilidades/workflow-claude-code/SKILL.md +359 -0
  135. package/hooks/calidad-pre-commit.js +578 -0
  136. package/hooks/escaneo-secretos.js +302 -0
  137. package/hooks/extraccion-aprendizajes.js +550 -0
  138. package/hooks/linea-estado.js +249 -0
  139. package/hooks/monitor-contexto.js +230 -0
  140. package/hooks/proteccion-rutas.js +249 -0
  141. package/manifiestos/hooks-config.json +41 -0
  142. package/manifiestos/modulos.json +318 -0
  143. package/manifiestos/perfiles.json +189 -0
  144. package/package.json +45 -0
  145. package/plantillas/PROJECT.md +122 -0
  146. package/plantillas/REQUIREMENTS.md +132 -0
  147. package/plantillas/ROADMAP.md +143 -0
  148. package/plantillas/STATE.md +109 -0
  149. package/plantillas/research/ARCHITECTURE.md +220 -0
  150. package/plantillas/research/FEATURES.md +175 -0
  151. package/plantillas/research/PITFALLS.md +299 -0
  152. package/plantillas/research/STACK.md +233 -0
  153. package/plantillas/research/SUMMARY.md +165 -0
  154. package/plugin.json +144 -0
  155. package/reglas/accesibilidad.md +269 -0
  156. package/reglas/api-diseno.md +400 -0
  157. package/reglas/arquitectura.md +183 -0
  158. package/reglas/cloud-infra.md +247 -0
  159. package/reglas/docs.md +245 -0
  160. package/reglas/estilo-codigo.md +179 -0
  161. package/reglas/git-workflow.md +186 -0
  162. package/reglas/performance.md +195 -0
  163. package/reglas/pruebas.md +159 -0
  164. package/reglas/seguridad.md +151 -0
  165. package/reglas/skills-estandar.md +473 -0
  166. package/scripts/actualizar.js +51 -0
  167. package/scripts/desinstalar.js +86 -0
  168. package/scripts/doctor.js +222 -0
  169. package/scripts/inicializar.js +89 -0
  170. package/scripts/instalador.js +333 -0
  171. package/scripts/lib/detectar-runtime.js +177 -0
  172. package/scripts/lib/estado.js +112 -0
  173. package/scripts/lib/hooks-settings.js +283 -0
  174. package/scripts/lib/manifiestos.js +138 -0
  175. package/scripts/lib/seguridad.js +160 -0
  176. package/scripts/publicar.js +209 -0
  177. package/scripts/validar.js +120 -0
@@ -0,0 +1,506 @@
1
+ openapi: "3.1.0"
2
+
3
+ # ─────────────────────────────────────────────────────────────────────────────
4
+ # INSTRUCCIONES DE USO
5
+ # Copiar este archivo a tu proyecto como docs/openapi.yaml
6
+ # Reemplazar todos los valores entre [corchetes] con los reales.
7
+ # Eliminar los comentarios que empiezan con # INSTRUCCIÓN antes de publicar.
8
+ # ─────────────────────────────────────────────────────────────────────────────
9
+
10
+ info:
11
+ title: "[Nombre del API]"
12
+ version: "1.0.0"
13
+ description: |
14
+ [Descripción de 2-3 oraciones: qué hace el API, quién lo consume, qué dominio cubre.]
15
+
16
+ ## Autenticación
17
+ Todos los endpoints (excepto los marcados con `public: true`) requieren
18
+ un token JWT válido en el header `Authorization: Bearer <token>`.
19
+
20
+ ## Versionado
21
+ Esta API sigue SemVer. Los cambios breaking incrementan el segmento MAJOR
22
+ del header `API-Version`.
23
+ contact:
24
+ name: "[Equipo responsable]"
25
+ email: "[email@empresa.com]"
26
+ license:
27
+ name: "Proprietary"
28
+
29
+ servers:
30
+ - url: "https://api.[tu-dominio.com]/v1"
31
+ description: "Producción"
32
+ - url: "https://api-staging.[tu-dominio.com]/v1"
33
+ description: "Staging"
34
+ - url: "http://localhost:8000/v1"
35
+ description: "Desarrollo local"
36
+
37
+ # ─── Seguridad global ──────────────────────────────────────────────────────────
38
+ security:
39
+ - BearerAuth: []
40
+
41
+ components:
42
+ securitySchemes:
43
+ BearerAuth:
44
+ type: http
45
+ scheme: bearer
46
+ bearerFormat: JWT
47
+ description: |
48
+ JWT obtenido del endpoint `POST /auth/login`.
49
+ Expira en 24 horas. Renovar con `POST /auth/refresh`.
50
+
51
+ # ─── Schemas reutilizables ──────────────────────────────────────────────────
52
+ schemas:
53
+
54
+ # Paginación estándar
55
+ PaginatedResponse:
56
+ type: object
57
+ required: [items, total, page, page_size, pages]
58
+ properties:
59
+ items:
60
+ type: array
61
+ description: "Lista de recursos de la página actual"
62
+ total:
63
+ type: integer
64
+ minimum: 0
65
+ description: "Total de registros en todas las páginas"
66
+ example: 247
67
+ page:
68
+ type: integer
69
+ minimum: 1
70
+ description: "Número de página actual (base 1)"
71
+ example: 1
72
+ page_size:
73
+ type: integer
74
+ minimum: 1
75
+ maximum: 100
76
+ description: "Registros por página"
77
+ example: 20
78
+ pages:
79
+ type: integer
80
+ minimum: 0
81
+ description: "Total de páginas disponibles"
82
+ example: 13
83
+
84
+ # Error estándar
85
+ ErrorResponse:
86
+ type: object
87
+ required: [error, message]
88
+ properties:
89
+ error:
90
+ type: string
91
+ description: "Código de error en snake_case"
92
+ example: "recurso_no_encontrado"
93
+ message:
94
+ type: string
95
+ description: "Descripción legible del error"
96
+ example: "El recurso con id '550e8400' no fue encontrado"
97
+ details:
98
+ type: object
99
+ description: "Información adicional de diagnóstico (opcional)"
100
+ additionalProperties: true
101
+ request_id:
102
+ type: string
103
+ format: uuid
104
+ description: "ID único de la request para trazabilidad en logs"
105
+
106
+ # Error de validación (422)
107
+ ValidationErrorResponse:
108
+ type: object
109
+ required: [error, message, fields]
110
+ properties:
111
+ error:
112
+ type: string
113
+ example: "error_de_validacion"
114
+ message:
115
+ type: string
116
+ example: "La request contiene campos inválidos"
117
+ fields:
118
+ type: array
119
+ items:
120
+ type: object
121
+ required: [field, message]
122
+ properties:
123
+ field:
124
+ type: string
125
+ description: "Nombre del campo con error (usa dot notation para anidados)"
126
+ example: "usuario.email"
127
+ message:
128
+ type: string
129
+ description: "Descripción del error de validación"
130
+ example: "Debe ser un email válido"
131
+
132
+ # UUID reutilizable
133
+ UUID:
134
+ type: string
135
+ format: uuid
136
+ example: "550e8400-e29b-41d4-a716-446655440000"
137
+
138
+ # Timestamp ISO 8601
139
+ Timestamp:
140
+ type: string
141
+ format: date-time
142
+ example: "2026-03-25T14:32:00Z"
143
+
144
+ # ─── [Recurso principal] ─────────────────────────────────────────────────
145
+ # INSTRUCCIÓN: Reemplazar [Recurso] con el nombre real (ej: Factura, Usuario)
146
+
147
+ RecursoBase:
148
+ type: object
149
+ required: [id, created_at, updated_at]
150
+ properties:
151
+ id:
152
+ $ref: "#/components/schemas/UUID"
153
+ created_at:
154
+ $ref: "#/components/schemas/Timestamp"
155
+ updated_at:
156
+ $ref: "#/components/schemas/Timestamp"
157
+ created_by:
158
+ type: string
159
+ format: email
160
+ description: "Email del usuario que creó el registro"
161
+
162
+ RecursoCreate:
163
+ type: object
164
+ required: [] # INSTRUCCIÓN: listar campos obligatorios
165
+ properties:
166
+ nombre:
167
+ type: string
168
+ minLength: 1
169
+ maxLength: 255
170
+ description: "[Descripción del campo]"
171
+ example: "[Ejemplo]"
172
+ # INSTRUCCIÓN: agregar más campos según el dominio
173
+
174
+ RecursoUpdate:
175
+ type: object
176
+ description: "Todos los campos son opcionales (PATCH semántico)"
177
+ properties:
178
+ nombre:
179
+ type: string
180
+ minLength: 1
181
+ maxLength: 255
182
+
183
+ RecursoRead:
184
+ allOf:
185
+ - $ref: "#/components/schemas/RecursoBase"
186
+ - $ref: "#/components/schemas/RecursoCreate"
187
+
188
+ # ─── Parámetros reutilizables ────────────────────────────────────────────────
189
+ parameters:
190
+
191
+ PathId:
192
+ name: id
193
+ in: path
194
+ required: true
195
+ schema:
196
+ $ref: "#/components/schemas/UUID"
197
+ description: "Identificador único del recurso"
198
+
199
+ QueryPage:
200
+ name: page
201
+ in: query
202
+ schema:
203
+ type: integer
204
+ minimum: 1
205
+ default: 1
206
+ description: "Número de página (base 1)"
207
+
208
+ QueryPageSize:
209
+ name: page_size
210
+ in: query
211
+ schema:
212
+ type: integer
213
+ minimum: 1
214
+ maximum: 100
215
+ default: 20
216
+ description: "Registros por página (máximo 100)"
217
+
218
+ QuerySearch:
219
+ name: q
220
+ in: query
221
+ schema:
222
+ type: string
223
+ minLength: 2
224
+ description: "Texto de búsqueda libre (busca en campos indexados)"
225
+
226
+ QueryOrderBy:
227
+ name: order_by
228
+ in: query
229
+ schema:
230
+ type: string
231
+ description: |
232
+ Campo de ordenamiento. Prefijo `-` para orden descendente.
233
+ Ejemplos: `created_at`, `-created_at`, `nombre`
234
+
235
+ # ─── Respuestas reutilizables ────────────────────────────────────────────────
236
+ responses:
237
+
238
+ "400BadRequest":
239
+ description: "Request inválida"
240
+ content:
241
+ application/json:
242
+ schema:
243
+ $ref: "#/components/schemas/ErrorResponse"
244
+
245
+ "401Unauthorized":
246
+ description: "Token JWT ausente, inválido o expirado"
247
+ content:
248
+ application/json:
249
+ schema:
250
+ $ref: "#/components/schemas/ErrorResponse"
251
+ example:
252
+ error: "token_invalido"
253
+ message: "El token JWT es inválido o ha expirado"
254
+
255
+ "403Forbidden":
256
+ description: "El usuario no tiene permiso para esta operación"
257
+ content:
258
+ application/json:
259
+ schema:
260
+ $ref: "#/components/schemas/ErrorResponse"
261
+ example:
262
+ error: "permiso_denegado"
263
+ message: "No tienes permiso para realizar esta acción"
264
+
265
+ "404NotFound":
266
+ description: "El recurso no existe"
267
+ content:
268
+ application/json:
269
+ schema:
270
+ $ref: "#/components/schemas/ErrorResponse"
271
+
272
+ "422Unprocessable":
273
+ description: "Error de validación en el cuerpo de la request"
274
+ content:
275
+ application/json:
276
+ schema:
277
+ $ref: "#/components/schemas/ValidationErrorResponse"
278
+
279
+ "500InternalError":
280
+ description: "Error interno del servidor"
281
+ content:
282
+ application/json:
283
+ schema:
284
+ $ref: "#/components/schemas/ErrorResponse"
285
+ example:
286
+ error: "error_interno"
287
+ message: "Ocurrió un error inesperado. Por favor contacta soporte con el request_id."
288
+
289
+ # ─── Paths ────────────────────────────────────────────────────────────────────
290
+ paths:
291
+
292
+ # INSTRUCCIÓN: Reemplazar /recursos con la ruta real del recurso en plural
293
+ # Mantener rutas ESTÁTICAS antes de las PARAMÉTRICAS
294
+
295
+ /recursos:
296
+ get:
297
+ operationId: "listar_recursos"
298
+ summary: "Listar recursos"
299
+ tags: ["[Nombre del recurso]"]
300
+ parameters:
301
+ - $ref: "#/components/parameters/QueryPage"
302
+ - $ref: "#/components/parameters/QueryPageSize"
303
+ - $ref: "#/components/parameters/QuerySearch"
304
+ - $ref: "#/components/parameters/QueryOrderBy"
305
+ # INSTRUCCIÓN: agregar filtros específicos del dominio
306
+ - name: estatus
307
+ in: query
308
+ schema:
309
+ type: string
310
+ enum: ["activo", "inactivo", "borrador"]
311
+ description: "Filtrar por estatus"
312
+ responses:
313
+ "200":
314
+ description: "Lista paginada de recursos"
315
+ content:
316
+ application/json:
317
+ schema:
318
+ allOf:
319
+ - $ref: "#/components/schemas/PaginatedResponse"
320
+ - type: object
321
+ properties:
322
+ items:
323
+ type: array
324
+ items:
325
+ $ref: "#/components/schemas/RecursoRead"
326
+ "401":
327
+ $ref: "#/components/responses/401Unauthorized"
328
+ "500":
329
+ $ref: "#/components/responses/500InternalError"
330
+
331
+ post:
332
+ operationId: "crear_recurso"
333
+ summary: "Crear un nuevo recurso"
334
+ tags: ["[Nombre del recurso]"]
335
+ requestBody:
336
+ required: true
337
+ content:
338
+ application/json:
339
+ schema:
340
+ $ref: "#/components/schemas/RecursoCreate"
341
+ responses:
342
+ "201":
343
+ description: "Recurso creado exitosamente"
344
+ content:
345
+ application/json:
346
+ schema:
347
+ $ref: "#/components/schemas/RecursoRead"
348
+ headers:
349
+ Location:
350
+ description: "URL del recurso creado"
351
+ schema:
352
+ type: string
353
+ format: uri
354
+ "401":
355
+ $ref: "#/components/responses/401Unauthorized"
356
+ "403":
357
+ $ref: "#/components/responses/403Forbidden"
358
+ "422":
359
+ $ref: "#/components/responses/422Unprocessable"
360
+ "500":
361
+ $ref: "#/components/responses/500InternalError"
362
+
363
+ /recursos/{id}:
364
+ parameters:
365
+ - $ref: "#/components/parameters/PathId"
366
+
367
+ get:
368
+ operationId: "obtener_recurso"
369
+ summary: "Obtener un recurso por ID"
370
+ tags: ["[Nombre del recurso]"]
371
+ responses:
372
+ "200":
373
+ description: "Recurso encontrado"
374
+ content:
375
+ application/json:
376
+ schema:
377
+ $ref: "#/components/schemas/RecursoRead"
378
+ "401":
379
+ $ref: "#/components/responses/401Unauthorized"
380
+ "404":
381
+ $ref: "#/components/responses/404NotFound"
382
+
383
+ patch:
384
+ operationId: "actualizar_recurso"
385
+ summary: "Actualizar parcialmente un recurso"
386
+ tags: ["[Nombre del recurso]"]
387
+ requestBody:
388
+ required: true
389
+ content:
390
+ application/json:
391
+ schema:
392
+ $ref: "#/components/schemas/RecursoUpdate"
393
+ responses:
394
+ "200":
395
+ description: "Recurso actualizado"
396
+ content:
397
+ application/json:
398
+ schema:
399
+ $ref: "#/components/schemas/RecursoRead"
400
+ "401":
401
+ $ref: "#/components/responses/401Unauthorized"
402
+ "403":
403
+ $ref: "#/components/responses/403Forbidden"
404
+ "404":
405
+ $ref: "#/components/responses/404NotFound"
406
+ "422":
407
+ $ref: "#/components/responses/422Unprocessable"
408
+
409
+ delete:
410
+ operationId: "eliminar_recurso"
411
+ summary: "Eliminar un recurso"
412
+ tags: ["[Nombre del recurso]"]
413
+ responses:
414
+ "204":
415
+ description: "Recurso eliminado — sin cuerpo de respuesta"
416
+ "401":
417
+ $ref: "#/components/responses/401Unauthorized"
418
+ "403":
419
+ $ref: "#/components/responses/403Forbidden"
420
+ "404":
421
+ $ref: "#/components/responses/404NotFound"
422
+
423
+ # ─── Autenticación (incluida como referencia) ──────────────────────────────
424
+ /auth/login:
425
+ post:
426
+ operationId: "login"
427
+ summary: "Iniciar sesión y obtener tokens JWT"
428
+ tags: ["Autenticación"]
429
+ security: [] # Endpoint público — no requiere token
430
+ requestBody:
431
+ required: true
432
+ content:
433
+ application/json:
434
+ schema:
435
+ type: object
436
+ required: [email, password]
437
+ properties:
438
+ email:
439
+ type: string
440
+ format: email
441
+ password:
442
+ type: string
443
+ format: password
444
+ minLength: 8
445
+ responses:
446
+ "200":
447
+ description: "Login exitoso"
448
+ content:
449
+ application/json:
450
+ schema:
451
+ type: object
452
+ required: [access_token, refresh_token, expires_in]
453
+ properties:
454
+ access_token:
455
+ type: string
456
+ description: "JWT de acceso. Incluir en header Authorization: Bearer <token>"
457
+ refresh_token:
458
+ type: string
459
+ description: "Token para renovar el access_token vía /auth/refresh"
460
+ expires_in:
461
+ type: integer
462
+ description: "Segundos hasta que expira el access_token"
463
+ example: 86400
464
+ "401":
465
+ description: "Credenciales inválidas"
466
+ content:
467
+ application/json:
468
+ schema:
469
+ $ref: "#/components/schemas/ErrorResponse"
470
+
471
+ /auth/refresh:
472
+ post:
473
+ operationId: "refresh_token"
474
+ summary: "Renovar access token usando refresh token"
475
+ tags: ["Autenticación"]
476
+ security: []
477
+ requestBody:
478
+ required: true
479
+ content:
480
+ application/json:
481
+ schema:
482
+ type: object
483
+ required: [refresh_token]
484
+ properties:
485
+ refresh_token:
486
+ type: string
487
+ responses:
488
+ "200":
489
+ description: "Token renovado"
490
+ content:
491
+ application/json:
492
+ schema:
493
+ type: object
494
+ properties:
495
+ access_token:
496
+ type: string
497
+ expires_in:
498
+ type: integer
499
+
500
+ # ─── Tags (para agrupar endpoints en la UI) ───────────────────────────────────
501
+ tags:
502
+ - name: "Autenticación"
503
+ description: "Endpoints para login y renovación de tokens"
504
+ - name: "[Nombre del recurso]"
505
+ description: "[Descripción del grupo de endpoints]"
506
+ # INSTRUCCIÓN: agregar más tags según los dominios del API