@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,225 @@
|
|
|
1
|
+
# Regla: Patrones de Arquitectura — Next.js (App Router)
|
|
2
|
+
|
|
3
|
+
El App Router de Next.js cambia fundamentalmente dónde y cómo se cargan datos.
|
|
4
|
+
Estos patrones aprovechan el modelo de Server Components para reducir el JavaScript
|
|
5
|
+
enviado al cliente, mejorar el rendimiento y simplificar la lógica de estado.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Server Components: fetch en el servidor
|
|
10
|
+
|
|
11
|
+
La forma correcta de cargar datos es en el servidor, no en el cliente con `useEffect`.
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
// MAL — useEffect para cargar datos (patrón del Pages Router)
|
|
15
|
+
'use client'
|
|
16
|
+
export default function PaginaFacturas() {
|
|
17
|
+
const [facturas, setFacturas] = useState<Factura[]>([])
|
|
18
|
+
const [cargando, setCargando] = useState(true)
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
fetch('/api/facturas')
|
|
22
|
+
.then(r => r.json())
|
|
23
|
+
.then(data => { setFacturas(data); setCargando(false) })
|
|
24
|
+
}, [])
|
|
25
|
+
|
|
26
|
+
if (cargando) return <p>Cargando...</p>
|
|
27
|
+
return <ListaFacturas facturas={facturas} />
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// BIEN — Server Component, fetch directo en el servidor
|
|
31
|
+
export default async function PaginaFacturas() {
|
|
32
|
+
const facturas = await obtenerFacturas() // llama directamente a la BD o API interna
|
|
33
|
+
return <ListaFacturas facturas={facturas} />
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- `obtenerFacturas()` puede llamar directamente a la BD, a un ORM o a un servicio
|
|
38
|
+
interno. No necesita pasar por una API REST si está en el mismo servidor.
|
|
39
|
+
- Next.js deduplica y cachea las llamadas automáticamente dentro del mismo render.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Server Actions para mutaciones
|
|
44
|
+
|
|
45
|
+
Las mutaciones de datos van en Server Actions, no en Route Handlers cuando
|
|
46
|
+
son invocadas desde formularios o componentes del mismo servidor.
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
// app/facturas/actions.ts
|
|
50
|
+
'use server'
|
|
51
|
+
|
|
52
|
+
import { revalidatePath } from 'next/cache'
|
|
53
|
+
import { redirect } from 'next/navigation'
|
|
54
|
+
import { z } from 'zod'
|
|
55
|
+
|
|
56
|
+
const EmitirFacturaSchema = z.object({
|
|
57
|
+
clienteId: z.coerce.number().int().positive(),
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
export async function emitirFactura(formData: FormData) {
|
|
61
|
+
const validado = EmitirFacturaSchema.safeParse({
|
|
62
|
+
clienteId: formData.get('clienteId'),
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
if (!validado.success) {
|
|
66
|
+
return { error: validado.error.flatten().fieldErrors }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
await facturaService.emitir(validado.data.clienteId)
|
|
70
|
+
revalidatePath('/facturas')
|
|
71
|
+
redirect('/facturas')
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- Las Server Actions validan sus inputs server-side con zod. NUNCA asumir que
|
|
76
|
+
el cliente envió datos válidos.
|
|
77
|
+
- `revalidatePath()` o `revalidateTag()` para invalidar el caché después de mutaciones.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Streaming con Suspense
|
|
82
|
+
|
|
83
|
+
- Envolver partes lentas del UI en `<Suspense>` para no bloquear el render completo:
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import { Suspense } from 'react'
|
|
87
|
+
|
|
88
|
+
export default function Dashboard() {
|
|
89
|
+
return (
|
|
90
|
+
<main>
|
|
91
|
+
<ResumenRapido /> {/* datos rápidos, sin Suspense */}
|
|
92
|
+
<Suspense fallback={<EsqueletoGrafica />}>
|
|
93
|
+
<GraficaVentasMensuales /> {/* query lenta */}
|
|
94
|
+
</Suspense>
|
|
95
|
+
<Suspense fallback={<EsqueletoTabla />}>
|
|
96
|
+
<TablaTopClientes /> {/* query lenta independiente */}
|
|
97
|
+
</Suspense>
|
|
98
|
+
</main>
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
- Cada `<Suspense>` permite que los demás componentes se rendericen sin esperar.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## ISR para contenido semi-estático
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
// Revalidar cada hora — ideal para catálogos de productos, precios, etc.
|
|
111
|
+
export const revalidate = 3600
|
|
112
|
+
|
|
113
|
+
// Revalidar bajo demanda con tag
|
|
114
|
+
fetch(url, { next: { tags: ['catalogo-productos'] } })
|
|
115
|
+
|
|
116
|
+
// En una Server Action o Route Handler:
|
|
117
|
+
revalidateTag('catalogo-productos')
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
- Usar ISR para contenido que cambia con menos frecuencia que las visitas.
|
|
121
|
+
- No usar ISR para datos que deben estar en tiempo real (inventario en compra,
|
|
122
|
+
saldo bancario). Para esos casos, `cache: 'no-store'`.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Parallel Routes para dashboards
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
app/dashboard/
|
|
130
|
+
@resumen/
|
|
131
|
+
page.tsx
|
|
132
|
+
@alertas/
|
|
133
|
+
page.tsx
|
|
134
|
+
@actividad/
|
|
135
|
+
page.tsx
|
|
136
|
+
layout.tsx ← recibe los tres slots en paralelo
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
// layout.tsx
|
|
141
|
+
export default function DashboardLayout({
|
|
142
|
+
resumen, alertas, actividad
|
|
143
|
+
}: {
|
|
144
|
+
resumen: React.ReactNode
|
|
145
|
+
alertas: React.ReactNode
|
|
146
|
+
actividad: React.ReactNode
|
|
147
|
+
}) {
|
|
148
|
+
return (
|
|
149
|
+
<div className="grid grid-cols-3 gap-4">
|
|
150
|
+
{resumen}
|
|
151
|
+
{alertas}
|
|
152
|
+
{actividad}
|
|
153
|
+
</div>
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Intercepting Routes para modales
|
|
161
|
+
|
|
162
|
+
- Para modales que muestran contenido de otra ruta sin navegar completamente:
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
app/
|
|
166
|
+
facturas/
|
|
167
|
+
page.tsx
|
|
168
|
+
[id]/
|
|
169
|
+
page.tsx ← vista completa de la factura
|
|
170
|
+
@modal/
|
|
171
|
+
(.)facturas/[id]/
|
|
172
|
+
page.tsx ← modal al hacer clic en la lista
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Route Handlers para API endpoints
|
|
178
|
+
|
|
179
|
+
- Usar `route.ts` para endpoints que son consumidos por clientes externos, móvil,
|
|
180
|
+
o por webhooks. No para datos internos del mismo servidor.
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
// app/api/facturas/route.ts
|
|
184
|
+
export async function GET(request: Request) {
|
|
185
|
+
const { searchParams } = new URL(request.url)
|
|
186
|
+
const pagina = Number(searchParams.get('pagina') ?? '1')
|
|
187
|
+
|
|
188
|
+
const facturas = await obtenerFacturasPaginadas(pagina)
|
|
189
|
+
return Response.json(facturas)
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Middleware para auth, redirects, i18n
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
// middleware.ts (raíz del proyecto)
|
|
199
|
+
export function middleware(request: NextRequest) {
|
|
200
|
+
const token = request.cookies.get('session')?.value
|
|
201
|
+
|
|
202
|
+
if (!token && request.nextUrl.pathname.startsWith('/app')) {
|
|
203
|
+
return NextResponse.redirect(new URL('/login', request.url))
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export const config = {
|
|
208
|
+
matcher: ['/app/:path*', '/api/:path*'],
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
- El middleware solo lee cookies y headers. No llama a la BD directamente.
|
|
213
|
+
- Para verificación de sesión pesada, usar la función `auth()` del framework
|
|
214
|
+
de autenticación dentro del Server Component, no en el middleware.
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Checklist de patrones antes de merge
|
|
219
|
+
|
|
220
|
+
- [ ] Sin `useEffect` para carga de datos que pueden ir en Server Component
|
|
221
|
+
- [ ] Mutaciones en Server Actions con validación zod server-side
|
|
222
|
+
- [ ] Secciones lentas del dashboard envueltas en `<Suspense>`
|
|
223
|
+
- [ ] `revalidatePath` o `revalidateTag` después de toda mutación
|
|
224
|
+
- [ ] Route Handlers solo para APIs externas, no para datos internos
|
|
225
|
+
- [ ] Middleware sin llamadas a BD directas
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# Regla: Performance
|
|
2
|
+
|
|
3
|
+
La optimización prematura es la raíz de todos los males — Donald Knuth.
|
|
4
|
+
Esta regla equilibra ese principio con las restricciones reales del sistema:
|
|
5
|
+
algunos problemas de performance son predecibles y deben evitarse desde el diseño.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## No optimizar prematuramente
|
|
10
|
+
|
|
11
|
+
- No escribir código complicado "por si acaso es lento".
|
|
12
|
+
Escribir el código más claro y simple primero.
|
|
13
|
+
- No sacrificar legibilidad por micro-optimizaciones sin evidencia de que
|
|
14
|
+
el código es un cuello de botella real.
|
|
15
|
+
- El código simple es más fácil de optimizar después que el código complejo
|
|
16
|
+
de hacer legible después.
|
|
17
|
+
- Excepción: anti-patrones de performance con costo predecible y conocido
|
|
18
|
+
(N+1 queries, carga de archivos completos en memoria, loops anidados O(n²))
|
|
19
|
+
deben evitarse desde el diseño aunque no haya medición todavía.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Medir antes de optimizar
|
|
24
|
+
|
|
25
|
+
- Antes de cualquier optimización: tener una medición de baseline.
|
|
26
|
+
Sin número, no hay optimización — hay cambio ciego.
|
|
27
|
+
- Formato mínimo de documentación de optimización:
|
|
28
|
+
```
|
|
29
|
+
Problema: el endpoint /facturas tarda 4.2s promedio bajo carga de 100 req/s
|
|
30
|
+
Causa identificada: N+1 queries en la relación factura → items (profiled con py-spy)
|
|
31
|
+
Solución: eager loading con selectinload()
|
|
32
|
+
Resultado: 0.18s promedio (mejora 23x)
|
|
33
|
+
```
|
|
34
|
+
- Optimización sin medición: no se acepta en code review.
|
|
35
|
+
- Las métricas de performance son parte del PR si el PR es una optimización.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Profiling con herramientas
|
|
40
|
+
|
|
41
|
+
Python — herramientas aprobadas:
|
|
42
|
+
- `py-spy` para profiling en producción (sin reiniciar el proceso)
|
|
43
|
+
- `cProfile` + `snakeviz` para profiling en desarrollo
|
|
44
|
+
- `line_profiler` para análisis línea por línea
|
|
45
|
+
- `memory_profiler` para problemas de memoria
|
|
46
|
+
- `EXPLAIN ANALYZE` en PostgreSQL para queries lentas
|
|
47
|
+
- `sqlalchemy echo=True` para ver queries generadas en desarrollo
|
|
48
|
+
|
|
49
|
+
TypeScript/Angular — herramientas aprobadas:
|
|
50
|
+
- Chrome DevTools Performance tab
|
|
51
|
+
- Angular DevTools (profiler de componentes y change detection)
|
|
52
|
+
- `webpack-bundle-analyzer` para tamaño de bundles
|
|
53
|
+
- Lighthouse para métricas web (LCP, FID, CLS)
|
|
54
|
+
|
|
55
|
+
Reglas de profiling:
|
|
56
|
+
- Perfilar en condiciones similares a producción (no en localhost con 1 usuario).
|
|
57
|
+
- Identificar el 20% del código que consume el 80% del tiempo antes de tocar nada.
|
|
58
|
+
- Documentar el resultado del profiling en el ticket o PR.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## N+1 queries — prohibidos
|
|
63
|
+
|
|
64
|
+
El problema N+1 es un bug de performance predecible y evitable desde el diseño:
|
|
65
|
+
|
|
66
|
+
Síntoma:
|
|
67
|
+
```python
|
|
68
|
+
# MALO: genera N+1 queries
|
|
69
|
+
facturas = db.query(Factura).all()
|
|
70
|
+
for factura in facturas:
|
|
71
|
+
print(factura.cliente.nombre) # query adicional por cada factura
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Solución con eager loading:
|
|
75
|
+
```python
|
|
76
|
+
# BIEN: 2 queries totales independientemente de cuántas facturas
|
|
77
|
+
facturas = db.query(Factura).options(selectinload(Factura.cliente)).all()
|
|
78
|
+
for factura in facturas:
|
|
79
|
+
print(factura.cliente.nombre) # ya cargado
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Reglas estrictas:
|
|
83
|
+
- Todo endpoint que devuelve colecciones con relaciones DEBE usar eager loading.
|
|
84
|
+
- Revisión obligatoria en code review: buscar acceso a atributos de relaciones
|
|
85
|
+
dentro de loops.
|
|
86
|
+
- En testing: activar logging de SQL en tests de integración para detectar N+1
|
|
87
|
+
contando queries ejecutadas.
|
|
88
|
+
- `lazy="selectin"` en relaciones ORM frecuentemente accedidas como default seguro.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Lazy loading para módulos pesados
|
|
93
|
+
|
|
94
|
+
Frontend Angular:
|
|
95
|
+
- Todo módulo que no es parte del critical rendering path DEBE cargarse con lazy loading.
|
|
96
|
+
- Rutas de admin, reportes, configuración: siempre lazy.
|
|
97
|
+
- Formato obligatorio en el router:
|
|
98
|
+
```typescript
|
|
99
|
+
{
|
|
100
|
+
path: 'reportes',
|
|
101
|
+
loadChildren: () => import('./reportes/reportes.module')
|
|
102
|
+
.then(m => m.ReportesModule)
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
- Verificar el tamaño del bundle inicial con `webpack-bundle-analyzer`.
|
|
106
|
+
Bundle inicial objetivo: <500KB gzipped.
|
|
107
|
+
- Preloading strategy para módulos que el usuario probablemente visitará:
|
|
108
|
+
`PreloadAllModules` o custom `QuicklinkStrategy`.
|
|
109
|
+
|
|
110
|
+
Backend Python:
|
|
111
|
+
- Imports costosos (modelos de ML, librerías de procesamiento) dentro de las
|
|
112
|
+
funciones que los usan, no en el nivel de módulo.
|
|
113
|
+
- Conexiones a servicios externos: inicializar en el primer uso, no al arrancar.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Caching con invalidación explícita
|
|
118
|
+
|
|
119
|
+
El caching sin invalidación es un bug en espera:
|
|
120
|
+
|
|
121
|
+
Reglas obligatorias:
|
|
122
|
+
- Todo cache tiene un TTL explícito definido en código o configuración.
|
|
123
|
+
NUNCA TTL infinito en producción.
|
|
124
|
+
- Los casos de invalidación anticipada están documentados en el código.
|
|
125
|
+
- El cache key incluye todos los parámetros que afectan el resultado.
|
|
126
|
+
Un cache key incorrecto causa bugs silenciosos de datos obsoletos.
|
|
127
|
+
|
|
128
|
+
Niveles de caching y herramientas:
|
|
129
|
+
- **In-memory (proceso)**: `functools.lru_cache` / `@cache` para valores
|
|
130
|
+
computacionalmente costosos e inmutables. Documentar el tamaño máximo.
|
|
131
|
+
- **Distribuido**: Redis para datos compartidos entre instancias.
|
|
132
|
+
Usar prefijos de key por entorno (`prod:`, `staging:`).
|
|
133
|
+
- **HTTP**: Cache-Control headers explícitos. `no-store` para datos sensibles.
|
|
134
|
+
`max-age` con revalidación para recursos estáticos.
|
|
135
|
+
- **BD query cache**: Con precaución — Postgres no tiene query cache nativo.
|
|
136
|
+
Usar vistas materializadas para queries complejas y costosas.
|
|
137
|
+
|
|
138
|
+
Patrón de invalidación:
|
|
139
|
+
```python
|
|
140
|
+
CACHE_KEY_FACTURAS = "facturas:{empresa_id}:{mes}"
|
|
141
|
+
CACHE_TTL_FACTURAS = 300 # 5 minutos
|
|
142
|
+
|
|
143
|
+
# Al mutar datos: invalidar explícitamente
|
|
144
|
+
async def crear_factura(empresa_id: UUID, ...):
|
|
145
|
+
factura = await _persistir_factura(...)
|
|
146
|
+
await cache.delete(CACHE_KEY_FACTURAS.format(empresa_id=empresa_id, mes=...))
|
|
147
|
+
return factura
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Índices de BD documentados
|
|
153
|
+
|
|
154
|
+
- Todo índice creado en la BD tiene un comentario en la migración que explica
|
|
155
|
+
qué query lo justifica.
|
|
156
|
+
- Formato obligatorio en la migración:
|
|
157
|
+
```python
|
|
158
|
+
# Índice para la query: GET /facturas?empresa_id=X&estatus=Y
|
|
159
|
+
# Antes del índice: 450ms (seq scan 2M filas)
|
|
160
|
+
# Después: 3ms (index scan)
|
|
161
|
+
op.create_index('ix_facturas_empresa_estatus', 'facturas',
|
|
162
|
+
['empresa_id', 'estatus'])
|
|
163
|
+
```
|
|
164
|
+
- No crear índices "preventivos" sin query que los justifique.
|
|
165
|
+
- Revisar índices no utilizados en producción cada 3 meses:
|
|
166
|
+
```sql
|
|
167
|
+
SELECT * FROM pg_stat_user_indexes WHERE idx_scan = 0;
|
|
168
|
+
```
|
|
169
|
+
- Índices compuestos: el orden de columnas importa. La columna más selectiva
|
|
170
|
+
o la usada en igualdad va primero.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Métricas de performance objetivo
|
|
175
|
+
|
|
176
|
+
Definir por proyecto, documentar en el README. Valores de referencia razonables:
|
|
177
|
+
|
|
178
|
+
| Tipo de operación | Objetivo | Alerta |
|
|
179
|
+
|-------------------|----------|--------|
|
|
180
|
+
| API GET simple | <100ms p95 | >500ms |
|
|
181
|
+
| API POST con escritura en BD | <300ms p95 | >1s |
|
|
182
|
+
| API con agregaciones | <500ms p95 | >2s |
|
|
183
|
+
| Render inicial de página | <2s LCP | >4s |
|
|
184
|
+
| Bundle JavaScript inicial | <500KB gzip | >1MB |
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Checklist de performance antes de merge
|
|
189
|
+
|
|
190
|
+
- [ ] Sin acceso a relaciones ORM dentro de loops (N+1)
|
|
191
|
+
- [ ] Módulos pesados en Angular con lazy loading
|
|
192
|
+
- [ ] Todo cache nuevo tiene TTL explícito e invalidación documentada
|
|
193
|
+
- [ ] Índices nuevos documentados en la migración con query que los justifica
|
|
194
|
+
- [ ] Si el PR es una optimización: tiene medición antes/después
|
|
195
|
+
- [ ] Sin imports costosos a nivel de módulo que retrasen el arranque
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Regla: Pruebas
|
|
2
|
+
|
|
3
|
+
Los tests no son opcionales. Son parte de la definición de "terminado" para
|
|
4
|
+
cualquier feature, bugfix o refactor. Código sin tests es código que no se puede
|
|
5
|
+
mantener con confianza.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Tests obligatorios para toda feature nueva
|
|
10
|
+
|
|
11
|
+
- Ninguna feature se considera completa sin tests que la cubran.
|
|
12
|
+
- Definición de Done incluye:
|
|
13
|
+
- Tests unitarios para toda función de lógica de negocio nueva
|
|
14
|
+
- Tests de integración para todo endpoint nuevo
|
|
15
|
+
- Tests de frontera para inputs extremos y casos de error
|
|
16
|
+
- El revisor rechaza PRs sin tests para código nuevo, sin excepción.
|
|
17
|
+
- Refactors: si el código refactorizado no tenía tests, agregarlos es parte del
|
|
18
|
+
trabajo de refactor, no una tarea separada.
|
|
19
|
+
- Bugfixes: escribir el test que reproduce el bug ANTES de escribir el fix.
|
|
20
|
+
Verificar que el test falla antes del fix y pasa después.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Cobertura mínima >80%
|
|
25
|
+
|
|
26
|
+
- La cobertura es una métrica, no el objetivo. Un 100% de cobertura con tests
|
|
27
|
+
triviales no garantiza calidad. Pero cobertura baja sí indica código sin probar.
|
|
28
|
+
- Umbral mínimo: 80% de cobertura de líneas en módulos de lógica de negocio.
|
|
29
|
+
- CI falla si la cobertura cae por debajo del umbral al agregar código nuevo.
|
|
30
|
+
- Reportar cobertura diferencial en el PR (cobertura del código nuevo añadido).
|
|
31
|
+
- Excepciones documentadas: código de configuración, __main__, scaffolding generado.
|
|
32
|
+
No se excluyen módulos por conveniencia — documentar explícitamente la razón.
|
|
33
|
+
- Herramientas: `pytest-cov` con `--cov-fail-under=80` para Python,
|
|
34
|
+
`jest --coverage --coverageThreshold` para TypeScript.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Patrón Arrange-Act-Assert (AAA)
|
|
39
|
+
|
|
40
|
+
Todo test unitario sigue este patrón sin excepción:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
def test_calcular_impuesto_con_tasa_estandar():
|
|
44
|
+
# Arrange — preparar el estado inicial
|
|
45
|
+
producto = Producto(precio=100.0, categoria="electronico")
|
|
46
|
+
calculadora = CalculadoraImpuesto(tasa=0.16)
|
|
47
|
+
|
|
48
|
+
# Act — ejecutar la unidad bajo prueba
|
|
49
|
+
resultado = calculadora.calcular(producto)
|
|
50
|
+
|
|
51
|
+
# Assert — verificar el resultado
|
|
52
|
+
assert resultado == 16.0
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Reglas del AAA:
|
|
56
|
+
- Los tres bloques separados visualmente (línea en blanco o comentario).
|
|
57
|
+
- Un solo Assert conceptual por test. Múltiples `assert` sobre el mismo resultado
|
|
58
|
+
están bien; assert sobre comportamientos distintos no.
|
|
59
|
+
- Si el Arrange es muy extenso: extraer a función helper o usar factories.
|
|
60
|
+
- Nombre del test describe el escenario completo:
|
|
61
|
+
`test_[unidad]_[escenario]_[resultado_esperado]`
|
|
62
|
+
Ejemplo: `test_crear_factura_sin_items_lanza_error_validacion`
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Tests deterministas — sin sleep ni delays
|
|
67
|
+
|
|
68
|
+
- Un test que falla intermitentemente es peor que ningún test: genera desconfianza
|
|
69
|
+
en el suite completo.
|
|
70
|
+
- NUNCA usar `time.sleep()`, `asyncio.sleep()`, `setTimeout()` en tests.
|
|
71
|
+
- NUNCA depender de tiempo real. Mockear el reloj:
|
|
72
|
+
- Python: `freezegun`, `unittest.mock.patch('datetime.datetime.now')`
|
|
73
|
+
- JavaScript: `jest.useFakeTimers()`
|
|
74
|
+
- NUNCA depender del orden de ejecución de los tests. Cada test es independiente.
|
|
75
|
+
- NUNCA depender del estado de un test anterior. Limpiar estado en `teardown`.
|
|
76
|
+
- Tests de integración con BD: usar transacciones que se revierten al final,
|
|
77
|
+
o fixtures aislados por test.
|
|
78
|
+
- Seeds de datos en BD de test: deterministas y reproducibles.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Factories sobre fixtures hardcodeados
|
|
83
|
+
|
|
84
|
+
- Fixtures hardcodeados (dicts o JSON estáticos con todos los campos) son frágiles:
|
|
85
|
+
cambian con el schema y no comunican qué datos son relevantes para el test.
|
|
86
|
+
- Usar factories que generan objetos con valores por defecto razonables y permiten
|
|
87
|
+
sobreescribir solo lo que importa para el test:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
# factory_boy (Python)
|
|
91
|
+
class FacturaFactory(factory.Factory):
|
|
92
|
+
class Meta:
|
|
93
|
+
model = Factura
|
|
94
|
+
estatus = "borrador"
|
|
95
|
+
total = 0.0
|
|
96
|
+
cliente = factory.SubFactory(ClienteFactory)
|
|
97
|
+
|
|
98
|
+
# En el test — solo los datos relevantes
|
|
99
|
+
factura = FacturaFactory(estatus="pagada", total=1000.0)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
- Factories en un módulo dedicado `tests/factories.py` o `tests/factories/`.
|
|
103
|
+
- No duplicar factories entre módulos — importar desde el módulo central.
|
|
104
|
+
- Para TypeScript: usar `@faker-js/faker` con funciones builder, no objetos
|
|
105
|
+
hardcodeados.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Tests de frontera para edge cases
|
|
110
|
+
|
|
111
|
+
Los casos felices son necesarios pero no suficientes. Todo test suite debe incluir:
|
|
112
|
+
|
|
113
|
+
- **Valores nulos / vacíos**: `None`, `""`, `[]`, `{}`, `0`
|
|
114
|
+
- **Valores en el límite**: longitud máxima, longitud mínima, valores justo
|
|
115
|
+
por encima y por debajo de umbrales numéricos
|
|
116
|
+
- **Tipos inesperados**: qué pasa si llega un string donde se espera un número
|
|
117
|
+
- **Colecciones extremas**: lista de 1 elemento, lista de 10,000 elementos
|
|
118
|
+
- **Concurrencia**: si la función modifica estado compartido, probar acceso
|
|
119
|
+
concurrente
|
|
120
|
+
- **Errores de dependencias externas**: qué pasa si la BD está caída, si la API
|
|
121
|
+
externa devuelve error 500, si el filesystem está lleno
|
|
122
|
+
- **Strings con caracteres especiales**: Unicode, emojis, SQL injection attempts,
|
|
123
|
+
XSS payloads — para validar que la sanitización funciona
|
|
124
|
+
|
|
125
|
+
Cada edge case que causó un bug en producción: agregar test de regresión.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Nomenclatura y organización
|
|
130
|
+
|
|
131
|
+
- Archivo de test espeja el módulo que prueba:
|
|
132
|
+
`app/services/factura_service.py` → `tests/services/test_factura_service.py`
|
|
133
|
+
- Tests de integración en `tests/integration/`, unitarios en `tests/unit/`.
|
|
134
|
+
- Agrupar tests relacionados en clases cuando hay mucho setup compartido.
|
|
135
|
+
- Nombre de la clase: `TestNombreDelModulo`. Nombre del método: `test_escenario`.
|
|
136
|
+
- No usar números en nombres de test (`test_1`, `test_caso_2`): sin semántica.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Mocks y stubs
|
|
141
|
+
|
|
142
|
+
- Mockear en el boundary del sistema: BD, APIs externas, filesystem, reloj.
|
|
143
|
+
- No mockear código propio — si se mockea, es señal de acoplamiento excesivo.
|
|
144
|
+
- Verificar que los mocks se configuran para el comportamiento esperado Y para
|
|
145
|
+
el comportamiento de error.
|
|
146
|
+
- Limpiar mocks entre tests para evitar contaminación de estado.
|
|
147
|
+
- Documentar en el test por qué se mockea algo si no es obvio.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Checklist de tests antes de merge
|
|
152
|
+
|
|
153
|
+
- [ ] Tests nuevos para todo código nuevo
|
|
154
|
+
- [ ] Test de regresión para todo bug corregido
|
|
155
|
+
- [ ] Cobertura del módulo modificado >= 80%
|
|
156
|
+
- [ ] Sin sleep/delay en tests
|
|
157
|
+
- [ ] Tests pasan de forma determinista 3 veces consecutivas en CI
|
|
158
|
+
- [ ] Factories usadas para datos de prueba complejos
|
|
159
|
+
- [ ] Edge cases cubiertos: nulos, vacíos, límites
|