@tacuchi/agent-workflow-cli 6.2.0 → 7.0.1
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/README.md +65 -12
- package/dist/application/profile/profile-service.d.ts +53 -0
- package/dist/application/profile/profile-service.d.ts.map +1 -0
- package/dist/application/profile/profile-service.js +210 -0
- package/dist/application/profile/profile-service.js.map +1 -0
- package/dist/application/self/bootstrap.js +2 -1
- package/dist/application/self/bootstrap.js.map +1 -1
- package/dist/application/self/detect-hosts.d.ts +18 -0
- package/dist/application/self/detect-hosts.d.ts.map +1 -0
- package/dist/application/self/detect-hosts.js +37 -0
- package/dist/application/self/detect-hosts.js.map +1 -0
- package/dist/application/self/install-hooks.d.ts +30 -0
- package/dist/application/self/install-hooks.d.ts.map +1 -0
- package/dist/application/self/install-hooks.js +253 -0
- package/dist/application/self/install-hooks.js.map +1 -0
- package/dist/application/self/install-skill.d.ts +2 -0
- package/dist/application/self/install-skill.d.ts.map +1 -1
- package/dist/application/self/install-skill.js +69 -3
- package/dist/application/self/install-skill.js.map +1 -1
- package/dist/cli/commands/self.d.ts.map +1 -1
- package/dist/cli/commands/self.js +9 -1
- package/dist/cli/commands/self.js.map +1 -1
- package/dist/cli/tui/tabs/skills-tab.d.ts.map +1 -1
- package/dist/cli/tui/tabs/skills-tab.js +100 -24
- package/dist/cli/tui/tabs/skills-tab.js.map +1 -1
- package/package.json +2 -2
- package/skills/agent-workflow/commands/README.md +26 -0
- package/skills/agent-workflow/commands/compact.md +24 -0
- package/skills/agent-workflow/commands/doctor.md +100 -0
- package/skills/agent-workflow/commands/export-arq.md +77 -0
- package/skills/agent-workflow/commands/export-conclusions.md +78 -0
- package/skills/agent-workflow/commands/export-plan.md +74 -0
- package/skills/agent-workflow/commands/export-qa-note.md +30 -0
- package/skills/agent-workflow/commands/export-report.md +78 -0
- package/skills/agent-workflow/commands/export-requirement.md +30 -0
- package/skills/agent-workflow/commands/export-scripts.md +92 -0
- package/skills/agent-workflow/commands/export-tech-manuals.md +75 -0
- package/skills/agent-workflow/commands/export-tech-note.md +30 -0
- package/skills/agent-workflow/commands/hub-init.md +82 -0
- package/skills/agent-workflow/commands/migrate.md +56 -0
- package/skills/agent-workflow/commands/project-init.md +60 -0
- package/skills/agent-workflow/commands/resume.md +22 -0
- package/skills/agent-workflow/commands/rules.md +40 -0
- package/skills/agent-workflow/commands/session.md +35 -0
- package/skills/agent-workflow/doctrine/README.md +15 -0
- package/skills/agent-workflow/doctrine/compact/SKILL.md +145 -0
- package/skills/agent-workflow/doctrine/doctor/SKILL.md +86 -0
- package/skills/agent-workflow/doctrine/doctor/SKILL.md.tmp +0 -0
- package/skills/agent-workflow/doctrine/hub-init/SKILL.md +157 -0
- package/skills/agent-workflow/doctrine/hub-init/SKILL.md.tmp +0 -0
- package/skills/agent-workflow/doctrine/hub-init/references/multiroot-manual.md +51 -0
- package/skills/agent-workflow/doctrine/implement/SKILL.md +290 -0
- package/skills/agent-workflow/doctrine/implement/references/branch-verification.md +16 -0
- package/skills/agent-workflow/doctrine/implement/references/design-md-template.md +108 -0
- package/skills/agent-workflow/doctrine/implement/references/rollback-guide.md +81 -0
- package/skills/agent-workflow/doctrine/migrate/SKILL.md +281 -0
- package/skills/agent-workflow/doctrine/migrate/SKILL.md.tmp +0 -0
- package/skills/agent-workflow/doctrine/project-init/SKILL.md +100 -0
- package/skills/agent-workflow/doctrine/project-init/SKILL.md.tmp +0 -0
- package/skills/agent-workflow/doctrine/refactor/SKILL.md +208 -0
- package/skills/agent-workflow/doctrine/refactor/references/refactor-md-template.md +108 -0
- package/skills/agent-workflow/doctrine/refactor/references/strangler-checklist.md +116 -0
- package/skills/agent-workflow/doctrine/resume/SKILL.md +199 -0
- package/skills/agent-workflow/doctrine/rules/SKILL.md +224 -0
- package/skills/agent-workflow/doctrine/rules/SKILL.md.tmp +0 -0
- package/skills/agent-workflow/doctrine/session/SKILL.md +383 -0
- package/skills/agent-workflow/doctrine/session/references/auto-plan-rules.md +63 -0
- package/skills/agent-workflow/doctrine/session/references/backlog-template.md +95 -0
- package/skills/agent-workflow/doctrine/session/references/branch-verification.md +198 -0
- package/skills/agent-workflow/doctrine/session/references/commits-policy.md +111 -0
- package/skills/agent-workflow/doctrine/session/references/communication-style.md +50 -0
- package/skills/agent-workflow/doctrine/session/references/graduacion-routing.md +88 -0
- package/skills/agent-workflow/doctrine/session/references/lifecycle-deep.md +160 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/C1-specialty-selection.md +11 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/C2-cost-guard.md +14 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/M1-closure-commit-prompt.md +104 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/M10-next-step.md +17 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/M11-context.md +16 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/M2-branch-caso-A.md +14 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/M3-branch-caso-C.md +33 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/M4-cross-source-hard-gate.md +33 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/M5-modality-analyze.md +15 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/M6-phase-gate.md +31 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/M7-refactor-legacy-detected.md +28 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/M8-refactor-cleanup.md +16 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/M9-contract-review.md +39 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/S1-type-design.md +15 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/S2-topic-change-detection.md +14 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/S3-flow-detection.md +28 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/S4-resume.md +27 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/S5-post-compact.md +17 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/S6-scope.md +16 -0
- package/skills/agent-workflow/doctrine/session/references/prompts/S7-design-review.md +37 -0
- package/skills/agent-workflow/doctrine/session/references/prompts-catalog.md +210 -0
- package/skills/agent-workflow/doctrine/session/references/sandbox-readonly-rules.md +82 -0
- package/skills/agent-workflow/doctrine/session/references/specialty-decision-tree.md +56 -0
- package/skills/agent-workflow/doctrine/session/references/topic-change-rules.md +67 -0
- package/skills/agent-workflow/exports/README.md +15 -0
- package/skills/agent-workflow/exports/export-arq/SKILL.md +229 -0
- package/skills/agent-workflow/exports/export-arq/SKILL.md.tmp +0 -0
- package/skills/agent-workflow/exports/export-arq/references/lexico-tecnico.md +94 -0
- package/skills/agent-workflow/exports/export-arq/references/template-c4.md +293 -0
- package/skills/agent-workflow/exports/export-arq/references/template-plantuml.puml +77 -0
- package/skills/agent-workflow/exports/export-arq/references/template-structurizr.dsl +72 -0
- package/skills/agent-workflow/exports/export-arq/references/validations.md +231 -0
- package/skills/agent-workflow/exports/export-conclusions/SKILL.md +169 -0
- package/skills/agent-workflow/exports/export-conclusions/references/dedup-rules.md +154 -0
- package/skills/agent-workflow/exports/export-conclusions/references/template-conclusions.md +158 -0
- package/skills/agent-workflow/exports/export-plan/SKILL.md +225 -0
- package/skills/agent-workflow/exports/export-plan/references/state-transitions.md +141 -0
- package/skills/agent-workflow/exports/export-plan/references/template-plan.md +132 -0
- package/skills/agent-workflow/exports/export-qa-note/SKILL.md +31 -0
- package/skills/agent-workflow/exports/export-report/SKILL.md +262 -0
- package/skills/agent-workflow/exports/export-report/SKILL.md.tmp +0 -0
- package/skills/agent-workflow/exports/export-report/references/lexico.md +174 -0
- package/skills/agent-workflow/exports/export-report/references/template-a.md +95 -0
- package/skills/agent-workflow/exports/export-report/references/template-b.md +221 -0
- package/skills/agent-workflow/exports/export-report/references/template-c.md +180 -0
- package/skills/agent-workflow/exports/export-report/references/validations.md +255 -0
- package/skills/agent-workflow/exports/export-requirement/SKILL.md +31 -0
- package/skills/agent-workflow/exports/export-scripts/SKILL.md +324 -0
- package/skills/agent-workflow/exports/export-scripts/references/code-scan-recommendations.md +83 -0
- package/skills/agent-workflow/exports/export-scripts/references/deprecation-plan.md +80 -0
- package/skills/agent-workflow/exports/export-scripts/references/lexico-tecnico.md +80 -0
- package/skills/agent-workflow/exports/export-scripts/references/manifest-template.md +253 -0
- package/skills/agent-workflow/exports/export-scripts/references/readme-template.md +79 -0
- package/skills/agent-workflow/exports/export-scripts/references/theme-handling.md +168 -0
- package/skills/agent-workflow/exports/export-scripts/references/validations.md +242 -0
- package/skills/agent-workflow/exports/export-tech-manuals/SKILL.md +214 -0
- package/skills/agent-workflow/exports/export-tech-manuals/references/lexico-tecnico.md +97 -0
- package/skills/agent-workflow/exports/export-tech-manuals/references/template-index.md +123 -0
- package/skills/agent-workflow/exports/export-tech-manuals/references/template-manual.md +143 -0
- package/skills/agent-workflow/exports/export-tech-manuals/references/validations.md +211 -0
- package/skills/agent-workflow/exports/export-tech-note/SKILL.md +31 -0
- package/skills/agent-workflow/hooks/README.md +15 -0
- package/skills/agent-workflow/hooks/hooks.template.json +90 -0
- package/skills/agent-workflow/references/README.md +12 -0
- package/skills/agent-workflow/references/legacy-anchors.md +50 -0
- package/skills/agent-workflow/references/profile-parametrization.md +88 -0
- package/skills/agent-workflow/specialties/README.md +14 -0
- package/skills/agent-workflow/specialties/analyze-conclude/SKILL.md +175 -0
- package/skills/agent-workflow/specialties/analyze-conclude/references/incident-classification.md +61 -0
- package/skills/agent-workflow/specialties/analyze-investigate/SKILL.md +148 -0
- package/skills/agent-workflow/specialties/analyze-investigate/SKILL.md.tmp +0 -0
- package/skills/agent-workflow/specialties/analyze-investigate/references/cost-guard.md +85 -0
- package/skills/agent-workflow/specialties/analyze-synthesize/SKILL.md +127 -0
- package/skills/agent-workflow/specialties/design-brief/SKILL.md +90 -0
- package/skills/agent-workflow/specialties/design-deliver/SKILL.md +121 -0
- package/skills/agent-workflow/specialties/design-develop/SKILL.md +115 -0
- package/skills/agent-workflow/specialties/design-discover/SKILL.md +103 -0
- package/skills/agent-workflow/standards/README.md +12 -0
- package/skills/agent-workflow/standards/coding-standards/SKILL.md +102 -0
- package/skills/agent-workflow/standards/coding-standards/SKILL.md.tmp +0 -0
- package/skills/agent-workflow/standards/coding-standards/references/angular-typescript.md +266 -0
- package/skills/agent-workflow/standards/coding-standards/references/database-conventions.md +170 -0
- package/skills/agent-workflow/standards/coding-standards/references/fe-be-integration.md +300 -0
- package/skills/agent-workflow/standards/coding-standards/references/frontend-structure.md +182 -0
- package/skills/agent-workflow/standards/coding-standards/references/java-spring.md +244 -0
- package/skills/agent-workflow/standards/coding-standards/references/project-structure.md +197 -0
- package/skills/agent-workflow/standards/frontend-design/SKILL.md +62 -0
- package/skills/agent-workflow/standards/frontend-design/references/feedback-toasts-patterns.md +249 -0
- package/skills/agent-workflow/standards/frontend-design/references/form-patterns.md +278 -0
- package/skills/agent-workflow/standards/frontend-design/references/list-patterns.md +256 -0
- package/skills/agent-workflow/standards/frontend-design/references/modal-patterns.md +220 -0
- package/skills/agent-workflow/standards/frontend-design/references/navigation-patterns.md +224 -0
- package/skills/agent-workflow/standards/redaccion-simple/SKILL.md +128 -0
- package/skills/agent-workflow/standards/sql-rollback-generator/SKILL.md +197 -0
- package/skills/agent-workflow/standards/sql-rollback-generator/references/irreversible-checklist.md +161 -0
- package/skills/agent-workflow/standards/sql-rollback-generator/references/release-rollback.md +131 -0
- package/skills/agent-workflow/standards/sql-rollback-generator/references/rollback-patterns.md +255 -0
- package/skills/agent-workflow/standards/sql-script-organizer/SKILL.md +244 -0
- package/skills/agent-workflow/standards/sql-script-organizer/references/bundle-readme-template.md +82 -0
- package/skills/agent-workflow/standards/sql-script-organizer/references/categorization-rules.md +122 -0
- package/skills/agent-workflow/standards/sql-script-organizer/references/consolidation-cross-session.md +125 -0
- package/skills/agent-workflow/standards/sql-script-organizer/references/scripts-sql-format.md +140 -0
- package/skills/agent-workflow/standards/testing-strategy/SKILL.md +113 -0
- package/skills/agent-workflow/standards/testing-strategy/references/test-levels.md +255 -0
- package/skills/agent-workflow/workflows/README.md +12 -0
- package/skills/agent-workflow/workflows/analyze-workflow/SKILL.md +107 -0
- package/skills/agent-workflow/workflows/design-workflow/SKILL.md +100 -0
- package/skills/agent-workflow/workflows/dev-workflow/SKILL.md +195 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coding-standards
|
|
3
|
+
description: Estándares de código por stack (Java/Spring, Angular, Node) — fail-fast, logging por nivel, seguridad (no secrets, SQL parametrizado), naming descriptivo, manejo de errores, validación de input, reglas FE-BE (Sparse DTO unificado, PATCH semantics, sin fallbacks ocultos). Activar al implementar, revisar o refactorizar, o ante NL como buenas prácticas/código limpio/cómo valido este input. Referencia transversal sin dependencia de sesiones.
|
|
4
|
+
version: 0.4.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
> **Profile parametrization**: lee `mcp_databases[] + examples_path` de `profile.json` (resuelto vía cascade 5 capas). Ver [`references/profile-parametrization.md`](../../references/profile-parametrization.md) para el contrato completo y comportamiento por defecto cuando el profile está vacío.
|
|
8
|
+
|
|
9
|
+
# Coding Standards
|
|
10
|
+
|
|
11
|
+
Estándares de código aplicables durante la implementación. Consultar la referencia del stack correspondiente para detalles.
|
|
12
|
+
|
|
13
|
+
## Principios generales
|
|
14
|
+
|
|
15
|
+
- **SOLID** — Single Responsibility, Open/Closed, Liskov, Interface Segregation, Dependency Inversion
|
|
16
|
+
- **Fail fast** — Validar y retornar errores al inicio del método (early returns, evitar nesting)
|
|
17
|
+
- **Nombres descriptivos** — El código habla por sí mismo; comentarios solo para el "por qué"
|
|
18
|
+
- **Métodos pequeños** — Una sola responsabilidad por método/función
|
|
19
|
+
- **Composición sobre herencia**
|
|
20
|
+
- **Reutilización antes que duplicación (DRY)** — antes de crear un componente, función o clase nueva, revisar si ya existe en `shared/` (frontend) o el paquete `common/`/`util/` (backend). Si un patrón aparece 2-3 veces, proponer extracción. Aplica transversalmente; para detalles de componentes frontend y `shared/`, ver skill `frontend-design` + `references/frontend-structure.md`.
|
|
21
|
+
|
|
22
|
+
## Estándares por stack
|
|
23
|
+
|
|
24
|
+
### Java / Spring Boot
|
|
25
|
+
Constructor Injection (sin Field Injection), `@Transactional(readOnly=true)` para lecturas, Java records para DTOs Request/Response, Jakarta Validation para inputs. Ver `references/java-spring.md`.
|
|
26
|
+
|
|
27
|
+
### Angular / TypeScript
|
|
28
|
+
Constructor injection, NgModules, `async` pipe en templates, evitar `any`. Arquitectura `@data`/`@presentation`. Ver `references/angular-typescript.md` y `references/frontend-structure.md`.
|
|
29
|
+
|
|
30
|
+
## Integración FE-BE (flow=dev v2.6+)
|
|
31
|
+
|
|
32
|
+
Aplica a sesiones `flow=dev` con `## Type: feature|refactor` y a refactors guiados por `agent-workflow:refactor`. Reglas canónicas en `references/fe-be-integration.md`:
|
|
33
|
+
|
|
34
|
+
- **R1 — Sparse DTO unificado**: mismo DTO `<Feature>SaveRequest` para create + edit, todos los campos nullable. `null` = "no tocar".
|
|
35
|
+
- **R2 — PATCH para edit**: `@PatchMapping` en BE, `http.patch()` en FE. POST queda solo para create. PUT no se usa salvo replace total justificado.
|
|
36
|
+
- **R3 — FE envía solo cambios**: payload diff entre `formValue` y entidad original.
|
|
37
|
+
- **R4 — Sin fallbacks que oculten errores**: prohibido `catchError(() => of([]))` en FE; prohibido try/catch con fallback al método legacy en BE durante migraciones. Usar feature flags explícitas si se necesita rollout gradual.
|
|
38
|
+
- **R5 — Validación BE con Bean Validation + groups**: `@NotNull(groups = OnCreate.class)` para distinguir reglas POST vs PATCH cuando comparten DTO.
|
|
39
|
+
- **R6 — DB stub-first**: funciones/SP nuevas arrancan en Phase 0 devolviendo mock (`RETURN '[]'::jsonb`); implementación real recién en Phase 1/2.
|
|
40
|
+
|
|
41
|
+
## Seguridad
|
|
42
|
+
|
|
43
|
+
- **Nunca** exponer secrets, API keys o credenciales en código
|
|
44
|
+
- **Nunca** logear datos sensibles (contraseñas, tokens, datos personales)
|
|
45
|
+
- **Siempre** parametrizar queries SQL (nunca concatenar strings)
|
|
46
|
+
- **BD vía MCP** — `<mcp-cert>` (pruebas) y `<mcp-prod>` (producción) son READONLY. Modificaciones a BD solo mediante scripts SQL versionados en `docs/scripts/` del workspace de la fuente; el usuario es quien aplica el script (no el AI), nunca ejecución directa via MCP, Bash, psql ni cualquier otro canal. Excepción única: el usuario explícitamente pide "ejecutalo vos contra cert" — aún así, confirmación por bloque y no asumir autorización ampliada
|
|
47
|
+
|
|
48
|
+
## Manejo de errores HTTP
|
|
49
|
+
|
|
50
|
+
- **Nunca silenciar errores HTTP con `catchError(() => of([]))` ni equivalentes.** Los errores del backend se propagan al usuario vía toast/mensaje; solo así detectamos regresiones durante guardado, sincronizaciones y creaciones. Si hace falta lógica de reintento, usar operadores RxJS explícitos (`retry`, `retryWhen`), no silenciar.
|
|
51
|
+
|
|
52
|
+
## Logging
|
|
53
|
+
|
|
54
|
+
- `ERROR` — Fallos que requieren atención inmediata
|
|
55
|
+
- `WARN` — Situaciones inesperadas pero manejadas
|
|
56
|
+
- `INFO` — Eventos de negocio relevantes (inicio/fin de procesos)
|
|
57
|
+
- `DEBUG` — Detalle técnico para diagnóstico
|
|
58
|
+
|
|
59
|
+
## Git y ramas
|
|
60
|
+
|
|
61
|
+
Política de commits: ver `agent-workflow:commits-policy` (canónico).
|
|
62
|
+
|
|
63
|
+
### Estrategia de ramas
|
|
64
|
+
- **`certificacion`** — Rama principal/producción. Base para crear feature branches.
|
|
65
|
+
- **`desarrollo`** — Rama QA. Solo para probar features desplegados. Se sincroniza desde `certificacion`. No se usa como base.
|
|
66
|
+
- **Feature branches** — Siempre desde `certificacion`, PR hacia `certificacion`.
|
|
67
|
+
|
|
68
|
+
### Prefijo opcional Conventional Commits
|
|
69
|
+
|
|
70
|
+
Si la sesión/equipo lo prefiere, se puede combinar con el formato canónico:
|
|
71
|
+
|
|
72
|
+
- `feat(session<NNN>):` nueva funcionalidad
|
|
73
|
+
- `fix(session<NNN>):` corrección de bug
|
|
74
|
+
- `docs(session<NNN>):` documentación
|
|
75
|
+
- `chore(session<NNN>):` mantenimiento, dependencias
|
|
76
|
+
- `refactor(session<NNN>):` reestructuración sin cambio funcional
|
|
77
|
+
|
|
78
|
+
Ramas: `feature/`, `fix/`, `hotfix/` + descripción-kebab-case.
|
|
79
|
+
|
|
80
|
+
## Sandbox read-only
|
|
81
|
+
|
|
82
|
+
Canon universal en `../session/references/sandbox-readonly-rules.md`. Esta skill es read-only por diseño — carga estándares de código por stack y reglas FE-BE, no edita ni ejecuta nada.
|
|
83
|
+
|
|
84
|
+
En plan mode: describir en el plan file qué reglas se aplicarían al edit/refactor propuesto (fail-fast, FE-BE R1-R6, MCP READONLY, SQL parametrizado) y listar los refs relevantes (Java/Spring, Angular/TypeScript, fe-be-integration). NO ejecuta `Write`, `Edit`, `MultiEdit`, `Bash` con efectos colaterales, ni queries MCP mutantes.
|
|
85
|
+
|
|
86
|
+
Compatible con plan mode sin restricciones adicionales.
|
|
87
|
+
|
|
88
|
+
## Recursos adicionales
|
|
89
|
+
|
|
90
|
+
### Archivos de referencia
|
|
91
|
+
- **`references/fe-be-integration.md`** — Reglas FE-BE (Sparse DTO unificado, PATCH, sin fallbacks ocultos, Bean Validation con groups, DB stub-first). Aplica a `## Type: feature|refactor`.
|
|
92
|
+
- **`references/java-spring.md`** — Convenciones Java/Spring Boot (inyección, records, transacciones, validación) + PATCH+Sparse DTO con records.
|
|
93
|
+
- **`references/angular-typescript.md`** — Convenciones Angular/TypeScript (constructor injection, NgModules, ApiService) + PATCH client + interfaces sparse.
|
|
94
|
+
- **`references/frontend-structure.md`** — Arquitectura `@data`/`@presentation`, ApiService, interfaces espejeo backend, environments, build
|
|
95
|
+
- **`references/database-conventions.md`** — Nomenclatura BD: esquemas `esq_`, tablas `tb_`, columnas, sequences, funciones `fn_`/`sp_`, patrón maestra-detalle, auditoría, estilo de scripts SQL (transacciones, CTE, comentarios, idempotencia)
|
|
96
|
+
- **`references/project-structure.md`** — Estructura de paquetes backend, capas Entity→Repository→Service→Controller, wrappers `ReqBase`/`RespBase`, convención DTOs `P`/`R`/`Req`
|
|
97
|
+
- **`../frontend-design/`** — Principios de diseño UX para formularios de mantenimiento (agnóstico a framework) + reutilización de componentes y framework-first CSS. Consultar en paralelo con `angular-typescript.md` cuando el trabajo es frontend de mantenimiento.
|
|
98
|
+
|
|
99
|
+
### Skills de base de datos
|
|
100
|
+
Cuando el stack involucra BD y se escriben scripts SQL:
|
|
101
|
+
- **`sql-script-organizer`** — Organiza scripts en 4 categorías, aplica estilo y genera bundle listo para producción
|
|
102
|
+
- **`sql-rollback-generator`** — Genera rollback acoplado por script y bundle global de reversión
|
|
File without changes
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# Angular / TypeScript — Convenciones detalladas
|
|
2
|
+
|
|
3
|
+
## Inyección de servicios
|
|
4
|
+
|
|
5
|
+
Los proyectos actuales usan constructor injection con `private`:
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
@Injectable({ providedIn: 'root' })
|
|
9
|
+
export class SolicitudService {
|
|
10
|
+
constructor(private apiService: ApiService) {}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@Component({ ... })
|
|
14
|
+
export class MiComponente {
|
|
15
|
+
constructor(
|
|
16
|
+
private solicitudService: SolicitudService,
|
|
17
|
+
private router: Router
|
|
18
|
+
) {}
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
> **Nota**: `inject()` es válido en Angular 14+ y preferible en proyectos nuevos, pero seguir la convención del proyecto actual.
|
|
23
|
+
|
|
24
|
+
## NgModules
|
|
25
|
+
|
|
26
|
+
Los proyectos usan NgModules con routing modules separados:
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
@NgModule({
|
|
30
|
+
declarations: [AppComponent],
|
|
31
|
+
imports: [
|
|
32
|
+
BrowserModule,
|
|
33
|
+
AppRoutingModule,
|
|
34
|
+
ComponentsModule,
|
|
35
|
+
SharedModule,
|
|
36
|
+
ToastrModule.forRoot(),
|
|
37
|
+
BrowserAnimationsModule
|
|
38
|
+
],
|
|
39
|
+
bootstrap: [AppComponent]
|
|
40
|
+
})
|
|
41
|
+
export class AppModule {}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
> **Nota**: Standalone components son válidos en Angular 15+ pero los proyectos actuales no los usan. No migrar a standalone a menos que el usuario lo pida.
|
|
45
|
+
|
|
46
|
+
## Async pipe en templates
|
|
47
|
+
|
|
48
|
+
Preferir async pipe sobre subscribe manual para datos del template:
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
<div *ngIf="solicitudes$ | async as solicitudes">
|
|
52
|
+
<app-tabla [data]="solicitudes"></app-tabla>
|
|
53
|
+
</div>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
solicitudes$ = this.solicitudService.listar();
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Tipos estrictos
|
|
61
|
+
|
|
62
|
+
Evitar `any`. Usar interfaces en `@data/interfaces/`:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
// Interfaces que espejean el backend
|
|
66
|
+
export interface IResponsePayload<T> {
|
|
67
|
+
trace: Trace;
|
|
68
|
+
status: Status;
|
|
69
|
+
payload: T;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface ResponseDTO {
|
|
73
|
+
identificador: number;
|
|
74
|
+
cuerpo: string;
|
|
75
|
+
mensaje: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Incorrecto
|
|
79
|
+
const data: any = response.body; // NO
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Estructura de proyecto
|
|
83
|
+
|
|
84
|
+
Ver `references/frontend-structure.md` para la arquitectura completa `@data`/`@presentation`.
|
|
85
|
+
|
|
86
|
+
## PATCH + Sparse DTO unificado (qtc-dev v2.6+)
|
|
87
|
+
|
|
88
|
+
Para mantenimientos CRUD seguir las reglas de `references/fe-be-integration.md`:
|
|
89
|
+
|
|
90
|
+
- **Interface única** `<Feature>SaveRequest` para create + edit con campos opcionales (`?` o `| null`).
|
|
91
|
+
- **POST** envía todos los required cargados; **PATCH** envía solo los campos modificados (resto omitido).
|
|
92
|
+
- ApiService expone `patch<T>(url, body)` paralelo a `post<T>(url, body)`.
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
export interface CategoriaSaveRequest {
|
|
96
|
+
nombre?: string | null;
|
|
97
|
+
descripcion?: string | null;
|
|
98
|
+
activo?: boolean | null;
|
|
99
|
+
ordenVisual?: number | null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@Injectable({ providedIn: 'root' })
|
|
103
|
+
export class CategoriasService {
|
|
104
|
+
constructor(private apiService: ApiService) {}
|
|
105
|
+
|
|
106
|
+
create(req: CategoriaSaveRequest): Observable<IResponsePayload<CategoriaResponse>> {
|
|
107
|
+
return this.apiService.post(`${env.API_ADMIN}v1/categorias`, req);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
edit(id: number, cambios: CategoriaSaveRequest): Observable<IResponsePayload<CategoriaResponse>> {
|
|
111
|
+
return this.apiService.patch(`${env.API_ADMIN}v1/categorias/${id}`, cambios);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
En el componente de edición, construir el payload diff con solo los campos que cambiaron:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
guardar(): void {
|
|
120
|
+
const original = this.categoriaOriginal;
|
|
121
|
+
const form = this.form.value;
|
|
122
|
+
const cambios: CategoriaSaveRequest = {};
|
|
123
|
+
if (form.nombre !== original.nombre) cambios.nombre = form.nombre;
|
|
124
|
+
if (form.descripcion !== original.descripcion) cambios.descripcion = form.descripcion;
|
|
125
|
+
if (form.activo !== original.activo) cambios.activo = form.activo;
|
|
126
|
+
if (form.ordenVisual !== original.ordenVisual) cambios.ordenVisual = form.ordenVisual;
|
|
127
|
+
|
|
128
|
+
if (Object.keys(cambios).length === 0) return; // nada cambió
|
|
129
|
+
|
|
130
|
+
this.servicio.edit(original.id, cambios).subscribe({
|
|
131
|
+
next: (res) => this.toast.success('Guardado'),
|
|
132
|
+
error: (err) => this.errorHandler.handle(err) // R4 — no silenciar
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Anti-pattern**: enviar `form.value` completo en PATCH equivale a PUT y rompe la semántica sparse. Detalles + casos edge: `references/fe-be-integration.md`.
|
|
138
|
+
|
|
139
|
+
## Services y API
|
|
140
|
+
|
|
141
|
+
Todas las llamadas HTTP pasan por `ApiService` (wrapper central en `@data/services/`):
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
@Injectable({ providedIn: 'root' })
|
|
145
|
+
export class SolicitudService {
|
|
146
|
+
constructor(private apiService: ApiService) {}
|
|
147
|
+
|
|
148
|
+
generaSolicitud(solicitud: Solicitud): Observable<IResponsePayload<ResponseDTO>> {
|
|
149
|
+
const request = armarPayload<any>(solicitud);
|
|
150
|
+
const url = `${env.API_PRESTAMO}v1/solicitud`;
|
|
151
|
+
return this.apiService.post(url, request);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
getOfertas(idSolicitud: number): Observable<IResponsePayload<IPayloadListG<Oferta>>> {
|
|
155
|
+
const params = requestFilter({ idSolicitud });
|
|
156
|
+
const url = `${env.API_PRESTAMO}v1/solicitud/listar-ofertas?${params}`;
|
|
157
|
+
return this.apiService.get(url);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
No usar `HttpClient` directamente en services de presentación.
|
|
163
|
+
|
|
164
|
+
## Environments
|
|
165
|
+
|
|
166
|
+
URLs de API se configuran en environment files:
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
export const environment = {
|
|
170
|
+
production: false,
|
|
171
|
+
API_PRESTAMO: '',
|
|
172
|
+
API_SOLICITUD: '',
|
|
173
|
+
API_IDENTIDAD: '',
|
|
174
|
+
API_MOTOR: '',
|
|
175
|
+
};
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Archivos: `environment.ts`, `environment.dev.ts`, `environment.prod.ts`
|
|
179
|
+
|
|
180
|
+
## Build y verificación
|
|
181
|
+
|
|
182
|
+
- Build producción: `npm run build:prod` (equivale a `ng build -c=production`)
|
|
183
|
+
- Build desarrollo: `npm run build:dev` (equivale a `ng build -c=development`)
|
|
184
|
+
- Serve local: `npm run start:dev`
|
|
185
|
+
- Tests: `ng test --watch=false`
|
|
186
|
+
- Estilos: SCSS
|
|
187
|
+
- UI: Angular Material + Bootstrap
|
|
188
|
+
|
|
189
|
+
## Formularios reactivos
|
|
190
|
+
|
|
191
|
+
Patrones al trabajar con `FormGroup` / `FormControl` en mantenimientos CRUD. Para los principios de UX (cuándo usar switch vs checkbox, layout de cards, hints en combos), ver skill `frontend-design`.
|
|
192
|
+
|
|
193
|
+
### Combo dependiente con carga diferida
|
|
194
|
+
|
|
195
|
+
Cuando el valor del combo B depende del valor del combo A, suscribirse a `valueChanges` de A en `ngOnInit`:
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
this.formMantenimiento.get('idPadre')?.valueChanges.subscribe((valor) => {
|
|
199
|
+
this.formMantenimiento.get('idHijo')?.setValue('');
|
|
200
|
+
if (valor) {
|
|
201
|
+
this.listarHijos(String(valor));
|
|
202
|
+
} else {
|
|
203
|
+
this.lstHijos = [];
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Al editar, la **precarga inicial** debe setear padre e hijo **sin** disparar el listener (para no perder el valor de hijo que viene del backend):
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
this.formMantenimiento.patchValue({
|
|
212
|
+
idPadre: data.idPadre != null ? String(data.idPadre) : '',
|
|
213
|
+
idHijo: data.idHijo != null ? String(data.idHijo) : ''
|
|
214
|
+
}, { emitEvent: false });
|
|
215
|
+
|
|
216
|
+
if (data.idPadre) {
|
|
217
|
+
this.listarHijos(String(data.idPadre));
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Normalización de tipos en controles compartidos
|
|
222
|
+
|
|
223
|
+
Componentes custom tipo `search-select` o equivalentes suelen comparar opciones con `===`. Si las opciones tienen `value: "1"` (string) pero el DTO trae `1` (number), la opción **no matchea** y el combo queda vacío.
|
|
224
|
+
|
|
225
|
+
Regla: normalizar consistentemente en el `patchValue`. La forma que expone el componente UI manda:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
this.formMantenimiento.patchValue({
|
|
229
|
+
idRol: data.idRol != null ? String(data.idRol) : ''
|
|
230
|
+
}, { emitEvent: false });
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Aplicar la misma regla a todos los campos tipo id. Documentar la decisión si no es obvia.
|
|
234
|
+
|
|
235
|
+
### Sincronizaciones secuenciales con `concat`
|
|
236
|
+
|
|
237
|
+
Cuando N operaciones HTTP deben correr **en orden estricto** (evitar race conditions contra restricciones de unicidad del backend), usar `concat` de RxJS, no paralelo:
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
import { concat, of } from 'rxjs';
|
|
241
|
+
import { toArray } from 'rxjs/operators';
|
|
242
|
+
|
|
243
|
+
const ops = [
|
|
244
|
+
...paraDesactivar.map(r => this.servicio.desactivar(r.id)),
|
|
245
|
+
...(nuevoRequerido ? [this.servicio.asignar(nuevo)] : [])
|
|
246
|
+
];
|
|
247
|
+
return ops.length ? concat(...ops).pipe(toArray()) : of([]);
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Orden: primero desactivar los sobrantes, luego asignar el nuevo. Nunca paralelo en estos casos.
|
|
251
|
+
|
|
252
|
+
### Switch Bootstrap alineado
|
|
253
|
+
|
|
254
|
+
Patrón de clases para que el switch (3em×1.5em) quede alineado verticalmente con su label:
|
|
255
|
+
|
|
256
|
+
```html
|
|
257
|
+
<div class="form-switch d-flex align-items-center gap-2 ps-0 mb-0">
|
|
258
|
+
<input type="checkbox" class="form-check-input m-0" role="switch" id="mi-switch"
|
|
259
|
+
[checked]="activo" (change)="toggle($event)">
|
|
260
|
+
<label class="form-check-label mb-0" for="mi-switch">Texto del switch</label>
|
|
261
|
+
</div>
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Claves: `d-flex align-items-center gap-2` (alinea), `ps-0` (anula padding-left 1.5em default de `.form-check`), `input.m-0` y `label.mb-0` (anulan márgenes que desalinean con el switch grande).
|
|
265
|
+
|
|
266
|
+
Para la decisión UX **cuándo usar switch vs checkbox**, ver skill `frontend-design` (`references/form-patterns.md` §5).
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Convenciones de Base de Datos
|
|
2
|
+
|
|
3
|
+
PostgreSQL. Todas las convenciones son snake_case en español.
|
|
4
|
+
|
|
5
|
+
## Esquemas
|
|
6
|
+
|
|
7
|
+
Prefijo `esq_` + dominio: `esq_credito`, `esq_seguridad`, `esq_motor`, `esq_contabilidad`, `esq_liquidacion`, `esq_pago`, `esq_movimiento`, `esq_reportes`, `esq_audit`, `esq_sistema`, `esq_pos`, `esq_promocion`, `esq_planeamiento`, `esq_seguro`, `esq_reclamo`, `esq_request`, `esq_kashio`.
|
|
8
|
+
|
|
9
|
+
Cada microservicio trabaja con 1-2 esquemas. Siempre referenciar el schema explícitamente en queries nativas y en `@Table`.
|
|
10
|
+
|
|
11
|
+
## Tablas
|
|
12
|
+
|
|
13
|
+
- Prefijo `tb_` + entidad: `tb_credito`, `tb_cliente`, `tb_solicitud`
|
|
14
|
+
- Relaciones: `tb_pago_cronograma`, `tb_usuario_sucursal`
|
|
15
|
+
- Cabecera/detalle: sufijo `_cab` / `_det` → `tb_lote_cab`, `tb_lote_det`
|
|
16
|
+
|
|
17
|
+
## Columnas
|
|
18
|
+
|
|
19
|
+
### Primary Keys
|
|
20
|
+
`id_` + entidad → `id_credito`, `id_cliente`, `id_solicitud`
|
|
21
|
+
|
|
22
|
+
### Foreign Keys
|
|
23
|
+
Mismo nombre que la PK referenciada → `id_cliente` en `tb_credito` apunta a `tb_cliente.id_cliente`
|
|
24
|
+
|
|
25
|
+
### Fechas
|
|
26
|
+
`fecha_` + acción → `fecha_registro`, `fecha_modificacion`, `fecha_solicitud`, `fecha_aprobacion`, `fecha_prestamo`
|
|
27
|
+
|
|
28
|
+
### Montos
|
|
29
|
+
`monto_` + concepto → `monto_prestamo`, `monto_cuota`, `monto_pagar`, `monto_desembolsado`
|
|
30
|
+
|
|
31
|
+
### Estados
|
|
32
|
+
- `estado` → integer genérico (1=activo, 0=inactivo)
|
|
33
|
+
- `estado_proceso`, `estado_aprobacion` → integer, referencia a `tb_maestra_detalle.id_maestra_detalle`
|
|
34
|
+
|
|
35
|
+
### Flags
|
|
36
|
+
`flag_` + concepto → `flag_extorno` (integer 0/1)
|
|
37
|
+
|
|
38
|
+
### Tipos de datos
|
|
39
|
+
- `integer` → IDs, estados, flags
|
|
40
|
+
- `numeric` → montos, tasas, porcentajes
|
|
41
|
+
- `character varying` → textos
|
|
42
|
+
- `timestamp without time zone` → fechas con hora
|
|
43
|
+
- `date` → fechas sin hora
|
|
44
|
+
- `boolean` → flags en tablas más nuevas
|
|
45
|
+
|
|
46
|
+
## Auditoría
|
|
47
|
+
|
|
48
|
+
Campos presentes en casi todas las tablas (mapeados por la clase base `Auditoria` en Java):
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
estado integer NOT NULL -- 1=activo, 0=inactivo
|
|
52
|
+
usuario_registro varchar NOT NULL -- usuario que creó
|
|
53
|
+
fecha_registro timestamp NOT NULL -- cuándo se creó
|
|
54
|
+
usuario_modificacion varchar NULL -- usuario última modificación
|
|
55
|
+
fecha_modificacion timestamp NULL -- cuándo se modificó
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Sequences
|
|
59
|
+
|
|
60
|
+
Patrón: `seq_tb_[entidad]` en el mismo esquema → `esq_credito.seq_tb_credito`
|
|
61
|
+
|
|
62
|
+
## Índices
|
|
63
|
+
|
|
64
|
+
- PK: `pk_tb_[entidad]`
|
|
65
|
+
- Índices: `idx_tb_[entidad]_[columna]` o `idx_[entidad]_[columnas]`
|
|
66
|
+
|
|
67
|
+
## Funciones y Stored Procedures
|
|
68
|
+
|
|
69
|
+
- Funciones: `fn_` + verbo + sustantivo → `fn_obtener_segmento`, `fn_calcular_cuota_oferta`
|
|
70
|
+
- Procedures: `sp_` + verbo + sustantivo → `sp_genera_credito`, `sp_recalcula_credito`
|
|
71
|
+
- Versionado: sufijo `_v2`, `_v3` para versiones nuevas (no se borran las anteriores)
|
|
72
|
+
|
|
73
|
+
## Patrón Maestra-Detalle
|
|
74
|
+
|
|
75
|
+
`tb_maestra` + `tb_maestra_detalle` es el catálogo centralizado. Estados, tipos de documento, tipos de crédito, etc. se referencian vía `id_maestra_detalle`. El campo `codprog` identifica el grupo funcional dentro de la maestra.
|
|
76
|
+
|
|
77
|
+
Al crear nuevos estados o tipos, siempre usar `tb_maestra_detalle` en lugar de hardcodear valores.
|
|
78
|
+
|
|
79
|
+
## Estilo de scripts SQL
|
|
80
|
+
|
|
81
|
+
Reglas de escritura para todos los scripts SQL de la sesión. Aplicar desde el primer `.sql`.
|
|
82
|
+
|
|
83
|
+
### Transacciones
|
|
84
|
+
|
|
85
|
+
```sql
|
|
86
|
+
BEGIN;
|
|
87
|
+
-- cuerpo del script
|
|
88
|
+
COMMIT;
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`ROLLBACK` explícito en bloques con manejo de errores:
|
|
92
|
+
|
|
93
|
+
```sql
|
|
94
|
+
DO $$ BEGIN
|
|
95
|
+
-- lógica
|
|
96
|
+
EXCEPTION WHEN OTHERS THEN
|
|
97
|
+
RAISE;
|
|
98
|
+
END; $$;
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Idempotencia
|
|
102
|
+
|
|
103
|
+
| Operación | Forma idempotente |
|
|
104
|
+
|---|---|
|
|
105
|
+
| Crear tabla | `CREATE TABLE IF NOT EXISTS` |
|
|
106
|
+
| Eliminar objeto | `DROP ... IF EXISTS` |
|
|
107
|
+
| Crear/actualizar función | `CREATE OR REPLACE FUNCTION` |
|
|
108
|
+
| Insertar sin duplicar | `INSERT ... ON CONFLICT DO NOTHING` |
|
|
109
|
+
| Actualizar o insertar | `INSERT ... ON CONFLICT DO UPDATE` |
|
|
110
|
+
|
|
111
|
+
### CTEs sobre subqueries anidados
|
|
112
|
+
|
|
113
|
+
Usar CTE cuando hay ≥2 joins encadenados o cuando el mismo subquery se reutiliza:
|
|
114
|
+
|
|
115
|
+
```sql
|
|
116
|
+
-- Evitar:
|
|
117
|
+
SELECT * FROM tb_a WHERE id IN (SELECT id FROM tb_b WHERE id IN (SELECT id FROM tb_c));
|
|
118
|
+
|
|
119
|
+
-- Preferir:
|
|
120
|
+
WITH ids_c AS (SELECT id FROM tb_c),
|
|
121
|
+
ids_b AS (SELECT b.id FROM tb_b b JOIN ids_c c ON b.id = c.id)
|
|
122
|
+
SELECT * FROM tb_a a JOIN ids_b b ON a.id = b.id;
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Comentarios ligeros
|
|
126
|
+
|
|
127
|
+
Header canónico de 4 líneas (Script / Sesion / Objeto / Alcance) entre dos líneas de iguales:
|
|
128
|
+
|
|
129
|
+
```sql
|
|
130
|
+
-- ============================================================================
|
|
131
|
+
-- Script: 003-ddl-tb-solicitud-credito.sql
|
|
132
|
+
-- Sesion: s003
|
|
133
|
+
-- Objeto: Crear tabla de solicitudes de crédito.
|
|
134
|
+
-- Alcance: Esquema esq_credito; sin migración de datos.
|
|
135
|
+
-- ============================================================================
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Detalles, separadores entre secciones del cuerpo y la regla "CTEs sobre `DO`/`LOOP`" en `sql-script-organizer/SKILL.md#header-canónico`. Autor / Fecha / Motor / "Defensa futura" no van adentro del header — si el caso lo amerita, van como nota libre en una línea suelta debajo. Solo comentar el **por qué** cuando no es obvio. Nunca documentar qué hace una línea si el nombre ya lo dice.
|
|
139
|
+
|
|
140
|
+
### Sin funciones utilitarias efímeras
|
|
141
|
+
|
|
142
|
+
No crear `fn_*` o `sp_*` solo para reusar lógica dentro de un script. Usar CTE o repetir inline. Las `fn_`/`sp_` permanentes siguen la convención versionada (`_v2`, `_v3`).
|
|
143
|
+
|
|
144
|
+
### Esquema siempre explícito
|
|
145
|
+
|
|
146
|
+
```sql
|
|
147
|
+
-- Correcto:
|
|
148
|
+
SELECT * FROM esq_credito.tb_credito;
|
|
149
|
+
|
|
150
|
+
-- Incorrecto:
|
|
151
|
+
SELECT * FROM public.tb_credito;
|
|
152
|
+
SELECT * FROM tb_credito; -- sin schema
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Portabilidad
|
|
156
|
+
|
|
157
|
+
PostgreSQL es el motor primario. Si el destino es otro motor, indicarlo en `Objeto:` o como nota libre debajo del header (no como campo nuevo). Ver `sql-rollback-generator/references/rollback-patterns.md` para equivalencias Oracle/SQL Server.
|
|
158
|
+
|
|
159
|
+
### Seguridad en SQL dinámico
|
|
160
|
+
|
|
161
|
+
Nunca concatenar strings en SQL dinámico. Usar `$1`/`$2` en queries parametrizados, o `%L` con `format()` en PL/pgSQL.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
Para organización de scripts en sesiones de desarrollo: ver skill `sql-script-organizer`.
|
|
166
|
+
Para rollback de scripts: ver skill `sql-rollback-generator`.
|
|
167
|
+
|
|
168
|
+
## Scripts SQL
|
|
169
|
+
|
|
170
|
+
Modificaciones a BD solo mediante scripts SQL versionados en el proyecto. Nunca ejecutar INSERT/UPDATE/DELETE/DDL directamente contra la BD.
|