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.
- package/CLAUDE.md +425 -0
- package/_userland/agentes/.gitkeep +0 -0
- package/_userland/habilidades/.gitkeep +0 -0
- package/agentes/accesibilidad-wcag-swl.md +683 -0
- package/agentes/arquitecto-swl.md +210 -0
- package/agentes/auto-evolucion-swl.md +408 -0
- package/agentes/backend-api-swl.md +442 -0
- package/agentes/backend-node-swl.md +439 -0
- package/agentes/backend-python-swl.md +469 -0
- package/agentes/backend-workers-swl.md +444 -0
- package/agentes/cloud-infra-swl.md +466 -0
- package/agentes/consolidador-swl.md +487 -0
- package/agentes/datos-swl.md +568 -0
- package/agentes/depurador-swl.md +301 -0
- package/agentes/devops-ci-swl.md +352 -0
- package/agentes/disenador-ui-swl.md +546 -0
- package/agentes/documentador-swl.md +323 -0
- package/agentes/frontend-angular-swl.md +603 -0
- package/agentes/frontend-css-swl.md +700 -0
- package/agentes/frontend-react-swl.md +672 -0
- package/agentes/frontend-swl.md +483 -0
- package/agentes/frontend-tailwind-swl.md +808 -0
- package/agentes/implementador-swl.md +235 -0
- package/agentes/investigador-swl.md +274 -0
- package/agentes/investigador-ux-swl.md +482 -0
- package/agentes/migrador-swl.md +389 -0
- package/agentes/mobile-android-swl.md +473 -0
- package/agentes/mobile-cross-swl.md +501 -0
- package/agentes/mobile-ios-swl.md +464 -0
- package/agentes/notificador-swl.md +886 -0
- package/agentes/observabilidad-swl.md +408 -0
- package/agentes/orquestador-swl.md +490 -0
- package/agentes/planificador-swl.md +222 -0
- package/agentes/producto-prd-swl.md +565 -0
- package/agentes/release-manager-swl.md +545 -0
- package/agentes/rendimiento-swl.md +691 -0
- package/agentes/revisor-codigo-swl.md +254 -0
- package/agentes/revisor-seguridad-swl.md +316 -0
- package/agentes/tdd-qa-swl.md +323 -0
- package/agentes/ux-disenador-swl.md +498 -0
- package/bin/swl-ses.js +119 -0
- package/comandos/swl/actualizar.md +117 -0
- package/comandos/swl/aprender.md +348 -0
- package/comandos/swl/auditar-deps.md +390 -0
- package/comandos/swl/autoresearch.md +346 -0
- package/comandos/swl/checkpoint.md +296 -0
- package/comandos/swl/compactar.md +283 -0
- package/comandos/swl/crear-skill.md +609 -0
- package/comandos/swl/discutir-fase.md +230 -0
- package/comandos/swl/ejecutar-fase.md +302 -0
- package/comandos/swl/evolucionar.md +377 -0
- package/comandos/swl/instalar.md +220 -0
- package/comandos/swl/mapear-codebase.md +205 -0
- package/comandos/swl/nuevo-proyecto.md +154 -0
- package/comandos/swl/planear-fase.md +221 -0
- package/comandos/swl/release.md +405 -0
- package/comandos/swl/salud.md +382 -0
- package/comandos/swl/verificar.md +292 -0
- package/habilidades/accesibilidad-a11y/SKILL.md +584 -0
- package/habilidades/angular-avanzado/SKILL.md +491 -0
- package/habilidades/angular-moderno/SKILL.md +326 -0
- package/habilidades/api-rest-diseno/SKILL.md +302 -0
- package/habilidades/api-rest-diseno/recursos/openapi-template.yaml +506 -0
- package/habilidades/aprendizaje-continuo/SKILL.md +369 -0
- package/habilidades/async-python/SKILL.md +474 -0
- package/habilidades/auth-patrones/SKILL.md +488 -0
- package/habilidades/auto-evolucion-protocolo/SKILL.md +376 -0
- package/habilidades/autoresearch/SKILL.md +248 -0
- package/habilidades/autoresearch/recursos/checklist-template.md +191 -0
- package/habilidades/autoresearch/scripts/calcular-score.js +88 -0
- package/habilidades/checklist-calidad/SKILL.md +247 -0
- package/habilidades/checklist-calidad/recursos/quality-report-template.md +148 -0
- package/habilidades/checklist-seguridad/SKILL.md +224 -0
- package/habilidades/checkpoints-verificacion/SKILL.md +309 -0
- package/habilidades/checkpoints-verificacion/recursos/checkpoint-templates.md +360 -0
- package/habilidades/ci-cd-pipelines/SKILL.md +583 -0
- package/habilidades/ci-cd-pipelines/recursos/github-actions-template.yaml +403 -0
- package/habilidades/cloud-aws/SKILL.md +497 -0
- package/habilidades/compactacion-contexto/SKILL.md +201 -0
- package/habilidades/contenedores-docker/SKILL.md +453 -0
- package/habilidades/contenedores-docker/recursos/dockerfile-template.dockerfile +160 -0
- package/habilidades/css-moderno/SKILL.md +463 -0
- package/habilidades/datos-etl/SKILL.md +486 -0
- package/habilidades/dependencias-auditoria/SKILL.md +293 -0
- package/habilidades/deprecacion-migracion/SKILL.md +485 -0
- package/habilidades/design-tokens/SKILL.md +519 -0
- package/habilidades/discutir-fase/SKILL.md +167 -0
- package/habilidades/diseno-responsivo/SKILL.md +326 -0
- package/habilidades/django-experto/SKILL.md +395 -0
- package/habilidades/doc-sync/SKILL.md +259 -0
- package/habilidades/ejecutar-fase/SKILL.md +199 -0
- package/habilidades/estructura-proyecto-claude/SKILL.md +459 -0
- package/habilidades/estructura-proyecto-claude/recursos/claude-md-template.md +261 -0
- package/habilidades/estructura-proyecto-claude/recursos/frontmatter-y-hooks-referencia.md +213 -0
- package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +77 -0
- package/habilidades/estructura-proyecto-claude/recursos/variantes-por-stack.md +177 -0
- package/habilidades/event-driven/SKILL.md +580 -0
- package/habilidades/extractor-de-aprendizajes/SKILL.md +234 -0
- package/habilidades/fastapi-experto/SKILL.md +368 -0
- package/habilidades/frontend-avanzado/SKILL.md +555 -0
- package/habilidades/git-worktrees-paralelo/SKILL.md +246 -0
- package/habilidades/iam-secretos/SKILL.md +511 -0
- package/habilidades/instalar-sistema/SKILL.md +140 -0
- package/habilidades/kubernetes-orquestacion/SKILL.md +549 -0
- package/habilidades/manejo-errores/SKILL.md +512 -0
- package/habilidades/mapear-codebase/SKILL.md +199 -0
- package/habilidades/microservicios/SKILL.md +473 -0
- package/habilidades/mobile-flutter/SKILL.md +566 -0
- package/habilidades/mobile-react-native/SKILL.md +493 -0
- package/habilidades/monitoring-alertas/SKILL.md +447 -0
- package/habilidades/node-experto/SKILL.md +521 -0
- package/habilidades/notificaciones-multicanal/SKILL.md +448 -0
- package/habilidades/notificaciones-multicanal/recursos/config-template.json +115 -0
- package/habilidades/nuevo-proyecto/SKILL.md +183 -0
- package/habilidades/patrones-python/SKILL.md +381 -0
- package/habilidades/performance-baseline/SKILL.md +243 -0
- package/habilidades/planear-fase/SKILL.md +184 -0
- package/habilidades/postgresql-experto/SKILL.md +379 -0
- package/habilidades/react-experto/SKILL.md +434 -0
- package/habilidades/react-optimizacion/SKILL.md +328 -0
- package/habilidades/release-semver/SKILL.md +226 -0
- package/habilidades/release-semver/scripts/generar-changelog.sh +238 -0
- package/habilidades/sql-optimizacion/SKILL.md +314 -0
- package/habilidades/tailwind-experto/SKILL.md +412 -0
- package/habilidades/tdd-workflow/SKILL.md +267 -0
- package/habilidades/testing-python/SKILL.md +350 -0
- package/habilidades/threat-model-lite/SKILL.md +218 -0
- package/habilidades/typescript-avanzado/SKILL.md +454 -0
- package/habilidades/ux-diseno/SKILL.md +488 -0
- package/habilidades/validacion-ci-sistema/SKILL.md +543 -0
- package/habilidades/validacion-ci-sistema/scripts/validar-sistema.sh +286 -0
- package/habilidades/verificar-trabajo/SKILL.md +208 -0
- package/habilidades/wireframes-flujos/SKILL.md +396 -0
- package/habilidades/workflow-claude-code/SKILL.md +359 -0
- package/hooks/calidad-pre-commit.js +578 -0
- package/hooks/escaneo-secretos.js +302 -0
- package/hooks/extraccion-aprendizajes.js +550 -0
- package/hooks/linea-estado.js +249 -0
- package/hooks/monitor-contexto.js +230 -0
- package/hooks/proteccion-rutas.js +249 -0
- package/manifiestos/hooks-config.json +41 -0
- package/manifiestos/modulos.json +318 -0
- package/manifiestos/perfiles.json +189 -0
- package/package.json +45 -0
- package/plantillas/PROJECT.md +122 -0
- package/plantillas/REQUIREMENTS.md +132 -0
- package/plantillas/ROADMAP.md +143 -0
- package/plantillas/STATE.md +109 -0
- package/plantillas/research/ARCHITECTURE.md +220 -0
- package/plantillas/research/FEATURES.md +175 -0
- package/plantillas/research/PITFALLS.md +299 -0
- package/plantillas/research/STACK.md +233 -0
- package/plantillas/research/SUMMARY.md +165 -0
- package/plugin.json +144 -0
- package/reglas/accesibilidad.md +269 -0
- package/reglas/api-diseno.md +400 -0
- package/reglas/arquitectura.md +183 -0
- package/reglas/cloud-infra.md +247 -0
- package/reglas/docs.md +245 -0
- package/reglas/estilo-codigo.md +179 -0
- package/reglas/git-workflow.md +186 -0
- package/reglas/performance.md +195 -0
- package/reglas/pruebas.md +159 -0
- package/reglas/seguridad.md +151 -0
- package/reglas/skills-estandar.md +473 -0
- package/scripts/actualizar.js +51 -0
- package/scripts/desinstalar.js +86 -0
- package/scripts/doctor.js +222 -0
- package/scripts/inicializar.js +89 -0
- package/scripts/instalador.js +333 -0
- package/scripts/lib/detectar-runtime.js +177 -0
- package/scripts/lib/estado.js +112 -0
- package/scripts/lib/hooks-settings.js +283 -0
- package/scripts/lib/manifiestos.js +138 -0
- package/scripts/lib/seguridad.js +160 -0
- package/scripts/publicar.js +209 -0
- 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
|