@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,251 @@
|
|
|
1
|
+
# Regla: Hooks de Desarrollo Java
|
|
2
|
+
|
|
3
|
+
Los hooks de desarrollo son verificaciones automáticas que atrapan problemas
|
|
4
|
+
antes de que lleguen al repositorio o al CI. Ejecutar manualmente es propenso
|
|
5
|
+
a olvidos — automatizar garantiza consistencia.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Checkstyle: verificación de estilo antes de commit
|
|
10
|
+
|
|
11
|
+
Checkstyle verifica que el código sigue las convenciones definidas. Se integra
|
|
12
|
+
como plugin de Maven/Gradle y como pre-commit hook.
|
|
13
|
+
|
|
14
|
+
```xml
|
|
15
|
+
<!-- pom.xml -->
|
|
16
|
+
<plugin>
|
|
17
|
+
<groupId>org.apache.maven.plugins</groupId>
|
|
18
|
+
<artifactId>maven-checkstyle-plugin</artifactId>
|
|
19
|
+
<version>3.3.1</version>
|
|
20
|
+
<configuration>
|
|
21
|
+
<configLocation>google_checks.xml</configLocation>
|
|
22
|
+
<failsOnError>true</failsOnError>
|
|
23
|
+
<violationSeverity>warning</violationSeverity>
|
|
24
|
+
</configuration>
|
|
25
|
+
<executions>
|
|
26
|
+
<execution>
|
|
27
|
+
<id>validar-estilo</id>
|
|
28
|
+
<phase>validate</phase>
|
|
29
|
+
<goals><goal>check</goal></goals>
|
|
30
|
+
</execution>
|
|
31
|
+
</executions>
|
|
32
|
+
</plugin>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Pre-commit hook local (`.git/hooks/pre-commit`):
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
#!/bin/sh
|
|
39
|
+
# Verificar estilo Checkstyle antes de cada commit
|
|
40
|
+
mvn checkstyle:check -q 2>&1
|
|
41
|
+
if [ $? -ne 0 ]; then
|
|
42
|
+
echo "ERROR: Checkstyle falló. Corregir estilo antes de hacer commit."
|
|
43
|
+
echo "Ejecutar: mvn checkstyle:check para ver los errores."
|
|
44
|
+
exit 1
|
|
45
|
+
fi
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Spotless: formato automático obligatorio
|
|
51
|
+
|
|
52
|
+
Spotless puede formatear en lugar de solo verificar. Integrar como hook de
|
|
53
|
+
formato automático antes de verificar estilo.
|
|
54
|
+
|
|
55
|
+
```xml
|
|
56
|
+
<!-- pom.xml — Spotless formatea con google-java-format -->
|
|
57
|
+
<plugin>
|
|
58
|
+
<groupId>com.diffplug.spotless</groupId>
|
|
59
|
+
<artifactId>spotless-maven-plugin</artifactId>
|
|
60
|
+
<version>2.43.0</version>
|
|
61
|
+
<configuration>
|
|
62
|
+
<java>
|
|
63
|
+
<googleJavaFormat>
|
|
64
|
+
<version>1.19.2</version>
|
|
65
|
+
<style>AOSP</style>
|
|
66
|
+
</googleJavaFormat>
|
|
67
|
+
<removeUnusedImports/>
|
|
68
|
+
<trimTrailingWhitespace/>
|
|
69
|
+
</java>
|
|
70
|
+
</configuration>
|
|
71
|
+
<executions>
|
|
72
|
+
<execution>
|
|
73
|
+
<phase>compile</phase>
|
|
74
|
+
<goals><goal>check</goal></goals>
|
|
75
|
+
</execution>
|
|
76
|
+
</executions>
|
|
77
|
+
</plugin>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Aplicar formato manualmente antes de commit: `mvn spotless:apply`
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## SpotBugs: análisis estático
|
|
85
|
+
|
|
86
|
+
SpotBugs detecta bugs comunes (null pointer potential, resource leaks, bad practices)
|
|
87
|
+
antes de que lleguen a producción.
|
|
88
|
+
|
|
89
|
+
```xml
|
|
90
|
+
<!-- pom.xml -->
|
|
91
|
+
<plugin>
|
|
92
|
+
<groupId>com.github.spotbugs</groupId>
|
|
93
|
+
<artifactId>spotbugs-maven-plugin</artifactId>
|
|
94
|
+
<version>4.8.3.0</version>
|
|
95
|
+
<configuration>
|
|
96
|
+
<effort>Max</effort>
|
|
97
|
+
<threshold>Medium</threshold>
|
|
98
|
+
<failOnError>true</failOnError>
|
|
99
|
+
<plugins>
|
|
100
|
+
<!-- Detectar bugs de seguridad adicionales -->
|
|
101
|
+
<plugin>
|
|
102
|
+
<groupId>com.h3xstream.findsecbugs</groupId>
|
|
103
|
+
<artifactId>findsecbugs-plugin</artifactId>
|
|
104
|
+
<version>1.13.0</version>
|
|
105
|
+
</plugin>
|
|
106
|
+
</plugins>
|
|
107
|
+
</configuration>
|
|
108
|
+
<executions>
|
|
109
|
+
<execution>
|
|
110
|
+
<phase>verify</phase>
|
|
111
|
+
<goals><goal>check</goal></goals>
|
|
112
|
+
</execution>
|
|
113
|
+
</executions>
|
|
114
|
+
</plugin>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## JaCoCo: cobertura mínima en CI
|
|
120
|
+
|
|
121
|
+
La cobertura se verifica en CI como gate bloqueante. Sin cobertura >= 80%,
|
|
122
|
+
el build falla y no se puede mergear.
|
|
123
|
+
|
|
124
|
+
```xml
|
|
125
|
+
<!-- pom.xml -->
|
|
126
|
+
<plugin>
|
|
127
|
+
<groupId>org.jacoco</groupId>
|
|
128
|
+
<artifactId>jacoco-maven-plugin</artifactId>
|
|
129
|
+
<version>0.8.11</version>
|
|
130
|
+
<executions>
|
|
131
|
+
<execution>
|
|
132
|
+
<id>prepare-agent</id>
|
|
133
|
+
<goals><goal>prepare-agent</goal></goals>
|
|
134
|
+
</execution>
|
|
135
|
+
<execution>
|
|
136
|
+
<id>report</id>
|
|
137
|
+
<phase>test</phase>
|
|
138
|
+
<goals><goal>report</goal></goals>
|
|
139
|
+
</execution>
|
|
140
|
+
<execution>
|
|
141
|
+
<id>check</id>
|
|
142
|
+
<phase>verify</phase>
|
|
143
|
+
<goals><goal>check</goal></goals>
|
|
144
|
+
<configuration>
|
|
145
|
+
<rules>
|
|
146
|
+
<rule>
|
|
147
|
+
<element>BUNDLE</element>
|
|
148
|
+
<limits>
|
|
149
|
+
<limit>
|
|
150
|
+
<counter>LINE</counter>
|
|
151
|
+
<value>COVEREDRATIO</value>
|
|
152
|
+
<minimum>0.80</minimum>
|
|
153
|
+
</limit>
|
|
154
|
+
</limits>
|
|
155
|
+
</rule>
|
|
156
|
+
</rules>
|
|
157
|
+
</configuration>
|
|
158
|
+
</execution>
|
|
159
|
+
</executions>
|
|
160
|
+
</plugin>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Detección de System.out.println en código no-test
|
|
166
|
+
|
|
167
|
+
`System.out.println` en código de producción es un antipatrón. El logger
|
|
168
|
+
configurado maneja niveles, formatos y destinos correctamente.
|
|
169
|
+
|
|
170
|
+
Hook en CI (o pre-commit) que detecta y bloquea:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
#!/bin/sh
|
|
174
|
+
# Detectar System.out.println en código que no es test
|
|
175
|
+
ARCHIVOS_CON_PRINT=$(grep -r "System\.out\.println" src/main/ --include="*.java" -l)
|
|
176
|
+
|
|
177
|
+
if [ -n "$ARCHIVOS_CON_PRINT" ]; then
|
|
178
|
+
echo "ERROR: System.out.println detectado en código de producción."
|
|
179
|
+
echo "Usar SLF4J (log.info, log.debug, log.error) en su lugar."
|
|
180
|
+
echo "Archivos afectados:"
|
|
181
|
+
echo "$ARCHIVOS_CON_PRINT"
|
|
182
|
+
exit 1
|
|
183
|
+
fi
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
En el `pom.xml` con Checkstyle, agregar la regla `RegexpSingleline`:
|
|
187
|
+
|
|
188
|
+
```xml
|
|
189
|
+
<module name="RegexpSingleline">
|
|
190
|
+
<property name="format" value="System\.out\.println"/>
|
|
191
|
+
<property name="message" value="Usar SLF4J en lugar de System.out.println"/>
|
|
192
|
+
</module>
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Verificación de @Deprecated sin javadoc de reemplazo
|
|
198
|
+
|
|
199
|
+
Métodos deprecados sin indicar el reemplazo confunden al equipo.
|
|
200
|
+
|
|
201
|
+
```java
|
|
202
|
+
// MAL — sin indicación de reemplazo
|
|
203
|
+
@Deprecated
|
|
204
|
+
public Factura crearFacturaLegacy(String datos) { ... }
|
|
205
|
+
|
|
206
|
+
// BIEN — documenta cuándo fue deprecado y qué usar en su lugar
|
|
207
|
+
/**
|
|
208
|
+
* @deprecated Desde v2.3.0. Usar {@link FacturaService#crear(CrearFacturaRequest)} en su lugar.
|
|
209
|
+
*/
|
|
210
|
+
@Deprecated(since = "2.3.0", forRemoval = true)
|
|
211
|
+
public Factura crearFacturaLegacy(String datos) { ... }
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Script de verificación en CI:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
#!/bin/sh
|
|
218
|
+
# Detectar @Deprecated sin comentario de reemplazo
|
|
219
|
+
DEPRECATED_SIN_DOC=$(grep -B2 "@Deprecated" src/main/**/*.java | grep -v "@deprecated" | grep "@Deprecated" || true)
|
|
220
|
+
|
|
221
|
+
if [ -n "$DEPRECATED_SIN_DOC" ]; then
|
|
222
|
+
echo "ADVERTENCIA: @Deprecated sin javadoc de reemplazo encontrado."
|
|
223
|
+
echo "Agregar @deprecated en el javadoc indicando el reemplazo y la versión."
|
|
224
|
+
fi
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Pipeline CI completa de calidad
|
|
230
|
+
|
|
231
|
+
Orden de ejecución en el pipeline de CI (cada fase bloquea las siguientes):
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
1. mvn spotless:check → Formato de código
|
|
235
|
+
2. mvn checkstyle:check → Estilo y convenciones
|
|
236
|
+
3. mvn test → Tests unitarios
|
|
237
|
+
4. mvn spotbugs:check → Análisis estático
|
|
238
|
+
5. mvn verify → Tests de integración + cobertura JaCoCo
|
|
239
|
+
6. mvn dependency-check:check → Vulnerabilidades en dependencias
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Checklist de hooks Java antes de hacer commit
|
|
245
|
+
|
|
246
|
+
- [ ] `mvn spotless:check` pasa (o `mvn spotless:apply` aplicado)
|
|
247
|
+
- [ ] `mvn checkstyle:check` pasa sin errores
|
|
248
|
+
- [ ] Sin `System.out.println` en `src/main/`
|
|
249
|
+
- [ ] Métodos @Deprecated tienen javadoc con reemplazo y versión
|
|
250
|
+
- [ ] `mvn test` pasa localmente
|
|
251
|
+
- [ ] `mvn spotbugs:check` pasa sin bugs de severidad media o alta
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# Regla: Patrones Java Idiomáticos
|
|
2
|
+
|
|
3
|
+
Los patrones aquí listados no son opcionales: representan las soluciones probadas
|
|
4
|
+
para problemas recurrentes en código Java de producción. Ignorarlos genera deuda
|
|
5
|
+
técnica predecible y bugs conocidos.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Inyección de dependencias vía constructor (nunca field injection)
|
|
10
|
+
|
|
11
|
+
La inyección por campo (`@Autowired` en el campo) oculta dependencias, impide
|
|
12
|
+
tests sin contenedor IoC y viola el principio de inmutabilidad.
|
|
13
|
+
|
|
14
|
+
```java
|
|
15
|
+
// MAL — field injection: dependencias ocultas, imposible testear sin Spring
|
|
16
|
+
@Service
|
|
17
|
+
public class FacturaService {
|
|
18
|
+
@Autowired
|
|
19
|
+
private FacturaRepository repositorio; // no se ve en el constructor
|
|
20
|
+
@Autowired
|
|
21
|
+
private EventoPublicador publicador;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// BIEN — constructor injection: dependencias explícitas, testeable con mocks simples
|
|
25
|
+
@Service
|
|
26
|
+
public class FacturaService {
|
|
27
|
+
private final FacturaRepository repositorio;
|
|
28
|
+
private final EventoPublicador publicador;
|
|
29
|
+
|
|
30
|
+
public FacturaService(FacturaRepository repositorio, EventoPublicador publicador) {
|
|
31
|
+
this.repositorio = repositorio;
|
|
32
|
+
this.publicador = publicador;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Con Lombok: `@RequiredArgsConstructor` en la clase + campos `final` genera el
|
|
38
|
+
constructor automáticamente sin renunciar a la inyección por constructor.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Repository pattern con interfaces
|
|
43
|
+
|
|
44
|
+
Toda interacción con persistencia pasa por una interfaz de repositorio.
|
|
45
|
+
La lógica de negocio depende de la interfaz, no de la implementación.
|
|
46
|
+
|
|
47
|
+
```java
|
|
48
|
+
// Interfaz — define el contrato, no el cómo
|
|
49
|
+
public interface FacturaRepository {
|
|
50
|
+
Optional<Factura> buscarPorId(UUID id);
|
|
51
|
+
List<Factura> listarPorCliente(UUID clienteId, Pageable pageable);
|
|
52
|
+
Factura guardar(Factura factura);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Implementación — detalle de persistencia (JPA, JDBC, etc.)
|
|
56
|
+
@Repository
|
|
57
|
+
public class FacturaRepositoryJpa implements FacturaRepository {
|
|
58
|
+
private final JpaFacturaRepository jpa;
|
|
59
|
+
// ...
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Builder pattern para objetos complejos
|
|
66
|
+
|
|
67
|
+
Usar builder cuando un objeto tiene más de 4 parámetros opcionales de construcción.
|
|
68
|
+
Lombok `@Builder` es la implementación preferida.
|
|
69
|
+
|
|
70
|
+
```java
|
|
71
|
+
// MAL — constructor telescópico: frágil, no documenta qué es cada argumento
|
|
72
|
+
Factura f = new Factura(clienteId, fecha, items, descuento, null, "BORRADOR", true);
|
|
73
|
+
|
|
74
|
+
// BIEN — builder: cada parámetro es explícito y opcional
|
|
75
|
+
Factura factura = Factura.builder()
|
|
76
|
+
.clienteId(clienteId)
|
|
77
|
+
.fecha(LocalDate.now())
|
|
78
|
+
.items(items)
|
|
79
|
+
.descuento(BigDecimal.ZERO)
|
|
80
|
+
.estatus(EstatusFactura.BORRADOR)
|
|
81
|
+
.build();
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Strategy con interfaces funcionales
|
|
87
|
+
|
|
88
|
+
Para comportamiento intercambiable, preferir interfaces funcionales sobre
|
|
89
|
+
jerarquías de clases cuando la estrategia es simple.
|
|
90
|
+
|
|
91
|
+
```java
|
|
92
|
+
// Interfaz funcional como estrategia
|
|
93
|
+
@FunctionalInterface
|
|
94
|
+
public interface CalculadorDescuento {
|
|
95
|
+
BigDecimal calcular(BigDecimal subtotal);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Estrategias como lambdas o method references — sin clases adicionales
|
|
99
|
+
CalculadorDescuento sinDescuento = subtotal -> BigDecimal.ZERO;
|
|
100
|
+
CalculadorDescuento descuentoFijo = subtotal -> new BigDecimal("100.00");
|
|
101
|
+
CalculadorDescuento descuentoPorcentual = subtotal -> subtotal.multiply(new BigDecimal("0.10"));
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Stream API sobre loops imperativos
|
|
107
|
+
|
|
108
|
+
Preferir Stream API para transformaciones, filtros y agregaciones de colecciones.
|
|
109
|
+
Los loops imperativos son aceptables cuando el Stream resultaría más oscuro.
|
|
110
|
+
|
|
111
|
+
```java
|
|
112
|
+
// MAL — loop imperativo para transformación simple
|
|
113
|
+
List<String> nombres = new ArrayList<>();
|
|
114
|
+
for (Usuario u : usuarios) {
|
|
115
|
+
if (u.isActivo()) {
|
|
116
|
+
nombres.add(u.getNombre().toUpperCase());
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// BIEN — Stream declara la intención, no los pasos
|
|
121
|
+
List<String> nombres = usuarios.stream()
|
|
122
|
+
.filter(Usuario::isActivo)
|
|
123
|
+
.map(Usuario::getNombre)
|
|
124
|
+
.map(String::toUpperCase)
|
|
125
|
+
.toList(); // Java 16+: List inmutable directamente
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## CompletableFuture para operaciones asíncronas
|
|
131
|
+
|
|
132
|
+
```java
|
|
133
|
+
// Composición de operaciones asíncronas sin bloquear threads
|
|
134
|
+
public CompletableFuture<FacturaEnviada> crearYEnviarFactura(FacturaRequest request) {
|
|
135
|
+
return CompletableFuture
|
|
136
|
+
.supplyAsync(() -> repositorio.guardar(request.toEntidad()), executor)
|
|
137
|
+
.thenApplyAsync(factura -> generarPdf(factura), executor)
|
|
138
|
+
.thenApplyAsync(pdf -> servicioEmail.enviar(pdf), executor)
|
|
139
|
+
.exceptionally(ex -> {
|
|
140
|
+
log.error("Error al crear factura", ex);
|
|
141
|
+
throw new FacturaException("No se pudo crear la factura", ex);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Try-with-resources obligatorio
|
|
149
|
+
|
|
150
|
+
Todo recurso que implementa `AutoCloseable` DEBE abrirse en try-with-resources.
|
|
151
|
+
Nunca cerrar manualmente en `finally`.
|
|
152
|
+
|
|
153
|
+
```java
|
|
154
|
+
// MAL — cierre manual propenso a fugas de recursos
|
|
155
|
+
InputStream stream = new FileInputStream(archivo);
|
|
156
|
+
try {
|
|
157
|
+
procesar(stream);
|
|
158
|
+
} finally {
|
|
159
|
+
stream.close(); // ¿qué pasa si procesar() lanza excepción?
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// BIEN — cierre garantizado por la JVM
|
|
163
|
+
try (var stream = new FileInputStream(archivo);
|
|
164
|
+
var reader = new BufferedReader(new InputStreamReader(stream))) {
|
|
165
|
+
procesar(reader);
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Jerarquía propia de excepciones
|
|
172
|
+
|
|
173
|
+
- Excepciones de negocio heredan de `RuntimeException` (unchecked).
|
|
174
|
+
- Checked exceptions solo para condiciones recuperables que el llamador DEBE manejar.
|
|
175
|
+
- Nunca capturar `Exception` o `Throwable` sin razón documentada.
|
|
176
|
+
|
|
177
|
+
```java
|
|
178
|
+
// Jerarquía de dominio
|
|
179
|
+
public class DominioException extends RuntimeException {
|
|
180
|
+
public DominioException(String mensaje) { super(mensaje); }
|
|
181
|
+
public DominioException(String mensaje, Throwable causa) { super(mensaje, causa); }
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
public class FacturaNoEncontradaException extends DominioException {
|
|
185
|
+
public FacturaNoEncontradaException(UUID id) {
|
|
186
|
+
super("Factura no encontrada: " + id);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
public class SaldoInsuficienteException extends DominioException { ... }
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Factory method para construcción compleja
|
|
196
|
+
|
|
197
|
+
Cuando la construcción de un objeto requiere lógica, usar factory method estático
|
|
198
|
+
en lugar de sobrecargar constructores.
|
|
199
|
+
|
|
200
|
+
```java
|
|
201
|
+
public class Factura {
|
|
202
|
+
// Factory methods con nombres descriptivos
|
|
203
|
+
public static Factura nueva(Cliente cliente, List<LineaFactura> lineas) {
|
|
204
|
+
var factura = new Factura();
|
|
205
|
+
factura.folio = generarFolio();
|
|
206
|
+
factura.cliente = cliente;
|
|
207
|
+
factura.lineas = List.copyOf(lineas);
|
|
208
|
+
factura.calcularTotales();
|
|
209
|
+
return factura;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
public static Factura desde(FacturaDto dto) { ... }
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Checklist de patrones Java antes de abrir PR
|
|
219
|
+
|
|
220
|
+
- [ ] Sin @Autowired en campos — inyección solo por constructor
|
|
221
|
+
- [ ] Objetos con >4 parámetros usan Builder
|
|
222
|
+
- [ ] Interacción con BD a través de interfaces Repository
|
|
223
|
+
- [ ] Recursos AutoCloseable abiertos con try-with-resources
|
|
224
|
+
- [ ] Excepciones de negocio extienden RuntimeException con jerarquía propia
|
|
225
|
+
- [ ] Transformaciones de colecciones usan Stream API
|
|
226
|
+
- [ ] Sin loops for que podrían ser un stream de 3 líneas
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# Regla: Seguridad Java
|
|
2
|
+
|
|
3
|
+
Esta regla es OBLIGATORIA. Ningún endpoint, servicio o componente se considera
|
|
4
|
+
completo si viola alguno de los puntos aquí listados.
|
|
5
|
+
Las vulnerabilidades de seguridad en Java tienen consecuencias predecibles
|
|
6
|
+
y conocidas — no hay excusa para repetirlas.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## PreparedStatement SIEMPRE — nunca concatenar SQL
|
|
11
|
+
|
|
12
|
+
La inyección SQL sigue siendo la vulnerabilidad #1 en aplicaciones Java.
|
|
13
|
+
Es 100% evitable con parameterized queries.
|
|
14
|
+
|
|
15
|
+
```java
|
|
16
|
+
// MAL — SQL injection garantizada
|
|
17
|
+
String query = "SELECT * FROM usuarios WHERE email = '" + email + "'";
|
|
18
|
+
Statement stmt = conn.createStatement();
|
|
19
|
+
ResultSet rs = stmt.executeQuery(query);
|
|
20
|
+
|
|
21
|
+
// MAL — también vulnerable aunque parezca diferente
|
|
22
|
+
String query = String.format("SELECT * FROM facturas WHERE id = %s", id);
|
|
23
|
+
|
|
24
|
+
// BIEN — PreparedStatement con parámetros nombrados
|
|
25
|
+
String query = "SELECT * FROM usuarios WHERE email = ? AND activo = ?";
|
|
26
|
+
try (var stmt = conn.prepareStatement(query)) {
|
|
27
|
+
stmt.setString(1, email);
|
|
28
|
+
stmt.setBoolean(2, true);
|
|
29
|
+
ResultSet rs = stmt.executeQuery();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// BIEN — con JPA/Spring Data (ORM hace el trabajo)
|
|
33
|
+
List<Usuario> usuarios = repositorio.findByEmailAndActivo(email, true);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Si se requiere SQL dinámico, usar `JdbcTemplate` con `?` o named parameters,
|
|
37
|
+
nunca `String.format()` ni concatenación.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Validación con @Valid y Bean Validation
|
|
42
|
+
|
|
43
|
+
Toda entrada del usuario DEBE validarse en el servidor. La validación en frontend
|
|
44
|
+
es UX, no seguridad.
|
|
45
|
+
|
|
46
|
+
```java
|
|
47
|
+
// DTO con restricciones de Bean Validation
|
|
48
|
+
public record CrearFacturaRequest(
|
|
49
|
+
@NotNull(message = "El cliente es obligatorio")
|
|
50
|
+
UUID clienteId,
|
|
51
|
+
|
|
52
|
+
@NotEmpty(message = "La factura debe tener al menos una línea")
|
|
53
|
+
@Size(max = 100, message = "Máximo 100 líneas por factura")
|
|
54
|
+
List<@Valid LineaRequest> lineas,
|
|
55
|
+
|
|
56
|
+
@DecimalMin(value = "0.0", message = "El descuento no puede ser negativo")
|
|
57
|
+
@DecimalMax(value = "100.0", message = "El descuento no puede superar 100%")
|
|
58
|
+
BigDecimal descuentoPorcentaje
|
|
59
|
+
) {}
|
|
60
|
+
|
|
61
|
+
// Controller — @Valid activa la validación automáticamente
|
|
62
|
+
@PostMapping("/facturas")
|
|
63
|
+
public ResponseEntity<FacturaDto> crear(@RequestBody @Valid CrearFacturaRequest request) {
|
|
64
|
+
// Si llega aquí, request ya fue validado
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Spring Security: CORS, CSRF y sesiones
|
|
71
|
+
|
|
72
|
+
```java
|
|
73
|
+
@Configuration
|
|
74
|
+
@EnableWebSecurity
|
|
75
|
+
public class SecurityConfig {
|
|
76
|
+
|
|
77
|
+
@Bean
|
|
78
|
+
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
|
79
|
+
return http
|
|
80
|
+
// CORS desde variables de entorno, nunca hardcodeado
|
|
81
|
+
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
|
|
82
|
+
// CSRF: habilitar para apps con sesiones; deshabilitar solo en APIs stateless con JWT
|
|
83
|
+
.csrf(csrf -> csrf.disable()) // APIs REST con JWT — documentar por qué
|
|
84
|
+
// Sesiones stateless para APIs REST
|
|
85
|
+
.sessionManagement(session ->
|
|
86
|
+
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
|
87
|
+
// Headers de seguridad
|
|
88
|
+
.headers(headers -> headers
|
|
89
|
+
.frameOptions(frame -> frame.deny())
|
|
90
|
+
.xssProtection(xss -> xss.disable()) // CSP es mejor que X-XSS-Protection
|
|
91
|
+
.contentSecurityPolicy(csp ->
|
|
92
|
+
csp.policyDirectives("default-src 'self'")))
|
|
93
|
+
.build();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@Bean
|
|
97
|
+
public CorsConfigurationSource corsConfigurationSource() {
|
|
98
|
+
var config = new CorsConfiguration();
|
|
99
|
+
// Leer desde environment, NUNCA hardcodear
|
|
100
|
+
config.setAllowedOrigins(List.of(env.getProperty("cors.allowed-origins").split(",")));
|
|
101
|
+
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
|
|
102
|
+
config.setAllowedHeaders(List.of("Authorization", "Content-Type"));
|
|
103
|
+
var source = new UrlBasedCorsConfigurationSource();
|
|
104
|
+
source.registerCorsConfiguration("/api/**", config);
|
|
105
|
+
return source;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Secretos vía variables de entorno
|
|
113
|
+
|
|
114
|
+
```java
|
|
115
|
+
// MAL — secreto hardcodeado en el código fuente
|
|
116
|
+
private static final String JWT_SECRET = "mi-secreto-super-secreto";
|
|
117
|
+
private static final String DB_PASSWORD = "admin123";
|
|
118
|
+
|
|
119
|
+
// MAL — secreto en application.properties que se versiona
|
|
120
|
+
// application.properties:
|
|
121
|
+
// spring.datasource.password=admin123
|
|
122
|
+
|
|
123
|
+
// BIEN — variables de entorno inyectadas
|
|
124
|
+
@Value("${JWT_SECRET}")
|
|
125
|
+
private String jwtSecret;
|
|
126
|
+
|
|
127
|
+
// BIEN — application.properties usa placeholders
|
|
128
|
+
// application.properties:
|
|
129
|
+
// spring.datasource.password=${DB_PASSWORD}
|
|
130
|
+
// jwt.secret=${JWT_SECRET}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
El archivo `.env` es solo para desarrollo local y SIEMPRE está en `.gitignore`.
|
|
134
|
+
En producción, las variables se inyectan desde Vault, AWS Secrets Manager o el
|
|
135
|
+
sistema de deployment.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## No deserializar objetos no confiables
|
|
140
|
+
|
|
141
|
+
```java
|
|
142
|
+
// MAL — deserialización insegura: vector de RCE (Remote Code Execution)
|
|
143
|
+
ObjectInputStream ois = new ObjectInputStream(inputStreamDeUsuario);
|
|
144
|
+
Object objeto = ois.readObject(); // NUNCA con datos no confiables
|
|
145
|
+
|
|
146
|
+
// BIEN — usar JSON con Jackson o protobuf, no serialización Java nativa
|
|
147
|
+
ObjectMapper mapper = new ObjectMapper();
|
|
148
|
+
FacturaDto dto = mapper.readValue(jsonInput, FacturaDto.class);
|
|
149
|
+
|
|
150
|
+
// BIEN — si se requiere deserialización Java, usar filtros de clase
|
|
151
|
+
ObjectInputStream ois = new ObjectInputStream(input) {
|
|
152
|
+
@Override
|
|
153
|
+
protected Class<?> resolveClass(ObjectStreamClass desc) throws ClassNotFoundException {
|
|
154
|
+
if (!desc.getName().startsWith("com.miempresa.")) {
|
|
155
|
+
throw new InvalidClassException("Clase no permitida: " + desc.getName());
|
|
156
|
+
}
|
|
157
|
+
return super.resolveClass(desc);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## OWASP Dependency Check en CI
|
|
165
|
+
|
|
166
|
+
```xml
|
|
167
|
+
<!-- pom.xml — falla el build si hay CVE de severidad >= 8.0 -->
|
|
168
|
+
<plugin>
|
|
169
|
+
<groupId>org.owasp</groupId>
|
|
170
|
+
<artifactId>dependency-check-maven</artifactId>
|
|
171
|
+
<version>9.0.10</version>
|
|
172
|
+
<configuration>
|
|
173
|
+
<failBuildOnCVSS>8</failBuildOnCVSS>
|
|
174
|
+
<suppressionFile>owasp-suppressions.xml</suppressionFile>
|
|
175
|
+
</configuration>
|
|
176
|
+
<executions>
|
|
177
|
+
<execution>
|
|
178
|
+
<goals><goal>check</goal></goals>
|
|
179
|
+
</execution>
|
|
180
|
+
</executions>
|
|
181
|
+
</plugin>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Logging sin datos sensibles (SLF4J + Logback)
|
|
187
|
+
|
|
188
|
+
```java
|
|
189
|
+
// MAL — datos sensibles en logs
|
|
190
|
+
log.info("Usuario autenticado: {} con contraseña: {}", email, password);
|
|
191
|
+
log.debug("Token JWT generado: {}", jwtToken);
|
|
192
|
+
log.error("Error de BD al procesar: {}", tarjetaCredito.getNumero());
|
|
193
|
+
|
|
194
|
+
// BIEN — log solo información no sensible
|
|
195
|
+
log.info("Autenticación exitosa para usuario: {}", email);
|
|
196
|
+
log.debug("Token JWT generado para sesión: {}", sesionId);
|
|
197
|
+
log.error("Error de BD al procesar pedido: {}", pedidoId);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Configurar en `logback.xml` un `PatternLayout` que sanitice campos sensibles
|
|
201
|
+
si el logging de requests completos es necesario para debugging.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Headers de seguridad en Spring Boot
|
|
206
|
+
|
|
207
|
+
```yaml
|
|
208
|
+
# application.yml — headers mínimos de seguridad
|
|
209
|
+
server:
|
|
210
|
+
servlet:
|
|
211
|
+
session:
|
|
212
|
+
cookie:
|
|
213
|
+
http-only: true
|
|
214
|
+
secure: true
|
|
215
|
+
same-site: strict
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Verificar con OWASP ZAP o similar que los headers `Strict-Transport-Security`,
|
|
219
|
+
`X-Content-Type-Options`, `X-Frame-Options` y `Content-Security-Policy` están
|
|
220
|
+
presentes en las respuestas de producción.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Checklist de seguridad Java antes de abrir PR
|
|
225
|
+
|
|
226
|
+
- [ ] Sin concatenación de strings en queries SQL — solo PreparedStatement o JPA
|
|
227
|
+
- [ ] Inputs validados con @Valid y Bean Validation en todos los endpoints
|
|
228
|
+
- [ ] Sin secretos hardcodeados — variables de entorno en todos los ambientes
|
|
229
|
+
- [ ] Sin ObjectInputStream con datos de usuarios externos
|
|
230
|
+
- [ ] CORS configurado desde variables de entorno, no hardcodeado
|
|
231
|
+
- [ ] OWASP Dependency Check en CI sin CVEs críticos sin suprimir
|
|
232
|
+
- [ ] Logs sin passwords, tokens ni datos personales
|
|
233
|
+
- [ ] Headers de seguridad configurados en Spring Security
|