@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,297 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: performance-baseline
|
|
3
|
+
description: Establece y documenta una línea base de rendimiento para el sistema. Mide latencia p50/p95/p99, throughput, uso de memoria y CPU. Identifica cuellos de botella con herramientas de profiling. Guía la optimización con datos, no con suposiciones.
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
herramientasPermitidas: [Read, Bash]
|
|
6
|
+
evolvable: true # default para skill estandar
|
|
7
|
+
exclusiones:
|
|
8
|
+
- "No cargar para observabilidad de producción en tiempo real (Prometheus, Grafana, alertas) — para monitoreo y alertas de sistemas en producción cargar `monitoring-alertas`."
|
|
9
|
+
- "No cargar para profiling de memoria o CPU con flamegraphs en producción bajo carga real sin un baseline previo — establecer primero la línea base antes de profiling avanzado."
|
|
10
|
+
- "No cargar para load testing de APIs externas o terceros sin autorización — las pruebas de carga sobre infraestructura ajena sin permiso constituyen un ataque DoS."
|
|
11
|
+
- "No cargar para benchmarks de hardware o comparación de proveedores cloud — este skill mide la aplicación propia, no la plataforma subyacente."
|
|
12
|
+
---
|
|
13
|
+
# Habilidad: Performance Baseline
|
|
14
|
+
|
|
15
|
+
## Cuándo NO cargar
|
|
16
|
+
|
|
17
|
+
- La tarea es monitoreo de producción en tiempo real (Prometheus, alertas, dashboards): cargar `monitoring-alertas`.
|
|
18
|
+
- La tarea es load testing de sistemas externos o terceros sin autorización escrita: no proceder.
|
|
19
|
+
- La tarea es comparar proveedores cloud o benchmarks de hardware: usar documentación del proveedor directamente.
|
|
20
|
+
- La tarea es profiling avanzado de un componente ya identificado como cuello de botella: iniciar con este skill para el baseline, luego proceder al profiling específico.
|
|
21
|
+
|
|
22
|
+
## Propósito
|
|
23
|
+
|
|
24
|
+
"Optimizar sin medir es adivinar." Esta habilidad establece mediciones reales
|
|
25
|
+
del sistema antes de cualquier optimización, documenta el baseline y guía
|
|
26
|
+
el trabajo de mejora con evidencia. Ninguna optimización se acepta sin una
|
|
27
|
+
comparación before/after con los mismos benchmarks.
|
|
28
|
+
|
|
29
|
+
## Cuándo activar
|
|
30
|
+
|
|
31
|
+
- Antes de iniciar una fase de optimización de rendimiento
|
|
32
|
+
- Cuando el usuario reporta "el sistema está lento" sin métricas
|
|
33
|
+
- Al establecer SLOs para un sistema nuevo
|
|
34
|
+
- Antes y después de cambios en queries, caching o arquitectura
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Métricas clave a medir
|
|
39
|
+
|
|
40
|
+
### Latencia (la más importante para APIs)
|
|
41
|
+
|
|
42
|
+
| Percentil | Descripción | Target típico web |
|
|
43
|
+
|-----------|-------------|------------------|
|
|
44
|
+
| p50 | Mediana — 50% de requests son más rápidos | < 100ms |
|
|
45
|
+
| p95 | 95% de requests terminan antes de este tiempo | < 300ms |
|
|
46
|
+
| p99 | El "peor caso razonable" | < 1000ms |
|
|
47
|
+
| p99.9 | Outliers extremos | < 3000ms |
|
|
48
|
+
|
|
49
|
+
**Por qué p95 y p99, no promedio**: El promedio oculta las colas lentas. Un
|
|
50
|
+
sistema con p50=50ms y p99=10000ms tiene un promedio "aceptable" pero una
|
|
51
|
+
experiencia terrible para 1 de cada 100 usuarios.
|
|
52
|
+
|
|
53
|
+
### Throughput
|
|
54
|
+
|
|
55
|
+
- **Requests por segundo (RPS)**: Cuántas peticiones puede manejar el sistema
|
|
56
|
+
- **Concurrencia máxima**: Número de requests simultáneos sin degradación
|
|
57
|
+
- **Punto de quiebre**: RPS donde la latencia p99 supera el threshold aceptable
|
|
58
|
+
|
|
59
|
+
### Recursos del sistema
|
|
60
|
+
|
|
61
|
+
- **CPU**: % de uso en carga normal, pico y stress
|
|
62
|
+
- **Memoria**: RSS basal, memoria en carga, crecimiento por hora (leak detection)
|
|
63
|
+
- **I/O de BD**: queries/segundo, tiempo de query p95, conexiones activas
|
|
64
|
+
- **Network**: bytes in/out, conexiones abiertas
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Herramientas de medición por stack
|
|
69
|
+
|
|
70
|
+
### Backend Python / FastAPI
|
|
71
|
+
|
|
72
|
+
**Profiling de CPU** — encontrar funciones lentas:
|
|
73
|
+
```python
|
|
74
|
+
# Con cProfile (incluido en stdlib)
|
|
75
|
+
import cProfile
|
|
76
|
+
import pstats
|
|
77
|
+
import io
|
|
78
|
+
|
|
79
|
+
def profile_function():
|
|
80
|
+
pr = cProfile.Profile()
|
|
81
|
+
pr.enable()
|
|
82
|
+
# ... función a perfilar
|
|
83
|
+
pr.disable()
|
|
84
|
+
|
|
85
|
+
s = io.StringIO()
|
|
86
|
+
ps = pstats.Stats(pr, stream=s).sort_stats('cumulative')
|
|
87
|
+
ps.print_stats(20) # Top 20 funciones más lentas
|
|
88
|
+
print(s.getvalue())
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Profiling de memoria** — detectar leaks:
|
|
92
|
+
```bash
|
|
93
|
+
pip install memory-profiler
|
|
94
|
+
python -m memory_profiler mi_script.py
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Profiling de queries SQL** — con SQLAlchemy:
|
|
98
|
+
```python
|
|
99
|
+
# En desarrollo, activar logging de queries con tiempo
|
|
100
|
+
import logging
|
|
101
|
+
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
|
|
102
|
+
|
|
103
|
+
# O con pgBadger / pg_stat_statements en PostgreSQL
|
|
104
|
+
# Ver queries más lentas:
|
|
105
|
+
SELECT query, calls, total_time, mean_time, stddev_time
|
|
106
|
+
FROM pg_stat_statements
|
|
107
|
+
ORDER BY mean_time DESC
|
|
108
|
+
LIMIT 20;
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Load testing** — con locust:
|
|
112
|
+
```python
|
|
113
|
+
# locustfile.py
|
|
114
|
+
from locust import HttpUser, task, between
|
|
115
|
+
|
|
116
|
+
class APIUser(HttpUser):
|
|
117
|
+
wait_time = between(0.1, 0.5)
|
|
118
|
+
|
|
119
|
+
@task(3) # peso 3 = ejecuta 3x más frecuente
|
|
120
|
+
def listar_recursos(self):
|
|
121
|
+
self.client.get("/api/v1/recursos",
|
|
122
|
+
headers={"Authorization": f"Bearer {self.token}"})
|
|
123
|
+
|
|
124
|
+
@task(1)
|
|
125
|
+
def crear_recurso(self):
|
|
126
|
+
self.client.post("/api/v1/recursos",
|
|
127
|
+
json={"nombre": "test"},
|
|
128
|
+
headers={"Authorization": f"Bearer {self.token}"})
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Ejecutar con 100 usuarios, rampa de 10/segundo
|
|
133
|
+
locust -f locustfile.py --headless -u 100 -r 10 --run-time 2m \
|
|
134
|
+
--host http://localhost:8000
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Frontend Angular
|
|
138
|
+
|
|
139
|
+
**Core Web Vitals** (métricas que Google y usuarios ven):
|
|
140
|
+
| Métrica | Descripción | Target |
|
|
141
|
+
|---------|-------------|--------|
|
|
142
|
+
| LCP | Largest Contentful Paint — tiempo hasta que el contenido principal es visible | < 2.5s |
|
|
143
|
+
| FID / INP | First Input Delay / Interaction to Next Paint | < 100ms |
|
|
144
|
+
| CLS | Cumulative Layout Shift — estabilidad visual | < 0.1 |
|
|
145
|
+
| TTFB | Time to First Byte | < 600ms |
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# Lighthouse CLI
|
|
149
|
+
npm install -g lighthouse
|
|
150
|
+
lighthouse http://localhost:4200 --output=json --output-path=lighthouse-report.json
|
|
151
|
+
|
|
152
|
+
# Analizar bundle size
|
|
153
|
+
ng build --stats-json
|
|
154
|
+
npx webpack-bundle-analyzer dist/*/stats.json
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Profiling de Angular en desarrollo**:
|
|
158
|
+
```typescript
|
|
159
|
+
// Habilitar profiler de Angular
|
|
160
|
+
import { enableProdMode } from '@angular/core';
|
|
161
|
+
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
|
162
|
+
|
|
163
|
+
// En main.ts para development
|
|
164
|
+
platformBrowserDynamic().bootstrapModule(AppModule)
|
|
165
|
+
.then(() => {
|
|
166
|
+
// Chrome DevTools > Performance > Profile
|
|
167
|
+
// Buscar "Angular" en la traza para ver change detection cycles
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Profiling browser-based — Trazas de rendimiento real
|
|
174
|
+
|
|
175
|
+
Lighthouse da un score sintético. Las trazas de rendimiento dan datos reales de lo que
|
|
176
|
+
ocurre frame-a-frame en el navegador. Preferir trazas cuando se necesita diagnosticar
|
|
177
|
+
**por qué** un Web Vital falla, no solo **que** falla.
|
|
178
|
+
|
|
179
|
+
**Workflow de profiling con DevTools** (manual o vía MCP con `chrome-devtools-mcp`):
|
|
180
|
+
|
|
181
|
+
1. Navegar a la página bajo prueba con throttling de CPU 4x y red "Fast 3G"
|
|
182
|
+
2. Grabar traza de rendimiento (botón Record → interactuar → Stop)
|
|
183
|
+
3. Extraer Performance Insights — cada uno indica una causa raíz específica:
|
|
184
|
+
|
|
185
|
+
| Performance Insight | Qué detecta | Acción correctiva |
|
|
186
|
+
|--------------------|--------------|--------------------|
|
|
187
|
+
| **LCPBreakdown** | Desglose de LCP: TTFB + load delay + load time + render delay | Optimizar el componente con mayor porcentaje |
|
|
188
|
+
| **DocumentLatency** | TTFB alto del documento principal | Revisar server response time, CDN, redirects |
|
|
189
|
+
| **RenderBlocking** | Scripts/CSS que bloquean el primer render | `async`/`defer` en scripts, inline critical CSS |
|
|
190
|
+
| **ThirdPartyIssues** | Scripts de terceros que consumen main thread | Lazy-load o eliminar; mover a web worker si es posible |
|
|
191
|
+
| **LayoutShift** | Elementos que causan CLS (imágenes sin dimensiones, fonts) | `width`/`height` explícitos, `font-display: swap` |
|
|
192
|
+
| **LongTask** | Tareas JS > 50ms que bloquean interactividad (INP) | Code-split, `requestIdleCallback`, web workers |
|
|
193
|
+
|
|
194
|
+
**Gotcha crítico**: Lighthouse scores (lab data) ≠ experiencia real del usuario (field data).
|
|
195
|
+
Un LCP de 1.8s en Lighthouse puede ser 4.2s en un dispositivo móvil real con red 4G.
|
|
196
|
+
Para datos de campo reales usar CrUX (Chrome User Experience Report) o web-vitals library
|
|
197
|
+
en producción.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Plantilla de documento baseline
|
|
202
|
+
|
|
203
|
+
### `.planning/PERFORMANCE-BASELINE.md`
|
|
204
|
+
|
|
205
|
+
```markdown
|
|
206
|
+
# PERFORMANCE-BASELINE.md
|
|
207
|
+
**Fecha de medición**: [fecha]
|
|
208
|
+
**Versión del sistema**: [git commit hash]
|
|
209
|
+
**Entorno**: [staging / producción / local con datos reales]
|
|
210
|
+
**Herramientas usadas**: [locust, pytest-benchmark, lighthouse, etc.]
|
|
211
|
+
|
|
212
|
+
## Condiciones del test
|
|
213
|
+
- Datos en BD: [número de registros en tablas principales]
|
|
214
|
+
- Concurrencia simulada: [N usuarios simultáneos]
|
|
215
|
+
- Duración del test: [N minutos]
|
|
216
|
+
- Hardware del servidor: [specs o instancia cloud]
|
|
217
|
+
|
|
218
|
+
## Resultados de latencia (API)
|
|
219
|
+
|
|
220
|
+
| Endpoint | p50 | p95 | p99 | RPS máx |
|
|
221
|
+
|----------|-----|-----|-----|---------|
|
|
222
|
+
| GET /api/v1/[recurso] | Xms | Xms | Xms | N |
|
|
223
|
+
| POST /api/v1/[recurso] | Xms | Xms | Xms | N |
|
|
224
|
+
|
|
225
|
+
## Resultados de recursos
|
|
226
|
+
|
|
227
|
+
| Métrica | Basal | Bajo carga | Pico |
|
|
228
|
+
|---------|-------|-----------|------|
|
|
229
|
+
| CPU % | | | |
|
|
230
|
+
| Memoria RSS | | | |
|
|
231
|
+
| Conexiones BD activas | | | |
|
|
232
|
+
| Queries/segundo | | | |
|
|
233
|
+
|
|
234
|
+
## Core Web Vitals (si aplica)
|
|
235
|
+
|
|
236
|
+
| Métrica | Valor medido | Target | Estado |
|
|
237
|
+
|---------|-------------|--------|--------|
|
|
238
|
+
| LCP | | < 2.5s | PASS/FAIL |
|
|
239
|
+
| INP | | < 100ms | PASS/FAIL |
|
|
240
|
+
| CLS | | < 0.1 | PASS/FAIL |
|
|
241
|
+
|
|
242
|
+
## Top 5 queries más lentas
|
|
243
|
+
| Query | Duración media | Llamadas/min | Plan de optimización |
|
|
244
|
+
|-------|---------------|-------------|---------------------|
|
|
245
|
+
| | | | |
|
|
246
|
+
|
|
247
|
+
## Cuellos de botella identificados
|
|
248
|
+
1. [Descripción, causa raíz, impacto estimado]
|
|
249
|
+
|
|
250
|
+
## SLOs propuestos (basados en baseline)
|
|
251
|
+
| Métrica | SLO | Alerta si supera |
|
|
252
|
+
|---------|-----|-----------------|
|
|
253
|
+
| Latencia p95 | < Xms | > Xms |
|
|
254
|
+
| Error rate | < 0.1% | > 0.5% |
|
|
255
|
+
| Disponibilidad | > 99.5% | < 99.0% |
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Proceso de optimización guiada por datos
|
|
261
|
+
|
|
262
|
+
```
|
|
263
|
+
1. Medir → documentar baseline
|
|
264
|
+
2. Identificar el cuello de botella más costoso (no el más fácil)
|
|
265
|
+
3. Hipótesis: "Creo que X es lento porque Y"
|
|
266
|
+
4. Implementar UNA optimización
|
|
267
|
+
5. Medir con los MISMOS benchmarks del baseline
|
|
268
|
+
6. Comparar before/after
|
|
269
|
+
7. Documentar resultado en PERFORMANCE-BASELINE.md
|
|
270
|
+
8. Si mejoró: hacer commit, continuar con siguiente cuello de botella
|
|
271
|
+
9. Si no mejoró: revertir, revisar hipótesis
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Optimizaciones por orden de impacto típico
|
|
275
|
+
|
|
276
|
+
1. **Índices de BD faltantes** — impacto: 10x-1000x en queries lentas
|
|
277
|
+
2. **N+1 queries** — impacto: reducción de O(n) queries a O(1)
|
|
278
|
+
3. **Caching de resultados costosos** — impacto: 5x-50x en datos calientes
|
|
279
|
+
4. **Connection pooling** — impacto: elimina overhead de conexiones
|
|
280
|
+
5. **Paginación de resultados grandes** — impacto: reducción de tiempo y memoria
|
|
281
|
+
6. **Bundle splitting en frontend** — impacto: reducción de tiempo de carga inicial
|
|
282
|
+
|
|
283
|
+
**Anti-patrón a evitar**: optimizar código Python/TypeScript antes de verificar
|
|
284
|
+
que las queries de BD no son el problema real. El 80% de los problemas de
|
|
285
|
+
rendimiento en aplicaciones web tienen origen en la capa de datos.
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Gotchas / Errores comunes no obvios
|
|
290
|
+
|
|
291
|
+
**Locust reporta latencia p99 dentro del target pero los usuarios se quejan de lentitud porque Locust mide solo el tiempo de respuesta de red y no incluye el tiempo de renderizado del navegador ni los assets**: en una prueba de carga Locust con 100 usuarios y p99=400ms, los usuarios reales experimentan 2.8s porque el bundle JS pesa 3MB y se descarga en paralelo con la API. Causa: Locust mide exclusivamente el tiempo de la llamada HTTP al endpoint, sin incluir la carga de assets estáticos, scripts ni el tiempo de parseo del navegador. Fix: complementar Locust con Lighthouse y trazas de Chrome DevTools. El baseline real de experiencia de usuario combina ambas mediciones, no solo la capa API.
|
|
292
|
+
|
|
293
|
+
**`memory_profiler` en Python muestra consumo de memoria estable pero la aplicación en producción tiene un leak real porque `memory_profiler` mide solo el proceso Python y no la memoria del pool de conexiones de SQLAlchemy ni los buffers del driver de PostgreSQL**: después de 4 horas de carga, el RSS del proceso crece de 150MB a 1.2GB sin que `@profile` muestre ninguna función acumulando objetos. Causa: `psycopg2` y `asyncpg` usan buffers de memoria C nativos no rastreados por el GC de Python. Fix: medir el RSS completo con `psutil.Process().memory_info().rss` cada N requests en producción, y revisar `pg_stat_activity` para conexiones huérfanas. Si el pool no tiene `pool_recycle` configurado, las conexiones viejas retienen buffers indefinidamente.
|
|
294
|
+
|
|
295
|
+
**Los resultados de `pg_stat_statements` son inestables en la primera semana de activarlo porque el módulo sólo agrega estadísticas de queries ejecutadas después de su activación**: hacer `CREATE EXTENSION pg_stat_statements` en una BD existente con meses de operación muestra historial vacío; las queries con `mean_time` alto son outliers de las primeras horas, no el comportamiento habitual. Causa: `pg_stat_statements` no retroactiva — solo mide desde su activación. Fix: esperar al menos 48 horas bajo carga normal antes de sacar conclusiones del baseline de queries. Hacer `SELECT pg_stat_statements_reset()` al inicio para tener un período de medición limpio y definido.
|
|
296
|
+
|
|
297
|
+
**El throughput máximo medido con `locust --headless` es artificialmente bajo cuando el servidor de prueba corre en la misma máquina que la aplicación porque ambos compiten por CPU**: en desarrollo local con 4 núcleos, Locust consume 1.5 núcleos para simular 200 usuarios, dejando solo 2.5 núcleos para la aplicación. El baseline registra 340 RPS como máximo, pero en staging dedicado el mismo sistema alcanza 820 RPS. Causa: la contención de recursos en la máquina local es un factor de confusión sistemático. Fix: ejecutar siempre las pruebas de carga desde una máquina separada (o en CI con runner dedicado) hacia la aplicación en un servidor aislado. Documentar en el baseline si la prueba fue local o remota.
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: php-experto
|
|
3
|
+
description: >
|
|
4
|
+
PHP moderno con Laravel: Service Container, Eloquent ORM, Form Requests,
|
|
5
|
+
API Resources, Events, Jobs/Queues, Middleware y Sanctum. Cargar cuando
|
|
6
|
+
se implementen APIs Laravel, modelos Eloquent, jobs asíncronos o autenticación.
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
herramientasPermitidas: [Read, Grep]
|
|
9
|
+
exclusiones:
|
|
10
|
+
- "No cargar para diseñar patrones Laravel (Action classes, DTOs readonly, Pipeline) — para diseño cargar `php-patrones`."
|
|
11
|
+
- "No cargar para escribir tests PHPUnit o Pest — para testing cargar `php-testing`."
|
|
12
|
+
- "No cargar para errores de compilación PHP o Composer — para build errors cargar `build-errors-php`."
|
|
13
|
+
- "No cargar para PHP sin Laravel (vanilla PHP, Symfony, Slim) — este skill cubre patrones idiomáticos de Laravel específicamente."
|
|
14
|
+
evolvable: true # default para skill estandar
|
|
15
|
+
---
|
|
16
|
+
# PHP Experto — Laravel Moderno
|
|
17
|
+
|
|
18
|
+
Laravel es un framework con opiniones fuertes. Este skill cubre los patrones
|
|
19
|
+
idiomáticos de Laravel 10/11: inyección de dependencias via Service Container,
|
|
20
|
+
Eloquent con relaciones complejas, Jobs con Horizon y autenticación con Sanctum.
|
|
21
|
+
|
|
22
|
+
## Cuándo cargar este skill
|
|
23
|
+
|
|
24
|
+
Invoca `Skill("php-experto")` cuando:
|
|
25
|
+
|
|
26
|
+
- Se implementen endpoints en una API Laravel (controllers, routes)
|
|
27
|
+
- Se definan modelos Eloquent con relaciones o query scopes
|
|
28
|
+
- Se escriban Form Requests para validación
|
|
29
|
+
- Se creen Jobs, Events o Listeners
|
|
30
|
+
- Se configure autenticación con Laravel Sanctum
|
|
31
|
+
- Se implementen Artisan commands custom
|
|
32
|
+
|
|
33
|
+
## Cuándo NO cargar
|
|
34
|
+
|
|
35
|
+
- La pregunta es sobre diseñar patrones Laravel (Action classes, DTOs readonly, Pipeline) — para diseño cargar `php-patrones`.
|
|
36
|
+
- La tarea es escribir tests PHPUnit o Pest — cargar `php-testing`.
|
|
37
|
+
- Los errores son de Composer, autoload o extensiones PHP — cargar `build-errors-php`.
|
|
38
|
+
- El proyecto usa PHP sin Laravel (Symfony, Slim, vanilla PHP) — este skill cubre patrones idiomáticos de Laravel específicamente.
|
|
39
|
+
|
|
40
|
+
## Conceptos clave
|
|
41
|
+
|
|
42
|
+
### Service Container y Dependency Injection
|
|
43
|
+
|
|
44
|
+
El Service Container resuelve dependencias automáticamente. Inyectar en constructores
|
|
45
|
+
de controllers y services — nunca instanciar con `new` dentro de métodos de negocio.
|
|
46
|
+
|
|
47
|
+
### Eloquent Relationships
|
|
48
|
+
|
|
49
|
+
Eloquent soporta `hasOne`, `hasMany`, `belongsTo`, `belongsToMany`, `morphTo` y
|
|
50
|
+
variantes polimórficas. Cada relación tiene un método que retorna el Builder,
|
|
51
|
+
no la colección — la colección se obtiene accediendo a la propiedad.
|
|
52
|
+
|
|
53
|
+
### Query Scopes
|
|
54
|
+
|
|
55
|
+
Los scopes encapsulan condiciones de query reutilizables. Los `local scopes` se
|
|
56
|
+
activan con un prefijo `scope` y se encadenan como métodos. Los `global scopes`
|
|
57
|
+
se aplican automáticamente a todas las queries del modelo.
|
|
58
|
+
|
|
59
|
+
## Reglas obligatorias
|
|
60
|
+
|
|
61
|
+
### Usar Form Requests para validación — NUNCA validar en el Controller
|
|
62
|
+
|
|
63
|
+
```php
|
|
64
|
+
// MAL — logica de validacion en el controller
|
|
65
|
+
public function store(Request $request) {
|
|
66
|
+
$request->validate([...]);
|
|
67
|
+
// ...
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// BIEN — Form Request separado
|
|
71
|
+
public function store(StoreProductoRequest $request) {
|
|
72
|
+
// $request ya viene validado y autorizado
|
|
73
|
+
$data = $request->validated();
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Por qué**: Los Form Requests permiten reutilizar validación, separar autorización
|
|
78
|
+
y tienen método `prepareForValidation` para normalizar inputs antes de validar.
|
|
79
|
+
|
|
80
|
+
### Eager loading OBLIGATORIO para relaciones en colecciones
|
|
81
|
+
|
|
82
|
+
```php
|
|
83
|
+
// MAL — N+1 queries
|
|
84
|
+
$pedidos = Pedido::all();
|
|
85
|
+
foreach ($pedidos as $pedido) {
|
|
86
|
+
echo $pedido->cliente->nombre; // query por cada pedido
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// BIEN — 2 queries sin importar el tamano de la coleccion
|
|
90
|
+
$pedidos = Pedido::with('cliente')->get();
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Cómo verificar**: Activar `DB::listen` en desarrollo o usar Telescope/Debugbar
|
|
94
|
+
para contar queries. Más de 2 queries para una colección es señal de N+1.
|
|
95
|
+
|
|
96
|
+
### API Resources para serializar respuestas — NUNCA retornar modelos directamente
|
|
97
|
+
|
|
98
|
+
```php
|
|
99
|
+
// MAL
|
|
100
|
+
return response()->json($usuario); // expone todos los campos incluidos sensibles
|
|
101
|
+
|
|
102
|
+
// BIEN
|
|
103
|
+
return new UsuarioResource($usuario);
|
|
104
|
+
return UsuarioResource::collection($usuarios);
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Jobs SIEMPRE en queues para operaciones costosas (>200ms)
|
|
108
|
+
|
|
109
|
+
```php
|
|
110
|
+
// Dispatch a queue, no sincrono
|
|
111
|
+
EnviarEmailBienvenida::dispatch($usuario)->onQueue('emails');
|
|
112
|
+
|
|
113
|
+
// Con reintento y delay
|
|
114
|
+
EnviarFactura::dispatch($factura)
|
|
115
|
+
->delay(now()->addMinutes(5))
|
|
116
|
+
->onQueue('documentos');
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Bindings en TODAS las queries raw — NUNCA interpolacion
|
|
120
|
+
|
|
121
|
+
```php
|
|
122
|
+
// MAL — SQL injection
|
|
123
|
+
DB::statement("UPDATE usuarios SET rol = '{$rol}' WHERE id = {$id}");
|
|
124
|
+
|
|
125
|
+
// BIEN — parametros nombrados
|
|
126
|
+
DB::statement("UPDATE usuarios SET rol = :rol WHERE id = :id", [
|
|
127
|
+
'rol' => $rol,
|
|
128
|
+
'id' => $id,
|
|
129
|
+
]);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Patrones recomendados
|
|
133
|
+
|
|
134
|
+
### Eloquent Relationships correctamente definidas
|
|
135
|
+
|
|
136
|
+
```php
|
|
137
|
+
class Pedido extends Model
|
|
138
|
+
{
|
|
139
|
+
// hasMany: un pedido tiene muchos items
|
|
140
|
+
public function items(): HasMany
|
|
141
|
+
{
|
|
142
|
+
return $this->hasMany(ItemPedido::class);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// belongsTo: un pedido pertenece a un cliente
|
|
146
|
+
public function cliente(): BelongsTo
|
|
147
|
+
{
|
|
148
|
+
return $this->belongsTo(Cliente::class);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// morphTo: comentarios polimorficos
|
|
152
|
+
public function comentarios(): MorphMany
|
|
153
|
+
{
|
|
154
|
+
return $this->morphMany(Comentario::class, 'comentable');
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Query Scopes para filtros reutilizables
|
|
160
|
+
|
|
161
|
+
```php
|
|
162
|
+
class Producto extends Model
|
|
163
|
+
{
|
|
164
|
+
// Local scope: $query->activo()
|
|
165
|
+
public function scopeActivo(Builder $query): Builder
|
|
166
|
+
{
|
|
167
|
+
return $query->where('activo', true);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Scope con parametro: $query->precioMenorA(500)
|
|
171
|
+
public function scopePrecioMenorA(Builder $query, float $precio): Builder
|
|
172
|
+
{
|
|
173
|
+
return $query->where('precio', '<', $precio);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Uso encadenado
|
|
178
|
+
$productos = Producto::activo()->precioMenorA(500)->with('categoria')->get();
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Event + Listener desacoplados
|
|
182
|
+
|
|
183
|
+
```php
|
|
184
|
+
// Disparar el evento en el service
|
|
185
|
+
event(new PedidoCreado($pedido));
|
|
186
|
+
|
|
187
|
+
// El listener se encola automaticamente si implementa ShouldQueue
|
|
188
|
+
class NotificarClientePedidoCreado implements ShouldQueue
|
|
189
|
+
{
|
|
190
|
+
public function handle(PedidoCreado $event): void
|
|
191
|
+
{
|
|
192
|
+
$event->pedido->cliente->notify(new PedidoCreadoNotification($event->pedido));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Sanctum — proteger rutas de API
|
|
198
|
+
|
|
199
|
+
```php
|
|
200
|
+
// routes/api.php
|
|
201
|
+
Route::middleware('auth:sanctum')->group(function () {
|
|
202
|
+
Route::apiResource('pedidos', PedidoController::class);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// Crear token para el usuario
|
|
206
|
+
$token = $usuario->createToken('app-movil', ['pedidos:leer'])->plainTextToken;
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Artisan Command custom
|
|
210
|
+
|
|
211
|
+
```php
|
|
212
|
+
class SincronizarCatalogo extends Command
|
|
213
|
+
{
|
|
214
|
+
protected $signature = 'catalogo:sincronizar {--forzar : Ignorar cache}';
|
|
215
|
+
protected $description = 'Sincroniza el catalogo desde la API externa';
|
|
216
|
+
|
|
217
|
+
public function handle(CatalogoService $servicio): int
|
|
218
|
+
{
|
|
219
|
+
$this->info('Iniciando sincronizacion...');
|
|
220
|
+
$resultado = $servicio->sincronizar(forzar: $this->option('forzar'));
|
|
221
|
+
$this->table(['Categoria', 'Productos'], $resultado->resumen());
|
|
222
|
+
return Command::SUCCESS;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Anti-patrones conocidos
|
|
228
|
+
|
|
229
|
+
### Fat Controllers — NUNCA poner lógica de negocio en controllers
|
|
230
|
+
|
|
231
|
+
```php
|
|
232
|
+
// MAL — controller con 80 lineas de logica
|
|
233
|
+
public function store(Request $request) {
|
|
234
|
+
$descuento = $request->codigo ? Cupon::where('codigo', $request->codigo)
|
|
235
|
+
->where('activo', true)->first()?->descuento ?? 0 : 0;
|
|
236
|
+
$total = collect($request->items)->sum(fn($i) => $i['precio'] * $i['cantidad']);
|
|
237
|
+
$totalConDescuento = $total * (1 - $descuento / 100);
|
|
238
|
+
// ... 50 lineas mas
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// BIEN — delegar a un service o action
|
|
242
|
+
public function store(StorePedidoRequest $request, CrearPedidoAction $action): JsonResponse
|
|
243
|
+
{
|
|
244
|
+
$pedido = $action->ejecutar($request->validated());
|
|
245
|
+
return new PedidoResource($pedido);
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Model Observers para lógica compleja — usar Events en su lugar
|
|
250
|
+
|
|
251
|
+
Los Observers son invisibles al lector del código. Para lógica de negocio
|
|
252
|
+
significativa (enviar emails, actualizar inventario) usar Events explícitamente.
|
|
253
|
+
|
|
254
|
+
### Collections::all() en tablas grandes sin paginación
|
|
255
|
+
|
|
256
|
+
```php
|
|
257
|
+
// MAL — carga toda la tabla en memoria
|
|
258
|
+
$productos = Producto::all();
|
|
259
|
+
|
|
260
|
+
// BIEN — paginar o usar lazy collection
|
|
261
|
+
$productos = Producto::paginate(50);
|
|
262
|
+
$productos = Producto::lazy(); // procesa de a chunks sin cargar todo
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Checklist de verificación
|
|
266
|
+
|
|
267
|
+
- [ ] Validación en Form Request, no en el controller
|
|
268
|
+
- [ ] Relaciones cargadas con `with()` en colecciones (sin N+1)
|
|
269
|
+
- [ ] Respuestas de API usando API Resources
|
|
270
|
+
- [ ] Operations >200ms despachadas como Jobs
|
|
271
|
+
- [ ] Sin interpolación de strings en queries SQL
|
|
272
|
+
- [ ] Autenticación con Sanctum en rutas protegidas
|
|
273
|
+
- [ ] `$fillable` o `$guarded` definido en cada modelo
|
|
274
|
+
|
|
275
|
+
## Referencias
|
|
276
|
+
|
|
277
|
+
- [Laravel Documentation](https://laravel.com/docs)
|
|
278
|
+
- [Laravel Best Practices](https://github.com/alexeymezenin/laravel-best-practices)
|
|
279
|
+
|
|
280
|
+
## Gotchas / Errores comunes no obvios
|
|
281
|
+
|
|
282
|
+
**Eloquent `with()` cargado en el controller no se aplica a queries del service**: si el controller hace `Factura::with('cliente')->find($id)` pero el service tiene su propio `Factura::find($id)` internamente, la relación `cliente` no se carga en la segunda query. Causa: `with()` es por query, no por modelo. Fix: centralizar el eager loading en el repositorio o service — no dispersarlo entre capas.
|
|
283
|
+
|
|
284
|
+
**`Job::dispatch()` en un test sin `Queue::fake()` ejecuta el job de forma síncrona**: sin `Queue::fake()`, Laravel ejecuta el job inmediatamente en el mismo proceso del test si la queue driver es `sync` (la default en `testing`). Esto puede causar efectos secundarios inesperados en los datos del test. Fix: agregar `Queue::fake()` en el `setUp()` de todos los tests que disparan jobs, y usar `Queue::assertPushed(MiJob::class)` para verificar que fue despachado.
|
|
285
|
+
|
|
286
|
+
**`FormRequest` con `authorize()` retornando `false` lanza `AuthorizationException` pero en tests lanza `403` sin mensaje descriptivo**: en tests de feature, un `authorize()` que retorna `false` devuelve 403 sin indicar cuál rule falló. Causa: la excepción de autorización no incluye el mensaje del FormRequest. Fix: usar `$this->actingAs($usuario)` con el usuario correcto en los tests, y verificar el comportamiento de `authorize()` en un test unitario del FormRequest separado.
|
|
287
|
+
|
|
288
|
+
**Eloquent `$fillable` vs `$guarded` — usar `$guarded = ['id']` en lugar de `$fillable` en modelos con muchos campos puede exponer campos no deseados al añadir nuevos**: si se añade un campo sensible al modelo sin actualizar `$fillable`, no se puede asignar masivamente (seguro). Pero con `$guarded = ['id']`, el nuevo campo sí acepta asignación masiva automáticamente. Fix: usar `$fillable` explícito en modelos con campos sensibles para que el default sea denegar asignación masiva.
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
*Skill creado con swl:crear-skill el 2026-03-31. Versión 1.0.0.*
|