Files
telegram_new_socias/db_logic.md

221 lines
11 KiB
Markdown

# Sistema Integrado de Gestión (Vanity)
Este repositorio documenta la **especificación técnica completa** del ecosistema Vanity: infraestructura de datos, diccionarios de campos sin truncar, relaciones entre entidades y reglas de negocio que gobiernan los Bots, Recursos Humanos y el sistema de Asistencia.
El objetivo es servir como **fuente de verdad técnica** para desarrollo, mantenimiento, auditoría y escalamiento.
---
## 1. Arquitectura de Datos
El sistema se distribuye en **tres bases de datos** dentro del mismo servidor, permitiendo integridad referencial y consultas cruzadas controladas:
* **USERS_ALMA** → Seguridad, autenticación y control de acceso.
* **vanity_hr** → Gestión de personal, vacaciones, permisos y reglas laborales.
* **vanity_attendance** → Control de asistencia y programación de horarios.
---
## 2. Diccionario de Datos
### 2.1 Base de Datos: `vanity_hr`
#### Tabla: `data_empleadas` (Maestra — 44 campos)
Tabla central de Recursos Humanos. Contiene información contractual, personal, de contacto y metadatos de registro.
| Campo | Tipo | Key | Descripción |
| ------------------------- | ------------ | --- | ---------------------------------- |
| numero_empleado | varchar(15) | PRI | ID único de nómina |
| puesto | varchar(50) | | Cargo / Puesto |
| sucursal | varchar(50) | | Sucursal asignada |
| fecha_ingreso | date | | Fecha de alta (base de antigüedad) |
| estatus | varchar(15) | | Activo / Baja |
| nombre_completo | varchar(150) | | Nombre completo concatenado |
| nombre | varchar(50) | | Nombre(s) |
| nombre_preferido | varchar(50) | | Apodo o nombre de preferencia |
| apellido_paterno | varchar(50) | | Primer apellido |
| apellido_materno | varchar(50) | | Segundo apellido |
| fecha_nacimiento | date | | Fecha de nacimiento |
| lugar_nacimiento | varchar(50) | | Ciudad / Estado |
| rfc | varchar(13) | UNI | RFC |
| curp | varchar(18) | UNI | CURP |
| email | varchar(100) | | Correo electrónico |
| telefono_celular | varchar(15) | | Teléfono móvil |
| domicilio_calle | varchar(255) | | Calle |
| domicilio_numero_exterior | varchar(10) | | Número exterior |
| domicilio_numero_interior | varchar(10) | | Número interior |
| domicilio_numero_texto | varchar(50) | | Referencias |
| domicilio_colonia | varchar(255) | | Colonia |
| domicilio_codigo_postal | varchar(10) | | CP |
| domicilio_ciudad | varchar(100) | | Ciudad |
| domicilio_estado | varchar(50) | | Estado |
| domicilio_completo | varchar(255) | | Dirección formateada |
| emergencia_nombre | varchar(100) | | Contacto de emergencia |
| emergencia_telefono | varchar(15) | | Teléfono de emergencia |
| emergencia_parentesco | varchar(50) | | Parentesco |
| referencia_1_nombre | varchar(100) | | Referencia 1 |
| referencia_1_telefono | varchar(15) | | Teléfono ref 1 |
| referencia_1_tipo | varchar(20) | | Tipo ref 1 |
| referencia_2_nombre | varchar(100) | | Referencia 2 |
| referencia_2_telefono | varchar(15) | | Teléfono ref 2 |
| referencia_2_tipo | varchar(20) | | Tipo ref 2 |
| referencia_3_nombre | varchar(100) | | Referencia 3 |
| referencia_3_telefono | varchar(15) | | Teléfono ref 3 |
| referencia_3_tipo | varchar(20) | | Tipo ref 3 |
| origen_registro | varchar(50) | | Web / Bot |
| telegram_usuario | varchar(50) | | Username Telegram |
| telegram_chat_id | bigint | | ID de chat Telegram |
| bot_version | varchar(20) | | Versión del bot |
| fecha_registro | datetime | | Timestamp creación |
| tiempo_registro_minutos | int | | Duración del registro |
| fecha_procesamiento | datetime(3) | | Timestamp procesado |
---
#### Tabla: `vacaciones` (14 campos)
| Campo | Tipo | Key | Descripción |
| ------------------- | ----------- | --- | -------------------------------------------- |
| vacaciones_id | varchar(50) | PRI | ID de solicitud |
| numero_empleado | varchar(15) | MUL | Relación con empleada |
| tipo_solicitud | varchar(20) | | VACACIONES |
| estatus | enum | | pendiente / aprobado / rechazado / cancelado |
| fecha_inicio | date | | Inicio |
| fecha_fin | date | | Fin |
| dias_solicitados | int | | Total días |
| dias_habiles | int | | Días descontados |
| motivo | text | | Observaciones |
| con_goce_sueldo | tinyint(1) | | 1 = Sí |
| fecha_solicitud | datetime | | Creación |
| fecha_procesamiento | datetime(3) | | Cambio de estatus |
| origen | varchar(20) | | telegram_bot / web |
| afecta_nomina | tinyint(1) | | Impacto en pago |
---
#### Tabla: `permisos` (9 campos)
| Campo | Tipo | Key | Descripción |
| ------------------ | ----------- | --- | -------------------------------------------- |
| permiso_id | varchar(50) | PRI | ID de permiso |
| numero_empleado | varchar(15) | MUL | Relación RH |
| categoria | enum | | PERSONAL / MEDICO / OFICIAL / OTRO |
| estatus | enum | | pendiente / aprobado / rechazado / cancelado |
| fecha_inicio | date | | Fecha |
| horario_especifico | varchar(50) | | Rango horario |
| motivo | text | | Razón |
| con_goce_sueldo | tinyint(1) | | 0 / 1 |
| afecta_nomina | tinyint(1) | | Impacto |
#### Tabla: `horario_empleadas` (Diccionario de turnos)
| Campo | Tipo | Key | Descripción |
| -------------------- | ----------- | --- | ---------------- |
| id_horario | int | PRI | ID |
| numero_empleado | varchar(15) | MUL | Relación RH |
| telegram_id | bigint | | Llave webhook |
| dia_semana | varchar(20) | | monday, tuesday… |
| hora_entrada_teorica | time | | Entrada |
| hora_salida_teorica | time | | Salida |
*Los capturados desde `/horario` generan un registro por día mediante upsert (por `telegram_id` + `dia_semana`).*
---
### 2.2 Base de Datos: `vanity_attendance`
#### Tabla: `asistencia_registros` (9 campos)
| Campo | Tipo | Key | Descripción |
| ----------------- | ----------- | --- | -------------- |
| id_asistencia | int | PRI | Auto-increment |
| numero_empleado | varchar(15) | MUL | Relación RH |
| fecha | date | | Día |
| hora_entrada_real | time | | Entrada |
| hora_salida_real | time | | Salida |
| minutos_retraso | int | | Calculado |
| minutos_extra | int | | Excedente |
| sucursal_registro | varchar(50) | | Sucursal |
| telegram_id_usado | bigint | | ID Telegram |
---
### 2.3 Base de Datos: `USERS_ALMA`
#### Tabla: `users` (10 campos)
| Campo | Tipo | Key | Descripción |
| ----------- | ------------ | --- | ---------------------- |
| id | int | PRI | ID interno |
| username | varchar(50) | UNI | Usuario |
| role | enum | | admin / manager / user |
| first_name | varchar(100) | | Nombre |
| last_name | varchar(100) | | Apellidos |
| email | varchar(100) | UNI | Correo |
| cell_phone | varchar(20) | | Teléfono |
| telegram_id | varchar(50) | UNI | Auth bot |
| created_at | timestamp | | Creación |
| updated_at | timestamp | | Actualización |
---
## 3. Reglas de Negocio
### 3.1 Vacaciones
* **Antigüedad**: `FLOOR(DATEDIFF(fecha_inicio, fecha_ingreso) / 365.25)`
* **Ventana**: mínimo 12 días, máximo 45 días de anticipación
* **Validación**: no se permite solicitar periodos no cumplidos
### 3.2 Asistencia
* Identificación por `telegram_id`
* Cruce con `vanity_hr.horario_empleadas` según día
* Cálculo de retraso contra horario teórico
---
## 4. Integración Webhook (Horarios)
* **Identificación**: `body.telegram.user_id`
* **Operación**: Upsert por día
* **Persistencia**: `vanity_hr.horario_empleadas` (clave `telegram_id` + `dia_semana`)
* **Formato**: conversión de `10:00 AM``10:00:00`
---
## 5. Consultas Operativas
```sql
-- Saldo actual de vacaciones
SELECT * FROM vanity_hr.vista_saldos_vacaciones
WHERE numero_empleado = ?;
-- Última solicitud
SELECT * FROM vanity_hr.vacaciones
WHERE numero_empleado = ?
ORDER BY fecha_solicitud DESC
LIMIT 1;
-- Horario del día
SELECT hora_entrada_teorica
FROM vanity_hr.horario_empleadas
WHERE telegram_id = ? AND dia_semana = 'monday';
```
---
Este documento define el **contrato técnico** del sistema Vanity. Cualquier cambio estructural debe reflejarse aquí antes de pasar a producción.
---
# DB Implementation Tasks
1. **Create initialization script:** Write a SQL script to create the databases and tables.
2. **Modify `docker-compose.yml`:** Mount the initialization script.
3. **Update `.env.example`:** Add new environment variables.
4. **Implement SQLAlchemy models:** Create Python classes for each table.
5. **Refactor database logic:** Use the new models in the application.