@saulwade/swl-ses 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.
- package/CLAUDE.md +238 -0
- package/README.md +560 -0
- package/_userland/agentes/.gitkeep +0 -0
- package/_userland/habilidades/.gitkeep +0 -0
- package/agentes/.evolved.json +9 -0
- package/agentes/accesibilidad-wcag-swl.md +692 -0
- package/agentes/arquitecto-swl.md +238 -0
- package/agentes/auto-evolucion-swl.md +854 -0
- package/agentes/backend-api-swl.md +470 -0
- package/agentes/backend-csharp-swl.md +418 -0
- package/agentes/backend-go-swl.md +388 -0
- package/agentes/backend-java-swl.md +279 -0
- package/agentes/backend-node-swl.md +477 -0
- package/agentes/backend-python-swl.md +608 -0
- package/agentes/backend-rust-swl.md +362 -0
- package/agentes/backend-workers-swl.md +480 -0
- package/agentes/cloud-infra-swl.md +485 -0
- package/agentes/consolidador-swl.md +539 -0
- package/agentes/datos-swl.md +584 -0
- package/agentes/depurador-swl.md +349 -0
- package/agentes/devops-ci-swl.md +374 -0
- package/agentes/disenador-ui-swl.md +558 -0
- package/agentes/documentador-swl.md +343 -0
- package/agentes/evals/arquitecto-swl.evals.json +56 -0
- package/agentes/evals/auto-evolucion-swl.evals.json +68 -0
- package/agentes/evals/implementador-swl.evals.json +56 -0
- package/agentes/evals/orquestador-swl.evals.json +60 -0
- package/agentes/evals/perfilador-usuario-swl.evals.json +60 -0
- package/agentes/evals/red-team-swl.evals.json +59 -0
- package/agentes/evals/revisor-codigo-swl.evals.json +59 -0
- package/agentes/frontend-angular-swl.md +627 -0
- package/agentes/frontend-css-swl.md +720 -0
- package/agentes/frontend-react-swl.md +696 -0
- package/agentes/frontend-swl.md +500 -0
- package/agentes/frontend-tailwind-swl.md +830 -0
- package/agentes/implementador-swl.md +328 -0
- package/agentes/investigador-swl.md +430 -0
- package/agentes/investigador-ux-swl.md +500 -0
- package/agentes/llm-apps-swl.md +276 -0
- package/agentes/migrador-swl.md +417 -0
- package/agentes/mobile-android-swl.md +509 -0
- package/agentes/mobile-cross-swl.md +539 -0
- package/agentes/mobile-ios-swl.md +500 -0
- package/agentes/mobile-testing-swl.md +300 -0
- package/agentes/notificador-swl.md +916 -0
- package/agentes/observabilidad-swl.md +436 -0
- package/agentes/orquestador-swl.md +884 -0
- package/agentes/pagos-swl.md +283 -0
- package/agentes/perfilador-usuario-swl.md +306 -0
- package/agentes/planificador-swl.md +402 -0
- package/agentes/producto-prd-swl.md +587 -0
- package/agentes/red-team-swl.md +216 -0
- package/agentes/release-manager-swl.md +568 -0
- package/agentes/rendimiento-swl.md +714 -0
- package/agentes/resolutor-build-swl.md +243 -0
- package/agentes/revisor-angular-swl.md +276 -0
- package/agentes/revisor-codigo-swl.md +348 -0
- package/agentes/revisor-csharp-swl.md +262 -0
- package/agentes/revisor-go-swl.md +257 -0
- package/agentes/revisor-java-swl.md +255 -0
- package/agentes/revisor-kotlin-swl.md +271 -0
- package/agentes/revisor-nextjs-swl.md +279 -0
- package/agentes/revisor-php-swl.md +269 -0
- package/agentes/revisor-react-swl.md +276 -0
- package/agentes/revisor-rust-swl.md +344 -0
- package/agentes/revisor-seguridad-swl.md +390 -0
- package/agentes/revisor-swift-swl.md +266 -0
- package/agentes/revisor-typescript-swl.md +344 -0
- package/agentes/sre-swl.md +265 -0
- package/agentes/tdd-qa-swl.md +354 -0
- package/agentes/ux-disenador-swl.md +501 -0
- package/bin/lib/bot-comandos.js +1030 -0
- package/bin/lib/bot-discovery.js +182 -0
- package/bin/lib/bot-git.js +142 -0
- package/bin/swl-ses.js +325 -0
- package/bin/swl-telegram-bot.js +442 -0
- package/bin/swl-telegram-bot.plist +21 -0
- package/bin/swl-telegram-bot.service +14 -0
- package/comandos/swl/.evolved.json +23 -0
- package/comandos/swl/actualizar.md +174 -0
- package/comandos/swl/adoptar-proyecto.md +207 -0
- package/comandos/swl/aprender.md +701 -0
- package/comandos/swl/auditar-deps.md +134 -0
- package/comandos/swl/autoresearch.md +170 -0
- package/comandos/swl/ayuda.md +224 -0
- package/comandos/swl/brainstorm.md +50 -0
- package/comandos/swl/checkpoint.md +330 -0
- package/comandos/swl/compactar.md +283 -0
- package/comandos/swl/configurar-ci.md +227 -0
- package/comandos/swl/contexto.md +112 -0
- package/comandos/swl/contribuir.md +233 -0
- package/comandos/swl/crear-skill.md +292 -0
- package/comandos/swl/cron.md +196 -0
- package/comandos/swl/dashboard.md +146 -0
- package/comandos/swl/discutir-fase.md +230 -0
- package/comandos/swl/ejecutar-fase.md +135 -0
- package/comandos/swl/evaluar-skill.md +487 -0
- package/comandos/swl/evolucion-estado.md +142 -0
- package/comandos/swl/evolucionar.md +259 -0
- package/comandos/swl/exportar-vault.md +189 -0
- package/comandos/swl/gateway.md +158 -0
- package/comandos/swl/inbox.md +116 -0
- package/comandos/swl/instalar.md +220 -0
- package/comandos/swl/instintos.md +86 -0
- package/comandos/swl/mapear-codebase.md +312 -0
- package/comandos/swl/mcp-status.md +175 -0
- package/comandos/swl/metricas.md +270 -0
- package/comandos/swl/modelo.md +102 -0
- package/comandos/swl/notificaciones.md +396 -0
- package/comandos/swl/nuevo-proyecto.md +154 -0
- package/comandos/swl/planear-fase.md +221 -0
- package/comandos/swl/plugins.md +256 -0
- package/comandos/swl/reflect-skills.md +125 -0
- package/comandos/swl/release.md +217 -0
- package/comandos/swl/revisar-impacto.md +206 -0
- package/comandos/swl/revisar.md +330 -0
- package/comandos/swl/salud.md +363 -0
- package/comandos/swl/sesiones.md +200 -0
- package/comandos/swl/skill-search.md +113 -0
- package/comandos/swl/verificar.md +585 -0
- package/comandos/swl/wiki.md +620 -0
- package/contextos/dev.md +32 -0
- package/contextos/research.md +30 -0
- package/contextos/review.md +31 -0
- package/habilidades/accesibilidad-a11y/SKILL.md +201 -0
- package/habilidades/accesibilidad-a11y/evals/evals.json +56 -0
- package/habilidades/accesibilidad-a11y/recursos/ejemplos-y-checklist-completo.md +441 -0
- package/habilidades/agent-browser/SKILL.md +218 -0
- package/habilidades/agentes-como-servicio/SKILL.md +218 -0
- package/habilidades/ai-runtime-security/SKILL.md +273 -0
- package/habilidades/angular-avanzado/SKILL.md +164 -0
- package/habilidades/angular-avanzado/recursos/ejemplos-avanzados.md +219 -0
- package/habilidades/angular-moderno/SKILL.md +186 -0
- package/habilidades/angular-moderno/evals/evals.json +45 -0
- package/habilidades/angular-moderno/recursos/ejemplos-avanzados.md +106 -0
- package/habilidades/api-rest-diseno/SKILL.md +191 -0
- package/habilidades/api-rest-diseno/recursos/openapi-template.yaml +506 -0
- package/habilidades/api-rest-diseno/recursos/referencia-api.md +140 -0
- package/habilidades/aprendizaje-continuo/SKILL.md +151 -0
- package/habilidades/aprendizaje-continuo/evals/evals.json +53 -0
- package/habilidades/aprendizaje-continuo/recursos/referencia-instintos.md +290 -0
- package/habilidades/async-python/SKILL.md +149 -0
- package/habilidades/async-python/evals/evals.json +47 -0
- package/habilidades/async-python/recursos/patrones-y-ejemplos-completos.md +292 -0
- package/habilidades/auth-patrones/.evolved.json +9 -0
- package/habilidades/auth-patrones/SKILL.md +413 -0
- package/habilidades/auth-patrones/recursos/implementaciones-completas.md +229 -0
- package/habilidades/auto-evolucion-protocolo/SKILL.md +276 -0
- package/habilidades/auto-evolucion-protocolo/evals/evals.json +55 -0
- package/habilidades/auto-evolucion-protocolo/recursos/referencia-completa.md +145 -0
- package/habilidades/autoresearch/SKILL.md +268 -0
- package/habilidades/autoresearch/evals/evals.json +41 -0
- package/habilidades/autoresearch/recursos/checklist-template.md +191 -0
- package/habilidades/autoresearch/scripts/calcular-score.js +88 -0
- package/habilidades/azure-cloud/SKILL.md +308 -0
- package/habilidades/azure-cloud/recursos/aks.md +327 -0
- package/habilidades/backend-mcp-servidor/SKILL.md +270 -0
- package/habilidades/backend-production-resilience/SKILL.md +288 -0
- package/habilidades/brainstorming/SKILL.md +295 -0
- package/habilidades/brainstorming/recursos/componentes-html.md +247 -0
- package/habilidades/build-errors-cpp/SKILL.md +270 -0
- package/habilidades/build-errors-csharp/SKILL.md +265 -0
- package/habilidades/build-errors-go/SKILL.md +306 -0
- package/habilidades/build-errors-java/SKILL.md +278 -0
- package/habilidades/build-errors-kotlin/SKILL.md +303 -0
- package/habilidades/build-errors-nextjs/SKILL.md +312 -0
- package/habilidades/build-errors-php/SKILL.md +270 -0
- package/habilidades/build-errors-python/SKILL.md +292 -0
- package/habilidades/build-errors-rust/SKILL.md +284 -0
- package/habilidades/build-errors-swift/SKILL.md +272 -0
- package/habilidades/build-errors-typescript/SKILL.md +369 -0
- package/habilidades/checklist-calidad/SKILL.md +271 -0
- package/habilidades/checklist-calidad/recursos/quality-report-template.md +148 -0
- package/habilidades/checklist-seguridad/SKILL.md +285 -0
- package/habilidades/checkpoints-verificacion/SKILL.md +298 -0
- package/habilidades/checkpoints-verificacion/recursos/checkpoint-templates.md +360 -0
- package/habilidades/ci-cd-pipelines/SKILL.md +157 -0
- package/habilidades/ci-cd-pipelines/recursos/github-actions-template.yaml +403 -0
- package/habilidades/ci-cd-pipelines/recursos/pipelines-completos.md +487 -0
- package/habilidades/cloud-aws/SKILL.md +142 -0
- package/habilidades/cloud-aws/recursos/servicios-aws-referencia.md +321 -0
- package/habilidades/compactacion-contexto/SKILL.md +247 -0
- package/habilidades/contenedores-docker/SKILL.md +137 -0
- package/habilidades/contenedores-docker/recursos/dockerfile-template.dockerfile +160 -0
- package/habilidades/contenedores-docker/recursos/ejemplos-y-configuraciones.md +327 -0
- package/habilidades/context-builder/SKILL.md +170 -0
- package/habilidades/control-profundidad/SKILL.md +128 -0
- package/habilidades/csharp-experto/SKILL.md +322 -0
- package/habilidades/csharp-patrones/SKILL.md +316 -0
- package/habilidades/csharp-testing/SKILL.md +286 -0
- package/habilidades/css-moderno/SKILL.md +166 -0
- package/habilidades/css-moderno/evals/evals.json +43 -0
- package/habilidades/css-moderno/recursos/ejemplos-y-patrones-completos.md +337 -0
- package/habilidades/datos-etl/SKILL.md +129 -0
- package/habilidades/datos-etl/recursos/implementaciones-completas.md +322 -0
- package/habilidades/dbml-experto/SKILL.md +339 -0
- package/habilidades/dbml-experto/evals/evals.json +56 -0
- package/habilidades/dependencias-auditoria/SKILL.md +320 -0
- package/habilidades/deprecacion-migracion/SKILL.md +169 -0
- package/habilidades/deprecacion-migracion/recursos/implementaciones-completas.md +220 -0
- package/habilidades/design-tokens/SKILL.md +158 -0
- package/habilidades/design-tokens/recursos/tokens-y-configuracion.md +363 -0
- package/habilidades/devsecops-pipeline-security/SKILL.md +309 -0
- package/habilidades/diagrama-arquitectura/SKILL.md +165 -0
- package/habilidades/diagrama-arquitectura/assets/template.html +276 -0
- package/habilidades/discutir-fase/SKILL.md +188 -0
- package/habilidades/diseno-herramientas-agente/SKILL.md +199 -0
- package/habilidades/diseno-responsivo/SKILL.md +186 -0
- package/habilidades/diseno-responsivo/recursos/ejemplos-layouts.md +156 -0
- package/habilidades/django-experto/SKILL.md +205 -0
- package/habilidades/django-experto/recursos/async-django.md +390 -0
- package/habilidades/django-experto/recursos/drf-patrones.md +438 -0
- package/habilidades/django-experto/recursos/orm-avanzado.md +382 -0
- package/habilidades/django-experto/recursos/referencia-completa.md +188 -0
- package/habilidades/django-experto/recursos/testing-django.md +415 -0
- package/habilidades/doc-sync/SKILL.md +280 -0
- package/habilidades/drift-detection/SKILL.md +179 -0
- package/habilidades/ejecutar-fase/SKILL.md +468 -0
- package/habilidades/estilo-sin-ai-isms/SKILL.md +775 -0
- package/habilidades/estilo-sin-ai-isms/evals/evals.json +63 -0
- package/habilidades/estilo-sin-ai-isms/scripts/detectar_aiisms.py +500 -0
- package/habilidades/estructura-proyecto-claude/SKILL.md +215 -0
- package/habilidades/estructura-proyecto-claude/recursos/claude-md-template.md +261 -0
- package/habilidades/estructura-proyecto-claude/recursos/configuracion-y-extensiones.md +176 -0
- package/habilidades/estructura-proyecto-claude/recursos/frontmatter-y-hooks-referencia.md +289 -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/evaluacion-agentes/SKILL.md +314 -0
- package/habilidades/event-driven/SKILL.md +153 -0
- package/habilidades/event-driven/recursos/implementaciones-completas.md +423 -0
- package/habilidades/extraccion-documentos/SKILL.md +221 -0
- package/habilidades/extractor-de-aprendizajes/.evolved.json +9 -0
- package/habilidades/extractor-de-aprendizajes/SKILL.md +311 -0
- package/habilidades/extractor-de-aprendizajes/evals/evals.json +55 -0
- package/habilidades/fastapi-experto/SKILL.md +221 -0
- package/habilidades/fastapi-experto/recursos/async-patterns.md +438 -0
- package/habilidades/fastapi-experto/recursos/dependency-injection.md +330 -0
- package/habilidades/fastapi-experto/recursos/referencia-completa.md +79 -0
- package/habilidades/fastapi-experto/recursos/testing-httpx.md +420 -0
- package/habilidades/filament-admin/SKILL.md +290 -0
- package/habilidades/frontend-avanzado/SKILL.md +257 -0
- package/habilidades/frontend-avanzado/recursos/apis-nativas-ejemplos.md +341 -0
- package/habilidades/gcp-cloud/SKILL.md +260 -0
- package/habilidades/gcp-cloud/recursos/gke.md +234 -0
- package/habilidades/gcp-cloud/recursos/terraform-gcp.md +307 -0
- package/habilidades/generacion-mermaid/SKILL.md +229 -0
- package/habilidades/git-worktrees-paralelo/SKILL.md +270 -0
- package/habilidades/go-experto/SKILL.md +305 -0
- package/habilidades/go-patrones/SKILL.md +299 -0
- package/habilidades/go-testing/SKILL.md +291 -0
- package/habilidades/graphql-experto/SKILL.md +323 -0
- package/habilidades/guardrail-semantico/SKILL.md +282 -0
- package/habilidades/harness-claude-code/SKILL.md +299 -0
- package/habilidades/iam-secretos/SKILL.md +265 -0
- package/habilidades/iam-secretos/recursos/implementaciones-completas.md +356 -0
- package/habilidades/infra-github-actions/SKILL.md +166 -0
- package/habilidades/instalar-sistema/.evolved.json +9 -0
- package/habilidades/instalar-sistema/SKILL.md +221 -0
- package/habilidades/java-experto/SKILL.md +290 -0
- package/habilidades/java-patrones/SKILL.md +275 -0
- package/habilidades/java-testing/SKILL.md +288 -0
- package/habilidades/kotlin-compose/SKILL.md +278 -0
- package/habilidades/kotlin-compose/recursos/animaciones-performance.md +93 -0
- package/habilidades/kotlin-experto/SKILL.md +318 -0
- package/habilidades/kotlin-testing/SKILL.md +267 -0
- package/habilidades/kotlin-testing/recursos/testing-avanzado.md +74 -0
- package/habilidades/kubernetes-orquestacion/SKILL.md +152 -0
- package/habilidades/kubernetes-orquestacion/recursos/manifiestos-completos.md +452 -0
- package/habilidades/langchain-langraph/SKILL.md +386 -0
- package/habilidades/langchain-langraph/recursos/evaluacion-rag.md +321 -0
- package/habilidades/langchain-langraph/recursos/rag-maturity-model.md +225 -0
- package/habilidades/langchain-langraph/recursos/vectorstores.md +306 -0
- package/habilidades/legacy-code-rescue/SKILL.md +267 -0
- package/habilidades/likec4-experto/SKILL.md +412 -0
- package/habilidades/likec4-experto/evals/evals.json +69 -0
- package/habilidades/manejo-errores/.evolved.json +9 -0
- package/habilidades/manejo-errores/SKILL.md +407 -0
- package/habilidades/manejo-errores/recursos/implementaciones-completas.md +248 -0
- package/habilidades/mapear-codebase/SKILL.md +275 -0
- package/habilidades/memoria-busqueda/SKILL.md +194 -0
- package/habilidades/memoria-busqueda/evals/evals.json +44 -0
- package/habilidades/meta-skills-estandar/SKILL.md +298 -0
- package/habilidades/meta-skills-estandar/recursos/anti-patrones-y-leyes.md +205 -0
- package/habilidades/meta-skills-estandar/recursos/frameworks-seguridad.md +107 -0
- package/habilidades/meta-skills-estandar/recursos/idiomas-framework.md +60 -0
- package/habilidades/meta-skills-estandar/recursos/skills-as-agents.md +163 -0
- package/habilidades/microservicios/SKILL.md +155 -0
- package/habilidades/microservicios/recursos/patrones-y-ejemplos-completos.md +325 -0
- package/habilidades/mobile-flutter/SKILL.md +199 -0
- package/habilidades/mobile-flutter/recursos/ejemplos-completos.md +319 -0
- package/habilidades/mobile-react-native/SKILL.md +176 -0
- package/habilidades/mobile-react-native/recursos/ejemplos-completos.md +216 -0
- package/habilidades/mongodb-experto/SKILL.md +302 -0
- package/habilidades/monitoring-alertas/SKILL.md +201 -0
- package/habilidades/monitoring-alertas/recursos/instrumentacion-y-alertas.md +301 -0
- package/habilidades/nestjs-experto/SKILL.md +307 -0
- package/habilidades/nestjs-experto/recursos/guards-interceptors.md +339 -0
- package/habilidades/nestjs-experto/recursos/modulos-di.md +287 -0
- package/habilidades/nestjs-experto/recursos/testing-nestjs.md +354 -0
- package/habilidades/nextjs-experto/SKILL.md +335 -0
- package/habilidades/nextjs-patrones/SKILL.md +303 -0
- package/habilidades/nextjs-testing/SKILL.md +331 -0
- package/habilidades/node-experto/.evolved.json +9 -0
- package/habilidades/node-experto/SKILL.md +266 -0
- package/habilidades/node-experto/recursos/patrones-completos.md +283 -0
- package/habilidades/notificaciones-multicanal/SKILL.md +159 -0
- package/habilidades/notificaciones-multicanal/recursos/config-template.json +115 -0
- package/habilidades/notificaciones-multicanal/recursos/configuracion-y-templates.md +303 -0
- package/habilidades/nuevo-proyecto/SKILL.md +204 -0
- package/habilidades/orquestacion-async/SKILL.md +303 -0
- package/habilidades/paid-media-tracking/SKILL.md +269 -0
- package/habilidades/paid-media-tracking/recursos/auditoria-tracking.md +220 -0
- package/habilidades/paid-media-tracking/recursos/google-ads-api.md +215 -0
- package/habilidades/patrones-python/SKILL.md +228 -0
- package/habilidades/patrones-python/evals/evals.json +56 -0
- package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -0
- package/habilidades/patrones-python/recursos/referencia-completa.md +202 -0
- package/habilidades/perfil-usuario/SKILL.md +200 -0
- package/habilidades/perfil-usuario/evals/evals.json +55 -0
- package/habilidades/performance-baseline/SKILL.md +297 -0
- package/habilidades/php-experto/SKILL.md +291 -0
- package/habilidades/php-patrones/SKILL.md +306 -0
- package/habilidades/php-testing/SKILL.md +280 -0
- package/habilidades/planear-fase/SKILL.md +269 -0
- package/habilidades/postgresql-experto/SKILL.md +151 -0
- package/habilidades/postgresql-experto/evals/evals.json +53 -0
- package/habilidades/postgresql-experto/recursos/referencia-completa.md +215 -0
- package/habilidades/prevencion-racionalizacion/SKILL.md +175 -0
- package/habilidades/prevencion-sobreingenieria/SKILL.md +323 -0
- package/habilidades/privacy-memoria/SKILL.md +141 -0
- package/habilidades/privacy-memoria/evals/evals.json +43 -0
- package/habilidades/prompt-engineering/SKILL.md +518 -0
- package/habilidades/prompt-engineering/recursos/patrones-avanzados.md +467 -0
- package/habilidades/rag-arquitectura/SKILL.md +338 -0
- package/habilidades/rails-experto/SKILL.md +237 -0
- package/habilidades/rails-experto/recursos/active-record.md +260 -0
- package/habilidades/rails-experto/recursos/hotwire-turbo.md +293 -0
- package/habilidades/rails-experto/recursos/testing-rspec.md +362 -0
- package/habilidades/react-experto/SKILL.md +209 -0
- package/habilidades/react-experto/evals/evals.json +55 -0
- package/habilidades/react-experto/recursos/patrones-y-ejemplos-completos.md +240 -0
- package/habilidades/react-optimizacion/SKILL.md +174 -0
- package/habilidades/react-optimizacion/recursos/patrones-avanzados.md +138 -0
- package/habilidades/redis-experto/SKILL.md +305 -0
- package/habilidades/release-semver/.evolved.json +9 -0
- package/habilidades/release-semver/SKILL.md +248 -0
- package/habilidades/release-semver/scripts/generar-changelog.sh +238 -0
- package/habilidades/rust-experto/SKILL.md +400 -0
- package/habilidades/rust-patrones/SKILL.md +296 -0
- package/habilidades/rust-testing/SKILL.md +311 -0
- package/habilidades/seguridad-skills-ia/SKILL.md +262 -0
- package/habilidades/sql-optimizacion/SKILL.md +200 -0
- package/habilidades/sql-optimizacion/evals/evals.json +54 -0
- package/habilidades/sql-optimizacion/recursos/patrones-sql-avanzados.md +131 -0
- package/habilidades/sre-patrones/SKILL.md +333 -0
- package/habilidades/sre-patrones/recursos/chaos-engineering.md +241 -0
- package/habilidades/sre-patrones/recursos/oncall-design.md +236 -0
- package/habilidades/stripe-pagos/SKILL.md +550 -0
- package/habilidades/stripe-pagos/recursos/errores-reintentos.md +390 -0
- package/habilidades/stripe-pagos/recursos/stripe-connect.md +290 -0
- package/habilidades/structured-outputs/SKILL.md +343 -0
- package/habilidades/swift-experto/SKILL.md +320 -0
- package/habilidades/swift-experto/recursos/keychain-y-wrappers.md +110 -0
- package/habilidades/swift-patrones/SKILL.md +313 -0
- package/habilidades/swift-patrones/recursos/tca-ejemplo-completo.md +113 -0
- package/habilidades/swift-testing/SKILL.md +254 -0
- package/habilidades/swift-testing/recursos/xcuitest-planes.md +143 -0
- package/habilidades/swl-dashboard/SKILL.md +370 -0
- package/habilidades/swl-markitdown/SKILL.md +285 -0
- package/habilidades/swl-markitdown/evals/evals.json +52 -0
- package/habilidades/swl-revisar-impacto/SKILL.md +233 -0
- package/habilidades/tailwind-experto/SKILL.md +240 -0
- package/habilidades/tailwind-experto/recursos/referencia-completa.md +184 -0
- package/habilidades/tdd-workflow/SKILL.md +293 -0
- package/habilidades/terraform-experto/SKILL.md +321 -0
- package/habilidades/testing-python/SKILL.md +340 -0
- package/habilidades/testing-python/recursos/ejemplos-completos.md +167 -0
- package/habilidades/threat-model-lite/SKILL.md +246 -0
- package/habilidades/tracing-processor/SKILL.md +212 -0
- package/habilidades/tracking-measurement/SKILL.md +239 -0
- package/habilidades/tracking-measurement/recursos/consent-mode.md +231 -0
- package/habilidades/tracking-measurement/recursos/gtm-datalayer.md +216 -0
- package/habilidades/tracking-measurement/recursos/meta-capi.md +262 -0
- package/habilidades/typescript-avanzado/SKILL.md +144 -0
- package/habilidades/typescript-avanzado/evals/evals.json +55 -0
- package/habilidades/typescript-avanzado/recursos/patrones-y-ejemplos-completos.md +298 -0
- package/habilidades/typescript-diagnosticos/SKILL.md +513 -0
- package/habilidades/ux-diseno/SKILL.md +116 -0
- package/habilidades/ux-diseno/evals/evals.json +43 -0
- package/habilidades/ux-diseno/recursos/patrones-ux-referencia.md +214 -0
- package/habilidades/validacion-ci-sistema/SKILL.md +136 -0
- package/habilidades/validacion-ci-sistema/recursos/validadores-completos.md +369 -0
- package/habilidades/validacion-ci-sistema/scripts/validar-sistema.sh +286 -0
- package/habilidades/verificacion-evidencia/SKILL.md +160 -0
- package/habilidades/verificar-trabajo/SKILL.md +303 -0
- package/habilidades/verificar-trabajo/recursos/plantilla-verificacion.md +60 -0
- package/habilidades/wiki-conocimiento/SKILL.md +276 -0
- package/habilidades/wireframes-flujos/SKILL.md +212 -0
- package/habilidades/wireframes-flujos/recursos/referencia-completa.md +192 -0
- package/habilidades/workflow-claude-code/SKILL.md +260 -0
- package/habilidades/workflow-claude-code/recursos/referencia-completa.md +109 -0
- package/hooks/_run-hook.sh +57 -0
- package/hooks/actualizar-perfil-usuario.js +364 -0
- package/hooks/agente-lifecycle.js +71 -0
- package/hooks/aiisms-detector.js +173 -0
- package/hooks/audit-trail.js +204 -0
- package/hooks/auto-background.js +97 -0
- package/hooks/auto-consolidacion.js +178 -0
- package/hooks/auto-evolucion.js +666 -0
- package/hooks/auto-restaurar-settings.js +360 -0
- package/hooks/calidad-pre-commit.js +929 -0
- package/hooks/calidad-typescript.js +511 -0
- package/hooks/captura-feedback-usuario.js +148 -0
- package/hooks/check-update.js +211 -0
- package/hooks/clasificador-mensajes.js +271 -0
- package/hooks/degradacion-instintos.js +272 -0
- package/hooks/escaneo-secretos.js +389 -0
- package/hooks/extraccion-aprendizajes.js +763 -0
- package/hooks/grafo-contexto.js +129 -0
- package/hooks/graph-update.js +67 -0
- package/hooks/guardrail-modelo.js +247 -0
- package/hooks/inbox-aviso.js +75 -0
- package/hooks/inyeccion-contexto.js +246 -0
- package/hooks/lib/abort-registry.js +214 -0
- package/hooks/lib/agent-backend.js +210 -0
- package/hooks/lib/agent-comms.js +263 -0
- package/hooks/lib/agent-issue-codes.js +284 -0
- package/hooks/lib/agent-matcher.js +189 -0
- package/hooks/lib/async-hook-registry.js +252 -0
- package/hooks/lib/atomic-write.js +130 -0
- package/hooks/lib/auto-consolidator.js +335 -0
- package/hooks/lib/canary-skills.js +187 -0
- package/hooks/lib/consolidation-lock.js +291 -0
- package/hooks/lib/context-builder.js +430 -0
- package/hooks/lib/context-compressor.js +657 -0
- package/hooks/lib/convergence-detector.js +105 -0
- package/hooks/lib/delegation-tracker.js +198 -0
- package/hooks/lib/detectar-package-manager.js +423 -0
- package/hooks/lib/edit-accumulator.js +171 -0
- package/hooks/lib/error-classifier.js +308 -0
- package/hooks/lib/event-bus.js +112 -0
- package/hooks/lib/evolution-tracker.js +442 -0
- package/hooks/lib/execution-state.js +316 -0
- package/hooks/lib/fingerprint-id.js +135 -0
- package/hooks/lib/gateway-notify.js +116 -0
- package/hooks/lib/graph-security.js +75 -0
- package/hooks/lib/guardrail-metrics.js +202 -0
- package/hooks/lib/hook-circuit-breaker.js +206 -0
- package/hooks/lib/loop-detector.js +267 -0
- package/hooks/lib/mcp-health.js +184 -0
- package/hooks/lib/mcp-pool.js +436 -0
- package/hooks/lib/memory-search.js +506 -0
- package/hooks/lib/merkle-audit.js +96 -0
- package/hooks/lib/model-router.js +222 -0
- package/hooks/lib/normalize-error.js +324 -0
- package/hooks/lib/normalize-input.js +65 -0
- package/hooks/lib/nudge-tracker.js +306 -0
- package/hooks/lib/otlp-exporter.js +365 -0
- package/hooks/lib/performance-marks.js +239 -0
- package/hooks/lib/privacy-filter.js +128 -0
- package/hooks/lib/prompt-injection-scanner.js +209 -0
- package/hooks/lib/provenance-tracker.js +183 -0
- package/hooks/lib/rate-limit-tracker.js +253 -0
- package/hooks/lib/reflect-classifier.js +164 -0
- package/hooks/lib/resource-quota.js +122 -0
- package/hooks/lib/retry-jitter.js +165 -0
- package/hooks/lib/risk-engine.js +368 -0
- package/hooks/lib/run-log.js +408 -0
- package/hooks/lib/session-fts.js +379 -0
- package/hooks/lib/session-store.js +293 -0
- package/hooks/lib/singleton-guard.js +159 -0
- package/hooks/lib/skill-auditor.js +588 -0
- package/hooks/lib/sync-status.js +228 -0
- package/hooks/lib/taint-tracker.js +107 -0
- package/hooks/lib/task-service.js +295 -0
- package/hooks/lib/tech-skills-map.js +146 -0
- package/hooks/lib/telegram-cliente.js +159 -0
- package/hooks/lib/telegram-config.js +170 -0
- package/hooks/lib/token-budget.js +156 -0
- package/hooks/lib/token-estimator.js +420 -0
- package/hooks/lib/toon-compressor.js +245 -0
- package/hooks/lib/usage-model.js +183 -0
- package/hooks/lib/variable-resolver.js +230 -0
- package/hooks/linea-estado.js +324 -0
- package/hooks/metricas-evolucion.js +209 -0
- package/hooks/monitor-contexto.js +325 -0
- package/hooks/notificacion-sesion-stop.js +198 -0
- package/hooks/notificacion-telegram-notification.js +4 -0
- package/hooks/notificacion-telegram-subagent.js +4 -0
- package/hooks/notificacion-telegram.js +267 -0
- package/hooks/preservar-estado-pre-compact.js +150 -0
- package/hooks/proteccion-rutas.js +366 -0
- package/hooks/registro-turnos.js +209 -0
- package/hooks/resumen-sesion.js +249 -0
- package/hooks/risk-scoring.js +323 -0
- package/hooks/rotar-audit-auto.js +122 -0
- package/hooks/sugerir-regenerar-inventario.js +170 -0
- package/hooks/telemetria-agentes.js +167 -0
- package/hooks/tracking-costos.js +688 -0
- package/instintos/global.yaml +8 -0
- package/instintos/perfil-usuario.yaml +53 -0
- package/instintos/prompt-appendices.yaml +57 -0
- package/instintos/proyecto.yaml +372 -0
- package/manifiestos/gateway-config.json +77 -0
- package/manifiestos/handoff-context.json +223 -0
- package/manifiestos/hook-profiles.json +44 -0
- package/manifiestos/hooks-config.json +360 -0
- package/manifiestos/modulos.json +1173 -0
- package/manifiestos/perfiles.json +404 -0
- package/package.json +86 -0
- package/plantillas/ESTADO.md +109 -0
- package/plantillas/HOJA-RUTA.md +143 -0
- package/plantillas/PROYECTO.md +122 -0
- package/plantillas/REQUISITOS.md +132 -0
- package/plantillas/auditor-veto-template.md +105 -0
- package/plantillas/github-workflows/README.md +47 -0
- package/plantillas/github-workflows/release-please.yml +44 -0
- package/plantillas/github-workflows/swl-ci.yml +107 -0
- package/plantillas/github-workflows/swl-security.yml +51 -0
- package/plantillas/mcp-mineru.json +13 -0
- package/plantillas/research/ARQUITECTURA.md +220 -0
- package/plantillas/research/FUNCIONALIDADES.md +175 -0
- package/plantillas/research/RESUMEN.md +165 -0
- package/plantillas/research/STACK.md +233 -0
- package/plantillas/research/TRAMPAS.md +299 -0
- package/plantillas/skill-evals-template.json +44 -0
- package/plugin.json +343 -0
- package/reglas/accesibilidad.md +269 -0
- package/reglas/api-diseno.md +400 -0
- package/reglas/arquitectura.md +352 -0
- package/reglas/brevedad-output.md +124 -0
- package/reglas/cloud-infra.md +247 -0
- package/reglas/docs.md +245 -0
- package/reglas/estilo-codigo.md +201 -0
- package/reglas/git-workflow.md +245 -0
- package/reglas/gobernanza.md +271 -0
- package/reglas/harness-claude-code.md +213 -0
- package/reglas/hooks.md +186 -0
- package/reglas/lenguajes/csharp/estilo-codigo.md +231 -0
- package/reglas/lenguajes/csharp/hooks.md +281 -0
- package/reglas/lenguajes/csharp/patrones.md +226 -0
- package/reglas/lenguajes/csharp/seguridad.md +258 -0
- package/reglas/lenguajes/csharp/testing.md +176 -0
- package/reglas/lenguajes/go/estilo-codigo.md +195 -0
- package/reglas/lenguajes/go/hooks.md +249 -0
- package/reglas/lenguajes/go/patrones.md +249 -0
- package/reglas/lenguajes/go/seguridad.md +225 -0
- package/reglas/lenguajes/go/testing.md +272 -0
- package/reglas/lenguajes/java/estilo-codigo.md +217 -0
- package/reglas/lenguajes/java/hooks.md +251 -0
- package/reglas/lenguajes/java/patrones.md +226 -0
- package/reglas/lenguajes/java/seguridad.md +233 -0
- package/reglas/lenguajes/java/testing.md +238 -0
- package/reglas/lenguajes/kotlin/estilo-codigo.md +208 -0
- package/reglas/lenguajes/kotlin/hooks.md +245 -0
- package/reglas/lenguajes/kotlin/patrones.md +201 -0
- package/reglas/lenguajes/kotlin/seguridad.md +202 -0
- package/reglas/lenguajes/kotlin/testing.md +236 -0
- package/reglas/lenguajes/nextjs/estilo-codigo.md +175 -0
- package/reglas/lenguajes/nextjs/hooks.md +186 -0
- package/reglas/lenguajes/nextjs/patrones.md +225 -0
- package/reglas/lenguajes/nextjs/seguridad.md +216 -0
- package/reglas/lenguajes/nextjs/testing.md +193 -0
- package/reglas/lenguajes/php/estilo-codigo.md +228 -0
- package/reglas/lenguajes/php/hooks.md +165 -0
- package/reglas/lenguajes/php/patrones.md +233 -0
- package/reglas/lenguajes/php/seguridad.md +186 -0
- package/reglas/lenguajes/php/testing.md +205 -0
- package/reglas/lenguajes/rust/estilo-codigo.md +207 -0
- package/reglas/lenguajes/rust/hooks.md +240 -0
- package/reglas/lenguajes/rust/patrones.md +250 -0
- package/reglas/lenguajes/rust/seguridad.md +221 -0
- package/reglas/lenguajes/rust/testing.md +194 -0
- package/reglas/lenguajes/swift/estilo-codigo.md +238 -0
- package/reglas/lenguajes/swift/hooks.md +257 -0
- package/reglas/lenguajes/swift/patrones.md +235 -0
- package/reglas/lenguajes/swift/seguridad.md +248 -0
- package/reglas/lenguajes/swift/testing.md +242 -0
- package/reglas/markitdown.md +60 -0
- package/reglas/memoria-consolidada.md +209 -0
- package/reglas/patrones.md +225 -0
- package/reglas/performance.md +195 -0
- package/reglas/pruebas.md +159 -0
- package/reglas/seguridad-agentes.md +351 -0
- package/reglas/seguridad.md +151 -0
- package/reglas/skills-estandar.md +373 -0
- package/reglas/testing.md +193 -0
- package/schemas/agent-contract.json +176 -0
- package/schemas/agent-frontmatter.schema.json +149 -0
- package/schemas/agent-message.schema.json +53 -0
- package/schemas/agent-output-implementacion.schema.json +85 -0
- package/schemas/agent-output-planificacion.schema.json +113 -0
- package/schemas/agent-output-review.schema.json +78 -0
- package/schemas/diary-entry.schema.json +80 -0
- package/schemas/hook-profiles.schema.json +39 -0
- package/schemas/hooks-config.schema.json +74 -0
- package/schemas/instinct.schema.json +115 -0
- package/schemas/modulos.schema.json +29 -0
- package/schemas/perfiles.schema.json +28 -0
- package/schemas/plugin.schema.json +64 -0
- package/schemas/skill-evals.schema.json +95 -0
- package/schemas/skill-frontmatter.schema.json +170 -0
- package/scripts/actualizar.js +145 -0
- package/scripts/audit-skills.sh +78 -0
- package/scripts/auditar-agentes-gaps.js +149 -0
- package/scripts/auditar-cobertura-frameworks.js +241 -0
- package/scripts/auditar-skills-gaps.js +206 -0
- package/scripts/bootstrap-instintos.js +259 -0
- package/scripts/check-update.js +109 -0
- package/scripts/comandos/agents.js +105 -0
- package/scripts/comandos/info.js +108 -0
- package/scripts/comandos/install-asistido.js +186 -0
- package/scripts/comandos/skills.js +211 -0
- package/scripts/configurar-branch-protection.js +418 -0
- package/scripts/daemon-swl.py +388 -0
- package/scripts/desinstalar.js +130 -0
- package/scripts/doctor.js +559 -0
- package/scripts/field-report.js +199 -0
- package/scripts/generar-inventario.js +317 -0
- package/scripts/inbox-tmux-inject.js +161 -0
- package/scripts/inferir-herramientas-permitidas.js +586 -0
- package/scripts/inicializar.js +133 -0
- package/scripts/instalador.js +1031 -0
- package/scripts/instalar-git-hook.js +122 -0
- package/scripts/lib/agp-frontmatter.js +222 -0
- package/scripts/lib/append-con-marcadores.js +199 -0
- package/scripts/lib/artefactos-python.js +43 -0
- package/scripts/lib/audit-query.js +221 -0
- package/scripts/lib/autostart-linux.js +347 -0
- package/scripts/lib/autostart-macos.js +360 -0
- package/scripts/lib/autostart-windows.js +307 -0
- package/scripts/lib/budget-enforcer.js +252 -0
- package/scripts/lib/claude-sessions.js +285 -0
- package/scripts/lib/configurar-ci.js +380 -0
- package/scripts/lib/console-span-exporter.js +92 -0
- package/scripts/lib/contadores-inventario.js +217 -0
- package/scripts/lib/dashboard-widgets.js +290 -0
- package/scripts/lib/detectar-runtime.js +279 -0
- package/scripts/lib/detectar-stack.js +187 -0
- package/scripts/lib/diary-entry.js +234 -0
- package/scripts/lib/drift-detector.js +545 -0
- package/scripts/lib/estado.js +124 -0
- package/scripts/lib/gestor-componentes.js +243 -0
- package/scripts/lib/gitignore-manifest.js +305 -0
- package/scripts/lib/graph-analyze.py +556 -0
- package/scripts/lib/graph-builder.py +485 -0
- package/scripts/lib/graph-cluster.py +259 -0
- package/scripts/lib/health-row.js +168 -0
- package/scripts/lib/hooks-settings.js +789 -0
- package/scripts/lib/manifiestos.js +138 -0
- package/scripts/lib/mc-client.js +137 -0
- package/scripts/lib/notificaciones-telegram.js +1107 -0
- package/scripts/lib/npm-version.js +261 -0
- package/scripts/lib/paquetes-conocidos.js +50 -0
- package/scripts/lib/preservar-usuario.js +586 -0
- package/scripts/lib/prompt-builder.js +264 -0
- package/scripts/lib/resolver-externo.js +332 -0
- package/scripts/lib/schedule-parser.js +305 -0
- package/scripts/lib/scoring-instintos.js +240 -0
- package/scripts/lib/seguridad.js +160 -0
- package/scripts/lib/selector-interactivo.js +152 -0
- package/scripts/lib/semantic-search.js +242 -0
- package/scripts/lib/skill-discovery.js +234 -0
- package/scripts/lib/skill-metrics.js +246 -0
- package/scripts/lib/skill-normalizer.js +112 -0
- package/scripts/lib/skills-hub.js +340 -0
- package/scripts/lib/span-schema.js +134 -0
- package/scripts/lib/tool-cost-analyzer.js +255 -0
- package/scripts/lib/tracing-processor-interface.js +286 -0
- package/scripts/lib/transformadores/base.js +80 -0
- package/scripts/lib/transformadores/claude.js +124 -0
- package/scripts/lib/transformadores/codex.js +115 -0
- package/scripts/lib/transformadores/copilot.js +106 -0
- package/scripts/lib/transformadores/gemini.js +74 -0
- package/scripts/lib/transformadores/index.js +35 -0
- package/scripts/lib/transformadores/opencode.js +75 -0
- package/scripts/lib/ui.js +259 -0
- package/scripts/limpiar-artefactos-python.js +131 -0
- package/scripts/mcp-orchestrator.py +386 -0
- package/scripts/mcp-pool-manager.py +352 -0
- package/scripts/mcp-telemetry.py +378 -0
- package/scripts/poblar-evolvable.js +226 -0
- package/scripts/publicar.js +287 -0
- package/scripts/reflect-skills.js +403 -0
- package/scripts/rotar-audit-logs.js +185 -0
- package/scripts/run-skill-evals.js +242 -0
- package/scripts/smoke-test.js +374 -0
- package/scripts/token-analysis.py +471 -0
- package/scripts/validar-manifest.js +195 -0
- package/scripts/validar-memoria.js +321 -0
- package/scripts/validar-tests-aislamiento.js +184 -0
- package/scripts/validar-tokens-test.js +208 -0
- package/scripts/validar.js +147 -0
- package/scripts/validate-markdown.py +339 -0
- package/scripts/validate-skills.py +385 -0
- package/scripts/vendor/claude-usage/README.md +116 -0
- package/scripts/vendor/claude-usage/cli.py +334 -0
- package/scripts/vendor/claude-usage/dashboard.py +795 -0
- package/scripts/vendor/claude-usage/scanner.py +467 -0
- package/scripts/vendor/markitdown/cli.py +194 -0
- package/scripts/verificar-evolucion.js +289 -0
- package/scripts/verificar-release.js +494 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
# Dependency Injection Avanzado — FastAPI
|
|
2
|
+
|
|
3
|
+
## Depends() con clases: parámetros de consulta reutilizables
|
|
4
|
+
|
|
5
|
+
Usar clases como dependencias evita repetir parámetros de paginación y filtrado en
|
|
6
|
+
cada endpoint. FastAPI instancia la clase automáticamente.
|
|
7
|
+
|
|
8
|
+
```python
|
|
9
|
+
# app/dependencies/paginacion.py
|
|
10
|
+
from fastapi import Depends, Query
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class Paginacion:
|
|
15
|
+
"""Dependencia reutilizable para paginación estándar."""
|
|
16
|
+
pagina: int = Query(default=1, ge=1, description="Número de página")
|
|
17
|
+
tamano: int = Query(default=20, ge=1, le=100, description="Elementos por página")
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def offset(self) -> int:
|
|
21
|
+
return (self.pagina - 1) * self.tamano
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def limit(self) -> int:
|
|
25
|
+
return self.tamano
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class FiltrosFactura:
|
|
30
|
+
"""Parámetros de filtrado específicos para facturas."""
|
|
31
|
+
estatus: str | None = Query(default=None, description="Filtrar por estatus")
|
|
32
|
+
cliente_id: str | None = Query(default=None, description="Filtrar por cliente")
|
|
33
|
+
fecha_desde: date | None = Query(default=None)
|
|
34
|
+
fecha_hasta: date | None = Query(default=None)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# Uso en endpoint — FastAPI inyecta la clase completa
|
|
38
|
+
@router.get("/facturas", response_model=PaginatedResponse[FacturaRead])
|
|
39
|
+
async def listar_facturas(
|
|
40
|
+
paginacion: Paginacion = Depends(),
|
|
41
|
+
filtros: FiltrosFactura = Depends(),
|
|
42
|
+
db: AsyncSession = Depends(get_db),
|
|
43
|
+
) -> PaginatedResponse[FacturaRead]:
|
|
44
|
+
query = select(Factura).offset(paginacion.offset).limit(paginacion.limit)
|
|
45
|
+
if filtros.estatus:
|
|
46
|
+
query = query.where(Factura.estatus == filtros.estatus)
|
|
47
|
+
...
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Patrón Annotated moderno (recomendado desde FastAPI 0.95)
|
|
53
|
+
|
|
54
|
+
`Annotated` centraliza la definición de la dependencia y elimina repetición.
|
|
55
|
+
El tipo queda documentado y el IDE lo infiere correctamente.
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
# app/dependencies/tipos.py
|
|
59
|
+
from typing import Annotated
|
|
60
|
+
from fastapi import Depends
|
|
61
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
62
|
+
from app.dependencies.database import get_db
|
|
63
|
+
from app.dependencies.auth import get_current_user, require_role
|
|
64
|
+
from app.models import Usuario
|
|
65
|
+
|
|
66
|
+
# Tipos anotados — definir una sola vez, usar en toda la app
|
|
67
|
+
DbDep = Annotated[AsyncSession, Depends(get_db)]
|
|
68
|
+
UsuarioActualDep = Annotated[Usuario, Depends(get_current_user)]
|
|
69
|
+
AdminDep = Annotated[Usuario, Depends(require_role(["admin", "superadmin"]))]
|
|
70
|
+
PaginacionDep = Annotated[Paginacion, Depends()]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# Uso en endpoints — limpio, sin repetir Depends()
|
|
74
|
+
@router.get("/facturas", response_model=list[FacturaRead])
|
|
75
|
+
async def listar_facturas(
|
|
76
|
+
db: DbDep,
|
|
77
|
+
usuario: UsuarioActualDep,
|
|
78
|
+
paginacion: PaginacionDep,
|
|
79
|
+
) -> list[FacturaRead]:
|
|
80
|
+
...
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@router.delete("/facturas/{factura_id}", status_code=204)
|
|
84
|
+
async def eliminar_factura(
|
|
85
|
+
factura_id: str,
|
|
86
|
+
db: DbDep,
|
|
87
|
+
admin: AdminDep, # Solo admins — validación automática
|
|
88
|
+
) -> None:
|
|
89
|
+
...
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Depends() anidados: dependencias que dependen de otras
|
|
95
|
+
|
|
96
|
+
FastAPI resuelve el grafo de dependencias automáticamente y reutiliza instancias
|
|
97
|
+
dentro de la misma request cuando se comparte la misma función de dependencia.
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
# app/dependencies/auth.py
|
|
101
|
+
from fastapi import Depends, HTTPException
|
|
102
|
+
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
|
103
|
+
|
|
104
|
+
bearer = HTTPBearer()
|
|
105
|
+
|
|
106
|
+
async def get_current_user(
|
|
107
|
+
credentials: HTTPAuthorizationCredentials = Depends(bearer),
|
|
108
|
+
db: AsyncSession = Depends(get_db), # Anidado — FastAPI comparte la sesión
|
|
109
|
+
) -> Usuario:
|
|
110
|
+
payload = decode_jwt(credentials.credentials)
|
|
111
|
+
if not payload:
|
|
112
|
+
raise HTTPException(status_code=401, detail="Token inválido o expirado")
|
|
113
|
+
usuario = await db.get(Usuario, payload["sub"])
|
|
114
|
+
if not usuario or not usuario.activo:
|
|
115
|
+
raise HTTPException(status_code=401, detail="Usuario inactivo")
|
|
116
|
+
return usuario
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def require_role(*roles: str):
|
|
120
|
+
"""Fábrica de dependencias — genera un Depends con roles específicos."""
|
|
121
|
+
async def verificar(
|
|
122
|
+
usuario: Usuario = Depends(get_current_user), # Anidado en la fábrica
|
|
123
|
+
) -> Usuario:
|
|
124
|
+
if usuario.rol not in roles:
|
|
125
|
+
raise HTTPException(
|
|
126
|
+
status_code=403,
|
|
127
|
+
detail=f"Se requiere uno de estos roles: {list(roles)}",
|
|
128
|
+
)
|
|
129
|
+
return usuario
|
|
130
|
+
return verificar
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def require_empresa_activa():
|
|
134
|
+
"""Verifica que la empresa del usuario esté activa — depende de get_current_user."""
|
|
135
|
+
async def verificar(
|
|
136
|
+
usuario: Usuario = Depends(get_current_user),
|
|
137
|
+
db: AsyncSession = Depends(get_db), # FastAPI reutiliza la MISMA sesión
|
|
138
|
+
) -> Usuario:
|
|
139
|
+
empresa = await db.get(Empresa, usuario.empresa_id)
|
|
140
|
+
if not empresa or empresa.suspendida:
|
|
141
|
+
raise HTTPException(status_code=403, detail="Empresa suspendida")
|
|
142
|
+
return usuario
|
|
143
|
+
return verificar
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Dependencias con yield para recursos externos
|
|
149
|
+
|
|
150
|
+
`yield` permite inicializar y limpiar recursos (sesiones DB, clientes HTTP, locks).
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
# app/dependencies/database.py
|
|
154
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
155
|
+
from app.db.session import AsyncSessionLocal
|
|
156
|
+
|
|
157
|
+
async def get_db() -> AsyncGenerator[AsyncSession, None]:
|
|
158
|
+
"""Sesión de base de datos con rollback automático en error."""
|
|
159
|
+
async with AsyncSessionLocal() as session:
|
|
160
|
+
try:
|
|
161
|
+
yield session
|
|
162
|
+
# El commit lo hace el endpoint DESPUÉS de que el service termine
|
|
163
|
+
await session.commit()
|
|
164
|
+
except Exception:
|
|
165
|
+
await session.rollback()
|
|
166
|
+
raise
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
# app/dependencies/http_client.py
|
|
170
|
+
import httpx
|
|
171
|
+
|
|
172
|
+
async def get_http_client() -> AsyncGenerator[httpx.AsyncClient, None]:
|
|
173
|
+
"""Cliente HTTP reutilizable — evita abrir conexiones por request."""
|
|
174
|
+
async with httpx.AsyncClient(timeout=10.0) as client:
|
|
175
|
+
yield client
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
HttpClientDep = Annotated[httpx.AsyncClient, Depends(get_http_client)]
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Security Schemes
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
# app/core/security.py
|
|
187
|
+
from fastapi.security import OAuth2PasswordBearer, HTTPBearer, APIKeyHeader
|
|
188
|
+
from jose import jwt, JWTError
|
|
189
|
+
from passlib.context import CryptContext
|
|
190
|
+
|
|
191
|
+
# Esquema OAuth2 — expone /token en la documentación Swagger
|
|
192
|
+
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
|
|
193
|
+
|
|
194
|
+
# Bearer directo — para APIs que emiten sus propios tokens JWT
|
|
195
|
+
bearer_scheme = HTTPBearer(auto_error=True)
|
|
196
|
+
|
|
197
|
+
# API Key en header — para integraciones M2M
|
|
198
|
+
api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False)
|
|
199
|
+
|
|
200
|
+
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def crear_token(sub: str, rol: str, expire_minutes: int = 30) -> str:
|
|
204
|
+
expire = datetime.utcnow() + timedelta(minutes=expire_minutes)
|
|
205
|
+
return jwt.encode(
|
|
206
|
+
{"sub": sub, "rol": rol, "exp": expire},
|
|
207
|
+
settings.SECRET_KEY,
|
|
208
|
+
algorithm="HS256",
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def decode_jwt(token: str) -> dict | None:
|
|
213
|
+
try:
|
|
214
|
+
return jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
|
|
215
|
+
except JWTError:
|
|
216
|
+
return None
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
# Dependencia combinada: JWT o API Key — cualquiera es válido
|
|
220
|
+
async def get_current_user_or_apikey(
|
|
221
|
+
bearer: HTTPAuthorizationCredentials | None = Depends(bearer_scheme),
|
|
222
|
+
api_key: str | None = Depends(api_key_header),
|
|
223
|
+
db: AsyncSession = Depends(get_db),
|
|
224
|
+
) -> Usuario:
|
|
225
|
+
if bearer:
|
|
226
|
+
payload = decode_jwt(bearer.credentials)
|
|
227
|
+
if payload:
|
|
228
|
+
return await _usuario_por_id(db, payload["sub"])
|
|
229
|
+
if api_key:
|
|
230
|
+
usuario = await _usuario_por_api_key(db, api_key)
|
|
231
|
+
if usuario:
|
|
232
|
+
return usuario
|
|
233
|
+
raise HTTPException(status_code=401, detail="Credenciales inválidas")
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Middleware vs Dependencies — cuándo usar cada uno
|
|
239
|
+
|
|
240
|
+
| Criterio | Middleware | Dependency |
|
|
241
|
+
|----------|-----------|------------|
|
|
242
|
+
| Acceso a la request ANTES de rutear | Sí | No |
|
|
243
|
+
| Acceso al response DESPUÉS de ejecutar | Sí | No (solo con yield) |
|
|
244
|
+
| Acceso a path params / query params | No | Sí |
|
|
245
|
+
| Aplica a todos los endpoints | Sí (por defecto) | No (explícito) |
|
|
246
|
+
| Puede retornar early (ej. CORS, cache) | Sí | Solo via HTTPException |
|
|
247
|
+
| Inyección de valores al endpoint | No | Sí |
|
|
248
|
+
| Testeable de forma aislada | Difícil | Fácil con dependency_overrides |
|
|
249
|
+
|
|
250
|
+
**Usar Middleware para**: logging de requests, timing, CORS, rate limiting global,
|
|
251
|
+
propagación de request-id.
|
|
252
|
+
|
|
253
|
+
**Usar Dependency para**: autenticación, autorización, validación de negocio,
|
|
254
|
+
sesiones DB, clientes HTTP, parámetros reutilizables.
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Dependencias por router vs por endpoint
|
|
259
|
+
|
|
260
|
+
```python
|
|
261
|
+
# Por router — aplica a TODOS los endpoints del router
|
|
262
|
+
router = APIRouter(
|
|
263
|
+
prefix="/admin",
|
|
264
|
+
tags=["Administración"],
|
|
265
|
+
dependencies=[Depends(require_role("admin"))], # Todos los endpoints requieren admin
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
# Por endpoint — control granular
|
|
269
|
+
@router.get("/reporte", dependencies=[Depends(require_empresa_activa())])
|
|
270
|
+
async def obtener_reporte(db: DbDep) -> dict:
|
|
271
|
+
...
|
|
272
|
+
|
|
273
|
+
# Router con dependencias globales + endpoint con dependencias adicionales
|
|
274
|
+
@router.post("/usuarios", dependencies=[Depends(require_role("superadmin"))])
|
|
275
|
+
async def crear_usuario_admin(
|
|
276
|
+
datos: UsuarioCreate,
|
|
277
|
+
db: DbDep,
|
|
278
|
+
# get_current_user ya está implícito via require_role
|
|
279
|
+
) -> UsuarioRead:
|
|
280
|
+
...
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Override de dependencias en tests
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
# tests/conftest.py
|
|
289
|
+
import pytest
|
|
290
|
+
from httpx import AsyncClient, ASGITransport
|
|
291
|
+
from app.main import app
|
|
292
|
+
from app.dependencies.database import get_db
|
|
293
|
+
from app.dependencies.auth import get_current_user
|
|
294
|
+
|
|
295
|
+
@pytest.fixture
|
|
296
|
+
def usuario_fake() -> Usuario:
|
|
297
|
+
return Usuario(id="test-uid", email="test@test.com", rol="admin", activo=True)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
@pytest.fixture
|
|
301
|
+
async def client_autenticado(db_test, usuario_fake):
|
|
302
|
+
"""Cliente con autenticación y BD de prueba inyectadas."""
|
|
303
|
+
async def _get_db_override():
|
|
304
|
+
yield db_test
|
|
305
|
+
|
|
306
|
+
async def _get_user_override():
|
|
307
|
+
return usuario_fake
|
|
308
|
+
|
|
309
|
+
# Registrar overrides ANTES de crear el cliente
|
|
310
|
+
app.dependency_overrides[get_db] = _get_db_override
|
|
311
|
+
app.dependency_overrides[get_current_user] = _get_user_override
|
|
312
|
+
|
|
313
|
+
async with AsyncClient(
|
|
314
|
+
transport=ASGITransport(app=app),
|
|
315
|
+
base_url="http://test",
|
|
316
|
+
) as ac:
|
|
317
|
+
yield ac
|
|
318
|
+
|
|
319
|
+
# Limpiar overrides DESPUÉS del test
|
|
320
|
+
app.dependency_overrides.clear()
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
@pytest.fixture
|
|
324
|
+
async def client_sin_auth(db_test):
|
|
325
|
+
"""Cliente sin autenticación para probar endpoints públicos."""
|
|
326
|
+
app.dependency_overrides[get_db] = lambda: db_test
|
|
327
|
+
async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as ac:
|
|
328
|
+
yield ac
|
|
329
|
+
app.dependency_overrides.clear()
|
|
330
|
+
```
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Referencia Completa — FastAPI Experto
|
|
2
|
+
|
|
3
|
+
## Middleware Personalizado
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
import time
|
|
7
|
+
import uuid
|
|
8
|
+
from fastapi import Request, Response
|
|
9
|
+
|
|
10
|
+
async def middleware_request_id(request: Request, call_next):
|
|
11
|
+
request_id = str(uuid.uuid4())
|
|
12
|
+
request.state.request_id = request_id
|
|
13
|
+
inicio = time.time()
|
|
14
|
+
response: Response = await call_next(request)
|
|
15
|
+
duracion = time.time() - inicio
|
|
16
|
+
response.headers["X-Request-ID"] = request_id
|
|
17
|
+
response.headers["X-Response-Time"] = f"{duracion:.4f}s"
|
|
18
|
+
return response
|
|
19
|
+
|
|
20
|
+
app.middleware("http")(middleware_request_id)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Testing con httpx
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
# tests/test_facturas.py
|
|
29
|
+
import pytest
|
|
30
|
+
from httpx import AsyncClient, ASGITransport
|
|
31
|
+
from app.main import app
|
|
32
|
+
|
|
33
|
+
@pytest.fixture
|
|
34
|
+
async def client(db_session):
|
|
35
|
+
async with AsyncClient(
|
|
36
|
+
transport=ASGITransport(app=app),
|
|
37
|
+
base_url="http://test",
|
|
38
|
+
) as ac:
|
|
39
|
+
yield ac
|
|
40
|
+
|
|
41
|
+
@pytest.mark.asyncio
|
|
42
|
+
async def test_crear_factura(client, token_admin, factura_valida):
|
|
43
|
+
respuesta = await client.post(
|
|
44
|
+
"/api/v1/facturas/",
|
|
45
|
+
json=factura_valida,
|
|
46
|
+
headers={"Authorization": f"Bearer {token_admin}"},
|
|
47
|
+
)
|
|
48
|
+
assert respuesta.status_code == 201
|
|
49
|
+
data = respuesta.json()
|
|
50
|
+
assert data["estatus"] == "borrador"
|
|
51
|
+
assert "id" in data
|
|
52
|
+
|
|
53
|
+
@pytest.mark.asyncio
|
|
54
|
+
async def test_factura_requiere_autenticacion(client):
|
|
55
|
+
respuesta = await client.post("/api/v1/facturas/", json={})
|
|
56
|
+
assert respuesta.status_code == 403 # Sin token
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Configuración con pydantic-settings
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
# app/core/config.py
|
|
65
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
66
|
+
|
|
67
|
+
class Settings(BaseSettings):
|
|
68
|
+
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8")
|
|
69
|
+
|
|
70
|
+
APP_NOMBRE: str = "Mi API"
|
|
71
|
+
APP_VERSION: str = "1.0.0"
|
|
72
|
+
DEBUG: bool = False
|
|
73
|
+
DATABASE_URL: str
|
|
74
|
+
SECRET_KEY: str
|
|
75
|
+
CORS_ORIGINS: list[str] = ["http://localhost:4200"]
|
|
76
|
+
ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
|
|
77
|
+
|
|
78
|
+
settings = Settings()
|
|
79
|
+
```
|