Convenciones de codigo
Reglas y patrones que todo el equipo (y todo agente IA) debe seguir en el ecosistema Zentto.
TypeScript
- Strict mode en todos los
tsconfig.json - Evitar
any— tipos concretos ounknowncon validación Zod - Interfaces en PascalCase sin prefijo
I:Product, noIProduct - Tipos exportados desde
types.tsen cada módulo
API (Express + Node.js)
- Cada módulo de dominio en
src/modules/<nombre>/con*.routes.ts+*.service.ts async/awaitsiempre; validación de entrada con Zod- Toda query pasa por funciones PL/pgSQL vía
callSp()/callSpOut()— cero SQL directo, siempre parametrizado - Errores:
catch (err) { next(err); }othrow new ApiError(status, code, msg). Prohibidores.status(500).json({ error: String(err) })(expone stack). Las routes viejas se migran al patrón en cada PR que las toque - Respuestas: listas
{ items, total }· escrituras{ ok, id?, message } - Routers nuevos se montan después de
app.use('/v1', requireJwt)
Frontend (React + Next.js)
- Componentes funcionales con hooks; UI de
@zentto/shared-ui - Tablas siempre con
<ZenttoDataGrid>— nunca<table>HTML (en apps no-ERP:<zentto-grid>) - Sin datos mock — catálogos y listas vienen de hooks de API
- Dashboards grandes: acordeones colapsables por sección
- Estilos con Tailwind; App Router de Next.js
- En
renderCelldel datagrid se devuelve string (no JSX) - Lógica de negocio en la API, no en la UI
SQL y base de datos (solo PostgreSQL)
- Funciones:
usp_[schema]_[entity]_[action]en snake_case exacto - Todo cambio de BD = migración goose + espejo en
sqlweb-pg/; cero T-SQL (ver PostgreSQL — motor único) - Fechas en UTC-0:
NOW() AT TIME ZONE 'UTC', columnas con sufijoUtc - Listados devuelven
"TotalCount"; escrituras("ok", "mensaje") - Bulk con parámetros
JSONB+jsonb_array_elements - Literales con cast (
::VARCHAR) y alias en columnas homónimas delRETURNS TABLE
Fechas y timezone
| Capa | Regla |
|---|---|
| Base de datos | Almacenar siempre en UTC-0 |
| API (middleware) | datetime.ts: entrada → UTC; salida → timezone de la empresa |
| Frontend | useTimezone() + formatDate()/formatDateTime() de shared-api |
Git y control de versiones
- Flujo obligatorio: rama desde
developer→ PR adeveloper→ CI verde → verificar en dev → PRdeveloper → main→ deploy a producción - Nunca commit directo a
mainnideveloper; nuncagit push --forceni saltarse hooks - Ramas:
feat/,fix/,chore/,refactor/,docs/+ descripción corta - Commits:
feat(modulo): descripcion— firmados con la identidad del equipo, sinCo-Authored-Byde agentes - Scan de seguridad local (gitleaks + trivy) antes de pushear
# Ejemplos de mensajes de commit
feat(inventario): agregar endpoint de lotes
fix(pos): corregir calculo de descuento por porcentaje
docs(tecnico): actualizar contrato OpenAPI Seguridad
- Secretos solo en Vault (AppRole + KV v2) — nunca versionados, nunca en Pulse/tickets; los servicios llevan solo el bootstrap AppRole en su env-file
- Auth por cookies httpOnly, nunca tokens en localStorage
- zentto-auth es el único broker de identidad: apps nuevas se federan contra
auth.zentto.net, no inventan su login - Passwords con bcrypt en Node, no en SQL
- Env vars leídas en tiempo de uso, no capturadas en constantes de módulo al importar (Vault carga async — una constante capturada al import queda undefined)
- Repos de código siempre privados; solo
*-releases,zentto-supporty.githubson públicos
Apps nuevas del ecosistema
- Patrón standalone: API Express + Next.js propios, nunca duplicar módulos del ERP
— la lógica compartida se consume como paquete
@zentto/module-* - Integración por API con contrato documentado + gate de CI
- Móvil: Capacitor para apps que envuelven una web responsive (patrón Pulse) o con bundle Ionic propio; Expo/RN solo en el monorepo zentto-mobile — verificar el stack del repo antes de asumir
- Todo repo con código lleva
security.ymlconsumiendo el reusable de la org (advisory,fail-on: noneal nacer)
Nomenclatura del proyecto
| Contexto | Nombre |
|---|---|
| Producto | Zentto |
| Scope npm | @zentto/* (registry privado Verdaccio npm.zentto.net / npmjs privado) |
| Store ecommerce | Zentto Store |
| Fiscal agent | Zentto Fiscal Agent |
| Reportería | Zentto Report Engine / Report Studio |
| Notificaciones | Zentto Notify |
| Work OS / scrum interno | Zentto Pulse (pulse.zentto.net) |
IMPORTANTE: toda la lógica de negocio vive en la API/servicios; el frontend solo
consume endpoints y presenta datos. Y toda feature nueva se documenta en
zentto-erp-docs en el mismo ciclo.