# NOMENCLATURA UNIFICADA **Versión:** 1.0.0 **Fecha:** 2025-12-08 **Prioridad:** OBLIGATORIA - Seguir en todo el código **Sistema:** SIMCO + CAPVED --- ## PROPÓSITO Definir convenciones de nomenclatura consistentes para todas las capas del sistema. --- ## 1. DIRECTORIOS ### Regla General ``` lowercase-kebab-case ``` ### Ejemplos ``` ✅ CORRECTO ❌ INCORRECTO ─────────────────────────────────────── user-management/ UserManagement/ auth-module/ AuthModule/ shared-utils/ sharedUtils/ api-v1/ API_V1/ ``` ### Estructura por Capa ``` DATABASE: db/ ├── schemas/ │ ├── auth/ │ │ └── tables/ │ ├── core/ │ └── {domain}/ ├── seeds/ │ ├── dev/ │ └── prod/ └── scripts/ BACKEND (NestJS): src/ ├── modules/ │ └── {module-name}/ │ ├── entities/ │ ├── dto/ │ ├── services/ │ ├── controllers/ │ └── tests/ ├── shared/ │ ├── config/ │ ├── guards/ │ ├── decorators/ │ ├── filters/ │ ├── interceptors/ │ └── utils/ └── main.ts FRONTEND (React): src/ ├── apps/ │ └── {app-name}/ │ ├── components/ │ ├── pages/ │ └── hooks/ ├── shared/ │ ├── components/ │ │ ├── ui/ # Componentes base │ │ └── common/ # Componentes compartidos │ ├── hooks/ │ ├── stores/ │ ├── services/ │ ├── types/ │ └── utils/ └── main.tsx ``` --- ## 2. ARCHIVOS ### Por Capa | Capa | Patrón | Ejemplo | |------|--------|---------| | **DDL** | `{NN}-{nombre}.sql` | `01-users.sql`, `02-products.sql` | | **Seed** | `{NN}-{nombre}.sql` | `01-admin-user.sql` | | **Entity** | `{nombre}.entity.ts` | `user.entity.ts` | | **DTO Create** | `create-{nombre}.dto.ts` | `create-user.dto.ts` | | **DTO Update** | `update-{nombre}.dto.ts` | `update-user.dto.ts` | | **DTO Response** | `{nombre}-response.dto.ts` | `user-response.dto.ts` | | **DTO Query** | `{nombre}-query.dto.ts` | `user-query.dto.ts` | | **Service** | `{nombre}.service.ts` | `user.service.ts` | | **Controller** | `{nombre}.controller.ts` | `user.controller.ts` | | **Module** | `{nombre}.module.ts` | `user.module.ts` | | **Guard** | `{nombre}.guard.ts` | `jwt-auth.guard.ts` | | **Strategy** | `{nombre}.strategy.ts` | `jwt.strategy.ts` | | **Filter** | `{nombre}.filter.ts` | `http-exception.filter.ts` | | **Interceptor** | `{nombre}.interceptor.ts` | `logging.interceptor.ts` | | **Decorator** | `{nombre}.decorator.ts` | `current-user.decorator.ts` | | **Component** | `{Nombre}.tsx` | `UserCard.tsx` | | **Page** | `{Nombre}Page.tsx` | `UserProfilePage.tsx` | | **Hook** | `use{Nombre}.ts` | `useUser.ts`, `useAuth.ts` | | **Store** | `{nombre}.store.ts` | `auth.store.ts` | | **Service (FE)** | `{nombre}.service.ts` | `user.service.ts` | | **Types** | `{nombre}.types.ts` | `user.types.ts` | | **Test Unit** | `{nombre}.spec.ts` | `user.service.spec.ts` | | **Test E2E** | `{nombre}.e2e-spec.ts` | `user.e2e-spec.ts` | | **Test Component** | `{Nombre}.test.tsx` | `UserCard.test.tsx` | ### DDL - Orden de Archivos ```sql -- Usar prefijo numérico para orden de ejecución 01-users.sql -- Tablas base primero 02-roles.sql -- Tablas relacionadas 03-user-roles.sql -- Junction tables después 04-permissions.sql 10-products.sql -- Otro dominio, nuevo rango 11-categories.sql 12-product-categories.sql ``` --- ## 3. CLASES Y TIPOS ### TypeScript/NestJS | Tipo | Patrón | Ejemplo | |------|--------|---------| | **Entity** | `{Nombre}Entity` | `UserEntity` | | **DTO** | `{Accion}{Nombre}Dto` | `CreateUserDto` | | **Service** | `{Nombre}Service` | `UserService` | | **Controller** | `{Nombre}Controller` | `UserController` | | **Module** | `{Nombre}Module` | `UserModule` | | **Guard** | `{Nombre}Guard` | `JwtAuthGuard` | | **Strategy** | `{Nombre}Strategy` | `JwtStrategy` | | **Filter** | `{Nombre}Filter` | `HttpExceptionFilter` | | **Interceptor** | `{Nombre}Interceptor` | `LoggingInterceptor` | | **Enum** | `{Nombre}` | `UserStatus`, `OrderState` | | **Interface** | `{Nombre}` o `I{Nombre}` | `User`, `IUserService` | | **Type** | `{Nombre}` | `UserWithRoles`, `OrderSummary` | ### Ejemplos Completos ```typescript // Entity @Entity({ schema: 'auth', name: 'users' }) export class UserEntity { ... } // DTOs export class CreateUserDto { ... } export class UpdateUserDto extends PartialType(CreateUserDto) { ... } export class UserResponseDto { ... } export class UserQueryDto { ... } // Service @Injectable() export class UserService { ... } // Controller @Controller('users') export class UserController { ... } // Module @Module({}) export class UserModule { ... } // Enum export enum UserStatus { ACTIVE = 'active', INACTIVE = 'inactive', } // Interface export interface User { id: string; email: string; } // Type export type UserWithRoles = User & { roles: Role[] }; ``` --- ## 4. FUNCIONES Y MÉTODOS ### Verbos Estándar | Operación | Verbo | Ejemplo | |-----------|-------|---------| | Obtener uno | `find`, `get` | `findById()`, `getUser()` | | Obtener muchos | `findAll`, `list` | `findAll()`, `listUsers()` | | Crear | `create` | `create()`, `createUser()` | | Actualizar | `update` | `update()`, `updateUser()` | | Eliminar | `remove`, `delete` | `remove()`, `deleteUser()` | | Buscar | `search` | `search()`, `searchUsers()` | | Verificar | `is`, `has`, `can` | `isActive()`, `hasPermission()` | | Contar | `count` | `count()`, `countActive()` | | Validar | `validate` | `validateEmail()` | | Formatear | `format` | `formatDate()`, `formatPrice()` | | Parsear | `parse` | `parseJson()`, `parseDate()` | | Convertir | `to`, `from` | `toDto()`, `fromEntity()` | ### Ejemplos por Capa ```typescript // Service - CRUD estándar class UserService { async create(dto: CreateUserDto): Promise { ... } async findAll(query: UserQueryDto): Promise { ... } async findById(id: string): Promise { ... } async findByEmail(email: string): Promise { ... } async update(id: string, dto: UpdateUserDto): Promise { ... } async remove(id: string): Promise { ... } // Métodos adicionales async activate(id: string): Promise { ... } async deactivate(id: string): Promise { ... } async assignRole(userId: string, roleId: string): Promise { ... } async hasPermission(userId: string, permission: string): Promise { ... } } // Controller - Endpoints REST class UserController { @Get() async findAll(@Query() query: UserQueryDto) { ... } @Get(':id') async findOne(@Param('id') id: string) { ... } @Post() async create(@Body() dto: CreateUserDto) { ... } @Put(':id') async update(@Param('id') id: string, @Body() dto: UpdateUserDto) { ... } @Delete(':id') async remove(@Param('id') id: string) { ... } } // Hook (Frontend) function useUsers() { return useQuery({ ... }); } function useUser(id: string) { return useQuery({ ... }); } function useCreateUser() { return useMutation({ ... }); } function useUpdateUser() { return useMutation({ ... }); } function useDeleteUser() { return useMutation({ ... }); } ``` --- ## 5. VARIABLES Y CONSTANTES ### Variables ```typescript // camelCase const userId = '123'; const isActive = true; const userCount = 10; const createdAt = new Date(); // Arrays en plural const users = []; const activeUsers = []; const userIds = ['1', '2', '3']; // Maps/Records con sufijo const userMap = new Map(); const roleById = {}; // Record ``` ### Constantes ```typescript // UPPER_SNAKE_CASE para constantes const MAX_LOGIN_ATTEMPTS = 5; const DEFAULT_PAGE_SIZE = 20; const API_VERSION = 'v1'; const JWT_EXPIRATION = '1d'; // Constantes de configuración const CONFIG = { MAX_FILE_SIZE: 10 * 1024 * 1024, // 10MB ALLOWED_EXTENSIONS: ['.jpg', '.png', '.pdf'], RATE_LIMIT: 100, }; // Rutas/Paths const ROUTES = { HOME: '/', LOGIN: '/auth/login', DASHBOARD: '/dashboard', USER_PROFILE: '/users/:id', }; ``` --- ## 6. ENUMS ### Definición ```typescript // PascalCase para nombre // Valores en minúsculas (para BD) o UPPER_CASE (para constantes) // Opción 1: Valores string (recomendado para BD) export enum UserStatus { ACTIVE = 'active', INACTIVE = 'inactive', SUSPENDED = 'suspended', DELETED = 'deleted', } // Opción 2: Valores UPPER_CASE (para constantes internas) export enum HttpMethod { GET = 'GET', POST = 'POST', PUT = 'PUT', DELETE = 'DELETE', } // Opción 3: Numéricos (solo si necesario) export enum Priority { LOW = 1, MEDIUM = 2, HIGH = 3, CRITICAL = 4, } ``` ### Uso ```typescript // Entity @Column({ type: 'enum', enum: UserStatus, default: UserStatus.ACTIVE }) status: UserStatus; // Validación DTO @IsEnum(UserStatus) status: UserStatus; // Frontend const statusLabel = { [UserStatus.ACTIVE]: 'Activo', [UserStatus.INACTIVE]: 'Inactivo', [UserStatus.SUSPENDED]: 'Suspendido', }; ``` --- ## 7. DATABASE (SQL) ### Tablas y Columnas ```sql -- Tablas: snake_case, plural CREATE TABLE users ( ... ); CREATE TABLE product_categories ( ... ); CREATE TABLE user_login_attempts ( ... ); -- Columnas: snake_case CREATE TABLE users ( id UUID PRIMARY KEY, first_name VARCHAR(100), last_name VARCHAR(100), email VARCHAR(255), is_active BOOLEAN, created_at TIMESTAMP, updated_at TIMESTAMP, deleted_at TIMESTAMP ); -- Foreign Keys: {tabla_singular}_id CREATE TABLE orders ( user_id UUID REFERENCES users(id), product_id UUID REFERENCES products(id) ); -- Junction Tables: {tabla1}_{tabla2} (orden alfabético) CREATE TABLE role_users ( ... ); -- ❌ CREATE TABLE user_roles ( ... ); -- ✅ (u antes de r) ``` ### Índices y Constraints ```sql -- Índices: idx_{tabla}_{columnas} CREATE INDEX idx_users_email ON users(email); CREATE INDEX idx_orders_user_created ON orders(user_id, created_at); -- Unique: uq_{tabla}_{columnas} ALTER TABLE users ADD CONSTRAINT uq_users_email UNIQUE (email); -- Foreign Key: fk_{tabla}_{referencia} ALTER TABLE orders ADD CONSTRAINT fk_orders_user FOREIGN KEY (user_id) REFERENCES users(id); -- Check: chk_{tabla}_{descripcion} ALTER TABLE users ADD CONSTRAINT chk_users_status CHECK (status IN ('active', 'inactive')); ``` --- ## 8. API ENDPOINTS ### Convenciones REST ``` GET /api/v1/users # Listar GET /api/v1/users/:id # Obtener uno POST /api/v1/users # Crear PUT /api/v1/users/:id # Actualizar completo PATCH /api/v1/users/:id # Actualizar parcial DELETE /api/v1/users/:id # Eliminar # Recursos anidados GET /api/v1/users/:id/orders # Órdenes del usuario POST /api/v1/users/:id/orders # Crear orden para usuario # Acciones especiales POST /api/v1/users/:id/activate # Acción POST /api/v1/users/:id/deactivate # Acción POST /api/v1/auth/login # Auth POST /api/v1/auth/logout # Auth POST /api/v1/auth/refresh # Auth ``` ### URL Patterns ``` ✅ CORRECTO ❌ INCORRECTO ────────────────────────────────────────── /users /user # Plural /users/:id /users/get/:id # Verbo innecesario /users/:id/orders /getUserOrders # Snake case, verbo /auth/login /doLogin # Verbo innecesario ``` --- ## 9. COMPONENTES REACT ### Nombres ```typescript // PascalCase para componentes const UserCard = () => { ... }; const ProductList = () => { ... }; const LoginForm = () => { ... }; // Sufijos descriptivos const UserProfilePage = () => { ... }; // Página completa const UserEditModal = () => { ... }; // Modal const UserDeleteDialog = () => { ... }; // Dialog de confirmación const UserAvatarSkeleton = () => { ... }; // Loading skeleton ``` ### Props ```typescript // Interface con Props suffix interface UserCardProps { user: User; onEdit?: (user: User) => void; onDelete?: (id: string) => void; isLoading?: boolean; } const UserCard: React.FC = ({ user, onEdit, onDelete, isLoading = false, }) => { ... }; ``` --- ## 10. CHECKLIST DE NOMENCLATURA ``` Antes de crear archivo: [ ] Nombre en formato correcto para su tipo [ ] Directorio correcto según capa [ ] Sin duplicados en nombre Antes de crear clase/tipo: [ ] PascalCase [ ] Sufijo correcto (Entity, Dto, Service, etc.) [ ] Nombre descriptivo Antes de crear función: [ ] camelCase [ ] Verbo al inicio [ ] Nombre describe qué hace Antes de crear variable: [ ] camelCase [ ] Nombre descriptivo [ ] Plural para arrays Antes de crear endpoint: [ ] Recurso en plural [ ] Sin verbos en URL [ ] Estructura RESTful ``` --- **Versión:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** Guía de Nomenclatura