feat: Implement client and provider management dashboard
- Added data table component for displaying clients and providers with infinite scroll functionality. - Created dropdown actions for each client/provider including copy ID, copy RFC, view details, edit, toggle status, and delete. - Implemented dialogs for creating, editing, viewing details, and deleting clients/providers. - Integrated API calls for fetching, creating, editing, deleting, and toggling status of clients/providers. - Enhanced error handling and loading states for better user experience. - Updated server-side logic to handle pagination and company selection for client/provider data retrieval.
This commit is contained in:
@@ -4,11 +4,12 @@
|
||||
1. [Visión General](#visión-general)
|
||||
2. [Stack Tecnológico](#stack-tecnológico)
|
||||
3. [Arquitectura del Sistema](#arquitectura-del-sistema)
|
||||
4. [Estructura del Proyecto](#estructura-del-proyecto)
|
||||
5. [Flujos Principales](#flujos-principales)
|
||||
6. [Seguridad](#seguridad)
|
||||
7. [Base de Datos](#base-de-datos)
|
||||
8. [API Reference](#api-reference)
|
||||
4. [Arquitectura de Schemas y Módulos](#arquitectura-de-schemas-y-módulos)
|
||||
5. [Estructura del Proyecto](#estructura-del-proyecto)
|
||||
6. [Flujos Principales](#flujos-principales)
|
||||
7. [Seguridad](#seguridad)
|
||||
8. [Base de Datos](#base-de-datos)
|
||||
9. [API Reference](#api-reference)
|
||||
|
||||
---
|
||||
|
||||
@@ -78,12 +79,12 @@ Anexo76 es una aplicación SaaS multi-tenant para gestión de comercio exterior
|
||||
│
|
||||
┌───────▼──────────────────────────┐
|
||||
│ DATABASE LAYER (Multi-tenant) │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────────┐ │
|
||||
│ │ Core DB │ │ Tenant 1 DB │ │
|
||||
│ │ (shared) │ │ (dedicated) │ │
|
||||
│ └──────────┘ └──────────────┘ │
|
||||
└───────────────────────────────────┘
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────────┐ │
|
||||
│ │ Core DB │ │ Tenant 1 DB │ │
|
||||
│ │ (shared) │ │ (dedicated) │ │
|
||||
│ └──────────┘ └──────────────┘ │
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Estructura Modular (por módulo)
|
||||
@@ -123,6 +124,104 @@ modules/{module_name}/
|
||||
|
||||
---
|
||||
|
||||
## Arquitectura de Schemas y Módulos
|
||||
|
||||
### Estructura de Schemas en Base de Datos
|
||||
|
||||
La aplicación utiliza una arquitectura de schemas para organizar lógicamente las tablas según su funcionalidad y alcance:
|
||||
|
||||
#### **Schema `a24` (Anexo 24)**
|
||||
Contiene todas las tablas relacionadas con el **Anexo 24 del SAT** (control de inventarios para empresas IMMEX):
|
||||
- Gestión de inventarios
|
||||
- Control de entradas y salidas de mercancías
|
||||
- Reportes de existencias
|
||||
- Cumplimiento de obligaciones fiscales del Anexo 24
|
||||
|
||||
#### **Schema `a76` (Anexo 76)**
|
||||
Contiene todas las tablas relacionadas con el **Anexo 76 del SAT** (comercio exterior):
|
||||
- Pedimentos aduanales
|
||||
- Facturas de importación/exportación
|
||||
- Documentación de comercio exterior
|
||||
- Cumplimiento normativo de comercio exterior
|
||||
|
||||
#### **Schema `public` (Catálogos Fijos)**
|
||||
Contiene **catálogos compartidos** y datos de referencia que no cambian frecuentemente:
|
||||
- Catálogos del SAT (tipos de material, unidades de medida, etc.)
|
||||
- Códigos de país
|
||||
- Catálogos de aduanas
|
||||
- Tipos de documento
|
||||
- Datos maestros compartidos entre módulos
|
||||
|
||||
### Convención de Prefijos de Tablas
|
||||
|
||||
Para mantener claridad y trazabilidad, las tablas utilizan prefijos que identifican su módulo funcional:
|
||||
|
||||
#### **Prefijo `inv_` (Inventarios)**
|
||||
Tablas relacionadas con el **control de inventarios**:
|
||||
- `inv_products`: Productos en inventario
|
||||
- `inv_movements`: Movimientos de entrada/salida
|
||||
- `inv_warehouses`: Almacenes
|
||||
- `inv_balances`: Saldos de inventario
|
||||
|
||||
**Nota histórica**: Anteriormente se utilizaba el prefijo `s` (SCAII - Sistema de aduanas e Inventarios).
|
||||
|
||||
#### **Prefijo `fa_` (Fixed Assets / Activos Fijos)**
|
||||
Tablas relacionadas con la **gestión de activos fijos**:
|
||||
- `fa_assets`: Registro de activos fijos
|
||||
- `fa_depreciation`: Depreciación de activos
|
||||
- `fa_maintenance`: Mantenimiento de activos
|
||||
- `fa_transfers`: Transferencias de activos
|
||||
|
||||
**Nota histórica**: Anteriormente se utilizaba el prefijo `q` (SCAF - Sistema de Control de Activos Fijos).
|
||||
|
||||
### Diagrama de Arquitectura de Schemas
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ DATABASE: anexo76_db │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌────────────────┐ ┌────────────────┐ ┌───────────────┐ │
|
||||
│ │ Schema: a24 │ │ Schema: a76 │ │Schema: public │ │
|
||||
│ │ (Anexo 24) │ │ (Anexo 76) │ │ (Catálogos) │ │
|
||||
│ ├────────────────┤ ├────────────────┤ ├───────────────┤ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ inv_products │ │ pedimentos │ │ material_types│ │
|
||||
│ │ inv_movements │ │ facturas │ │ uom_codes │ │
|
||||
│ │ inv_warehouses │ │ customs_docs │ │ countries │ │
|
||||
│ │ inv_balances │ │ export_ops │ │ customs_list │ │
|
||||
│ │ │ │ │ │ document_types│ │
|
||||
│ │ fa_assets │ │ │ │ │ │
|
||||
│ │ fa_depreciation│ │ │ │ │ │
|
||||
│ │ fa_maintenance │ │ │ │ │ │
|
||||
│ │ fa_transfers │ │ │ │ │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ └────────────────┘ └────────────────┘ └───────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Ventajas de esta Arquitectura
|
||||
|
||||
1. **Separación Lógica**: Cada schema representa un dominio específico del negocio
|
||||
2. **Escalabilidad**: Facilita la adición de nuevos módulos sin afectar los existentes
|
||||
3. **Seguridad**: Permite aplicar permisos a nivel de schema
|
||||
4. **Mantenibilidad**: Código y migraciones organizados por dominio
|
||||
5. **Claridad**: Los prefijos hacen evidente la funcionalidad de cada tabla
|
||||
6. **Migración Gradual**: Permite actualizar sistemas legados (SCAII/SCAF) sin interrupciones
|
||||
|
||||
### Mapeo de Sistemas Legados
|
||||
|
||||
| Sistema Legacy | Prefijo Antiguo | Sistema Nuevo | Prefijo Nuevo | Schema |
|
||||
|----------------------|-----------------|-------------------|---------------|----------|
|
||||
| SCAII (Inventarios) | `s` | Inventarios | `inv_` | `a24` |
|
||||
| SCAF (Activos Fijos) | `q` | Fixed Assets | `fa_` | `a24` |
|
||||
| Winsaii (Pedimentos) | `w` | - | - | `a22` |
|
||||
| - | `g` | Comercio Exterior | - | `a76` |
|
||||
| - | `g` | Catálogos SAT | - | `public` |
|
||||
|
||||
---
|
||||
|
||||
## Estructura del Proyecto
|
||||
|
||||
```
|
||||
@@ -143,11 +242,25 @@ anexo76/
|
||||
│ └── api/
|
||||
│ └── v1/
|
||||
│ ├── router.py # Router principal v1
|
||||
│ └── modules/ # Módulos de negocio
|
||||
│ ├── auth/ # Autenticación
|
||||
│ ├── tenants/ # Gestión de tenants
|
||||
│ ├── licenses/ # Control de licencias
|
||||
│ └── ... # Futuros módulos
|
||||
│ ├── common/ # Utilidades compartidas
|
||||
│ │ ├── base_models.py
|
||||
│ │ ├── crud_routes.py
|
||||
│ │ ├── dto_mixins.py
|
||||
│ │ └── tenant_crud_routes.py
|
||||
│ │
|
||||
│ └── modules/ # Módulos de negocio por schema
|
||||
│ ├── a24/ # Módulo Anexo 24 (Inventarios)
|
||||
│ │ ├── inventarios/
|
||||
│ │ └── activos_fijos/
|
||||
│ │
|
||||
│ ├── a76/ # Módulo Anexo 76 (Comercio Exterior)
|
||||
│ │ ├── pedimentos/
|
||||
│ │ └── facturas/
|
||||
│ │
|
||||
│ └── public/ # Catálogos compartidos
|
||||
│ ├── material_types/
|
||||
│ ├── uom_codes/
|
||||
│ └── countries/
|
||||
│
|
||||
├── frontend/
|
||||
│ ├── src/
|
||||
|
||||
@@ -2,6 +2,15 @@
|
||||
|
||||
Esta guía te ayudará a configurar Keycloak para usar con Anexo76.
|
||||
|
||||
# Script auto initialize
|
||||
|
||||
Te genera toda la configruracion inicial de keycloack que se ve en este documento,
|
||||
aparte de esto te genera un primer usuario configurado con su tenant y una company
|
||||
|
||||
```
|
||||
scripts/init_first_time.sh
|
||||
```
|
||||
|
||||
## 1. Acceder a Keycloak Admin Console
|
||||
|
||||
1. Abrir http://localhost:8080
|
||||
@@ -11,6 +20,7 @@ Esta guía te ayudará a configurar Keycloak para usar con Anexo76.
|
||||
## 2. Configurar Cliente Backend
|
||||
|
||||
### Crear Cliente Backend
|
||||
|
||||
1. En el menú izquierdo, ir a **Clients**
|
||||
2. Clic en **Create client**
|
||||
3. Configurar:
|
||||
@@ -29,6 +39,7 @@ Esta guía te ayudará a configurar Keycloak para usar con Anexo76.
|
||||
- Clic en **Save**
|
||||
|
||||
### Obtener Client Secret
|
||||
|
||||
1. Ir a la pestaña **Credentials**
|
||||
2. Copiar el **Client secret**
|
||||
3. Agregar al archivo `backend/.env`:
|
||||
@@ -39,6 +50,7 @@ Esta guía te ayudará a configurar Keycloak para usar con Anexo76.
|
||||
## 3. Configurar Cliente Frontend
|
||||
|
||||
### Crear Cliente Frontend
|
||||
|
||||
1. En **Clients**, clic en **Create client**
|
||||
2. Configurar:
|
||||
- **Client ID**: `anexo76-frontend`
|
||||
@@ -51,13 +63,13 @@ Esta guía te ayudará a configurar Keycloak para usar con Anexo76.
|
||||
- Clic en **Next**
|
||||
4. En "Login settings":
|
||||
- **Root URL**: `http://localhost:5173`
|
||||
- **Valid redirect URIs**:
|
||||
- **Valid redirect URIs**:
|
||||
- `http://localhost:5173/*`
|
||||
- `http://localhost:3000/*`
|
||||
- **Valid post logout redirect URIs**:
|
||||
- **Valid post logout redirect URIs**:
|
||||
- `http://localhost:5173/*`
|
||||
- `http://localhost:3000/*`
|
||||
- **Web origins**:
|
||||
- **Web origins**:
|
||||
- `http://localhost:5173`
|
||||
- `http://localhost:3000`
|
||||
- Clic en **Save**
|
||||
@@ -65,6 +77,7 @@ Esta guía te ayudará a configurar Keycloak para usar con Anexo76.
|
||||
## 4. Crear Usuario de Prueba
|
||||
|
||||
### Crear Usuario
|
||||
|
||||
1. En el menú izquierdo, ir a **Users**
|
||||
2. Clic en **Add user**
|
||||
3. Configurar:
|
||||
@@ -76,6 +89,7 @@ Esta guía te ayudará a configurar Keycloak para usar con Anexo76.
|
||||
- Clic en **Create**
|
||||
|
||||
### Establecer Contraseña
|
||||
|
||||
1. Ir a la pestaña **Credentials**
|
||||
2. Clic en **Set password**
|
||||
3. Configurar:
|
||||
@@ -85,6 +99,7 @@ Esta guía te ayudará a configurar Keycloak para usar con Anexo76.
|
||||
4. Clic en **Save**
|
||||
|
||||
### Agregar Atributo tenant_id
|
||||
|
||||
1. En el mismo usuario, ir a la pestaña **Attributes**
|
||||
2. Clic en **Add an attribute**
|
||||
3. Configurar:
|
||||
@@ -93,6 +108,7 @@ Esta guía te ayudará a configurar Keycloak para usar con Anexo76.
|
||||
4. Clic en **Save**
|
||||
|
||||
### Asignar Roles
|
||||
|
||||
1. Ir a la pestaña **Role mappings**
|
||||
2. En "Available roles", buscar y asignar:
|
||||
- `admin` (si existe)
|
||||
@@ -126,6 +142,7 @@ Repetir para el cliente `anexo76-frontend` si es necesario.
|
||||
## 6. Verificar Configuración
|
||||
|
||||
### Probar desde el Frontend
|
||||
|
||||
1. Abrir http://localhost:5173
|
||||
2. Hacer clic en "Iniciar Sesión"
|
||||
3. Ingresar credenciales:
|
||||
@@ -134,6 +151,7 @@ Repetir para el cliente `anexo76-frontend` si es necesario.
|
||||
4. Deberías ver el dashboard con información del usuario y licencia
|
||||
|
||||
### Probar desde el API
|
||||
|
||||
```bash
|
||||
# Obtener token
|
||||
curl -X POST http://localhost:8080/realms/master/protocol/openid-connect/token \
|
||||
@@ -152,11 +170,13 @@ curl -X GET http://localhost:8000/v1/auth/me \
|
||||
## 7. Configuración Adicional (Opcional)
|
||||
|
||||
### Personalizar Tema de Login
|
||||
|
||||
1. Ir a **Realm settings** → **Themes**
|
||||
2. Seleccionar tema de login deseado
|
||||
3. Guardar cambios
|
||||
|
||||
### Configurar Timeout de Sesión
|
||||
|
||||
1. Ir a **Realm settings** → **Sessions**
|
||||
2. Ajustar:
|
||||
- **SSO Session Idle**: Tiempo de inactividad antes de expirar (ej: 30 minutos)
|
||||
@@ -164,6 +184,7 @@ curl -X GET http://localhost:8000/v1/auth/me \
|
||||
3. Guardar cambios
|
||||
|
||||
### Habilitar Registro de Usuarios (Opcional)
|
||||
|
||||
1. Ir a **Realm settings** → **Login**
|
||||
2. Activar **User registration**
|
||||
3. Guardar cambios
|
||||
@@ -171,20 +192,24 @@ curl -X GET http://localhost:8000/v1/auth/me \
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "Invalid redirect URI"
|
||||
|
||||
- Verificar que las URIs en el cliente coincidan exactamente
|
||||
- Incluir el protocolo (http:// o https://)
|
||||
- Incluir el puerto si es necesario
|
||||
|
||||
### Error: "Client not found"
|
||||
|
||||
- Verificar que el Client ID sea exacto
|
||||
- Verificar que el realm sea correcto
|
||||
|
||||
### Token no incluye tenant_id
|
||||
|
||||
- Verificar que el usuario tenga el atributo configurado
|
||||
- Verificar que el mapper esté configurado correctamente
|
||||
- Probar obteniendo un nuevo token
|
||||
|
||||
### Usuario no puede hacer login
|
||||
|
||||
- Verificar que el usuario esté habilitado (User enabled: ON)
|
||||
- Verificar que el email esté verificado (Email verified: ON)
|
||||
- Verificar que la contraseña no sea temporal
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
# Módulos A76 Implementados - Anexo 76
|
||||
|
||||
**Fecha de implementación:** 4 de noviembre de 2025
|
||||
|
||||
---
|
||||
|
||||
## ✨ Nuevas Funcionalidades
|
||||
|
||||
### Módulo de Empresa (Company)
|
||||
- Gestión de empresa única con información comercial completa
|
||||
- Manejo de datos fiscales y operativos centralizados
|
||||
|
||||
### Módulo de Clientes y Proveedores (Client & Provider)
|
||||
- Gestión integral de clientes y proveedores
|
||||
- Relaciones con direcciones y programas asociados
|
||||
- Capacidad de diferenciar entre clientes y proveedores
|
||||
|
||||
### Módulo de Partes (GParts)
|
||||
- Gestión de partes/componentes para los sistemas SCAII, SCAF y WINSAAI
|
||||
- Control de inventario y clasificación arancelaria
|
||||
- Información regulatoria y de cumplimiento
|
||||
|
||||
### Módulo de Clases (Class)
|
||||
- Clasificaciones para sistemas SCAII y SCAF
|
||||
- Información arancelaria detallada
|
||||
- Gestión de fracciones arancelarias y materiales
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Relaciones de Base de Datos
|
||||
|
||||
### Relaciones Principales
|
||||
- **Part ↔ Class**: Relación de clave compuesta (client_id, part_class ↔ class_code)
|
||||
- **Part → Country**: Clave foránea a public.countries (country_of_origin)
|
||||
- **Part → CurrencyType**: Clave foránea a public.currency_types (currency_key)
|
||||
- **Class → MaterialType**: Clave foránea a public.material_types (material_key)
|
||||
|
||||
### Esquema de Relaciones
|
||||
```
|
||||
Part (Partes)
|
||||
├── País de origen → Country
|
||||
├── Tipo de moneda → CurrencyType
|
||||
└── Información de clase → Class
|
||||
└── Tipo de material → MaterialType
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Endpoints de API Agregados
|
||||
|
||||
### Módulo Empresa (`/company`)
|
||||
| Método | Endpoint | Descripción |
|
||||
|--------|----------|-------------|
|
||||
| POST | `/` | Crear empresa |
|
||||
| GET | `/` | Obtener información de la empresa |
|
||||
|
||||
### Módulo Clientes y Proveedores (`/clients-providers`)
|
||||
| Método | Endpoint | Descripción |
|
||||
|--------|----------|-------------|
|
||||
| POST | `/` | Crear cliente/proveedor |
|
||||
| GET | `/` | Listar todos con paginación |
|
||||
| GET | `/clients` | Listar solo clientes |
|
||||
| GET | `/providers` | Listar solo proveedores |
|
||||
| GET | `/search/rfc/{rfc}` | Buscar por RFC |
|
||||
| GET | `/{client_id}` | Obtener por ID |
|
||||
| PUT | `/{client_id}` | Actualizar cliente/proveedor |
|
||||
| DELETE | `/{client_id}` | Eliminar cliente/proveedor |
|
||||
| PATCH | `/{client_id}/toggle-status` | Cambiar estatus |
|
||||
| GET | `/{client_id}/address` | Obtener información de dirección |
|
||||
| GET | `/{client_id}/programs` | Obtener información de programas |
|
||||
| GET | `/{client_id}/basic` | Obtener información básica |
|
||||
|
||||
### Módulo Partes (`/parts`)
|
||||
| Método | Endpoint | Descripción |
|
||||
|--------|----------|-------------|
|
||||
| POST | `/` | Crear parte |
|
||||
| GET | `/` | Listar todas con paginación y filtros |
|
||||
| GET | `/client/{client_id}` | Obtener partes por cliente |
|
||||
| GET | `/search/fraction/{fraction}` | Buscar por fracción arancelaria |
|
||||
| GET | `/search/supplier/{supplier}` | Buscar por proveedor |
|
||||
| GET | `/search/country/{country_code}` | Buscar por país |
|
||||
| GET | `/statistics` | Obtener estadísticas de partes |
|
||||
| GET | `/{client_id}/{part_number}` | Obtener parte específica |
|
||||
| PUT | `/{client_id}/{part_number}` | Actualizar parte |
|
||||
| DELETE | `/{client_id}/{part_number}` | Eliminar parte |
|
||||
| PATCH | `/{client_id}/{part_number}/toggle-status` | Cambiar estatus |
|
||||
| GET | `/{client_id}/{part_number}/basic` | Obtener información básica |
|
||||
| GET | `/{client_id}/{part_number}/regulatory` | Obtener información regulatoria |
|
||||
|
||||
### Módulo Clases (`/classes`)
|
||||
| Método | Endpoint | Descripción |
|
||||
|--------|----------|-------------|
|
||||
| POST | `/` | Crear clase |
|
||||
| GET | `/` | Listar todas con paginación y filtros |
|
||||
| GET | `/client/{client_id}` | Obtener clases por cliente |
|
||||
| GET | `/search/fraction/{fraction}` | Buscar por fracción arancelaria |
|
||||
| GET | `/search/material/{material_key}` | Buscar por material |
|
||||
| GET | `/search/unit-measure/{unit_of_measure}` | Buscar por unidad de medida |
|
||||
| GET | `/search/physical-review/{physical_review}` | Buscar por revisión física |
|
||||
| GET | `/statistics` | Obtener estadísticas de clases |
|
||||
| GET | `/{client_id}/{class_code}` | Obtener clase específica |
|
||||
| PUT | `/{client_id}/{class_code}` | Actualizar clase |
|
||||
| DELETE | `/{client_id}/{class_code}` | Eliminar clase |
|
||||
| GET | `/{client_id}/{class_code}/basic` | Obtener información básica |
|
||||
| GET | `/{client_id}/{class_code}/tariff` | Obtener información arancelaria |
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Arquitectura Implementada
|
||||
|
||||
### Diseño Modular
|
||||
- **Modelos**: Definición de entidades ORM con SQLAlchemy
|
||||
- **DTOs**: Objetos de transferencia de datos con validación Pydantic
|
||||
- **Servicios**: Lógica de negocio y operaciones de base de datos
|
||||
- **Rutas**: Endpoints REST API con documentación automática
|
||||
|
||||
### Características Técnicas
|
||||
- **Nombres de campos en inglés** para consistencia internacional
|
||||
- **Claves primarias compuestas** donde es aplicable
|
||||
- **Operaciones CRUD completas** con endpoints de búsqueda especializados
|
||||
- **Relaciones SQLAlchemy** con restricciones de clave foránea apropiadas
|
||||
- **DTOs type-safe** con validación Pydantic
|
||||
|
||||
### Patrones de Desarrollo
|
||||
- Estructura consistente en todos los módulos para facilitar mantenimiento
|
||||
- Separación clara de responsabilidades (models, DTOs, services, routes)
|
||||
- Validación de datos en múltiples capas
|
||||
- Manejo de errores estandarizado
|
||||
- Documentación automática con FastAPI/OpenAPI
|
||||
|
||||
---
|
||||
|
||||
## 📝 Documentación
|
||||
|
||||
### Archivos de Documentación
|
||||
- **RELATIONSHIPS.md**: Documentación completa de relaciones de base de datos
|
||||
- **Type hints detallados** en todos los métodos de servicio
|
||||
- **Comentarios explicativos** en modelos y funciones complejas
|
||||
|
||||
### Estándares de Código
|
||||
- Consistencia en patrones de desarrollo entre módulos
|
||||
- Nomenclatura estandarizada para endpoints y funciones
|
||||
- Validación robusta de datos de entrada y salida
|
||||
- Manejo de excepciones centralizado
|
||||
|
||||
---
|
||||
|
||||
## 📈 Resumen de Implementación
|
||||
|
||||
### Números Totales
|
||||
- **4 módulos completos** implementados
|
||||
- **42+ endpoints** REST API disponibles
|
||||
- **23 archivos nuevos** agregados al proyecto
|
||||
- **2,798+ líneas de código** implementadas
|
||||
|
||||
### Estado del Proyecto
|
||||
- ✅ Modelos de base de datos implementados
|
||||
- ✅ Relaciones entre entidades establecidas
|
||||
- ✅ DTOs con validación completa
|
||||
- ✅ Servicios con lógica de negocio
|
||||
- ✅ Endpoints REST API funcionales
|
||||
- ✅ Integración en router principal
|
||||
- ⏳ Migraciones de base de datos (pendiente)
|
||||
|
||||
### Próximos Pasos
|
||||
1. Crear migraciones de Alembic para las nuevas tablas
|
||||
2. Implementar tests unitarios para cada módulo
|
||||
3. Agregar documentación de API con ejemplos
|
||||
4. Implementar autenticación y autorización
|
||||
5. Optimizar consultas de base de datos
|
||||
|
||||
---
|
||||
|
||||
*Documento generado automáticamente el 4 de noviembre de 2025*
|
||||
@@ -1,107 +0,0 @@
|
||||
# Relaciones entre Modelos A76
|
||||
|
||||
## Resumen de Relaciones Establecidas
|
||||
|
||||
### Part (Tabla: parts)
|
||||
El modelo `Part` representa las partes/componentes en los sistemas SCAII, SCAF y WINSAAI.
|
||||
|
||||
#### Relaciones:
|
||||
|
||||
1. **Con Country (public.countries)**
|
||||
- Campo: `country_of_origin` → `countries.m3_key`
|
||||
- Relación: Many-to-One
|
||||
- Propósito: País de origen de la parte
|
||||
|
||||
2. **Con CurrencyType (public.currency_types)**
|
||||
- Campo: `currency_key` → `currency_types.code`
|
||||
- Relación: Many-to-One
|
||||
- Propósito: Tipo de moneda para el costo unitario
|
||||
|
||||
3. **Con Class (classes)**
|
||||
- Campos: `(client_id, part_class)` → `(client_id, class_code)`
|
||||
- Relación: Many-to-One (usando primaryjoin complejo)
|
||||
- Propósito: Clasificación de la parte
|
||||
- Atributo: `part_class_info`
|
||||
|
||||
### Class (Tabla: classes)
|
||||
El modelo `Class` representa las clases de clasificación en sistemas SCAII y SCAF.
|
||||
|
||||
#### Relaciones:
|
||||
|
||||
1. **Con MaterialType (public.material_types)**
|
||||
- Campo: `material_key` → `material_types.key`
|
||||
- Relación: Many-to-One
|
||||
- Propósito: Tipo de material de la clase
|
||||
|
||||
2. **Con Part (parts)**
|
||||
- Campos: `(client_id, class_code)` → `(client_id, part_class)`
|
||||
- Relación: One-to-Many (inversa de la relación en Part)
|
||||
- Propósito: Partes que pertenecen a esta clase
|
||||
- Atributo: `parts`
|
||||
|
||||
## Esquema de Relaciones
|
||||
|
||||
```
|
||||
Part
|
||||
├── country (Country) # País de origen
|
||||
├── currency (CurrencyType) # Tipo de moneda
|
||||
└── part_class_info (Class) # Información de clasificación
|
||||
└── material_type (MaterialType) # Tipo de material
|
||||
|
||||
Class
|
||||
├── material_type (MaterialType) # Tipo de material
|
||||
└── parts (List[Part]) # Partes que usan esta clase
|
||||
```
|
||||
|
||||
## Uso de las Relaciones
|
||||
|
||||
### En consultas:
|
||||
```python
|
||||
# Obtener una parte con su información completa
|
||||
part = session.query(Part).options(
|
||||
joinedload(Part.country),
|
||||
joinedload(Part.currency),
|
||||
joinedload(Part.part_class_info).joinedload(Class.material_type)
|
||||
).filter(
|
||||
Part.client_id == 1,
|
||||
Part.part_number == "PART001"
|
||||
).first()
|
||||
|
||||
# Acceder a los datos relacionados
|
||||
print(f"País: {part.country.description_es}")
|
||||
print(f"Moneda: {part.currency.currency_name}")
|
||||
print(f"Clase: {part.part_class_info.description_spanish}")
|
||||
print(f"Material: {part.part_class_info.material_type.description}")
|
||||
```
|
||||
|
||||
### En DTOs:
|
||||
Los DTOs pueden incluir información relacionada:
|
||||
```python
|
||||
class PartDetailResponseDTO(BaseModel):
|
||||
client_id: int
|
||||
part_number: str
|
||||
description_spanish: Optional[str]
|
||||
country_name: Optional[str] = None
|
||||
currency_name: Optional[str] = None
|
||||
class_description: Optional[str] = None
|
||||
material_type: Optional[str] = None
|
||||
```
|
||||
|
||||
## Consideraciones Técnicas
|
||||
|
||||
1. **Composite Foreign Keys**: La relación entre `Part` y `Class` usa claves foráneas compuestas que requieren `primaryjoin` personalizado.
|
||||
|
||||
2. **Viewonly Relationships**: Algunas relaciones están marcadas como `viewonly=True` para evitar problemas de escritura accidental.
|
||||
|
||||
3. **Lazy Loading**: Por defecto, las relaciones usan lazy loading. Para consultas que necesiten datos relacionados, usar `joinedload` o `selectinload`.
|
||||
|
||||
4. **Type Hints**: Se usan `TYPE_CHECKING` imports para evitar import circulares mientras se mantienen los type hints.
|
||||
|
||||
## Futuras Relaciones
|
||||
|
||||
Potenciales relaciones adicionales que se pueden agregar:
|
||||
|
||||
1. **Con Sectors** (public.sectors) - para clasificación sectorial
|
||||
2. **Con Transport Types** (public.transport_types) - para modo de transporte
|
||||
3. **Con Customs Sections** (public.customs_sections) - para sección aduanera
|
||||
4. **Relaciones con tablas subsidiarias** como `SPartes`, `QPartes`, etc.
|
||||
@@ -1,126 +0,0 @@
|
||||
# Actualización de Schemas A76
|
||||
|
||||
**Fecha de actualización:** 5 de noviembre de 2025
|
||||
|
||||
---
|
||||
|
||||
## ✅ Modelos Actualizados al Schema A76
|
||||
|
||||
Se han actualizado todos los modelos en `api/v1/modules/a76/` para usar el schema `a76` en PostgreSQL.
|
||||
|
||||
### 📋 Tablas Configuradas
|
||||
|
||||
| Módulo | Tabla | Schema | Estado |
|
||||
|--------|-------|---------|---------|
|
||||
| **Company** | `company` | `a76` | ✅ Actualizada |
|
||||
| **Client & Provider** | `client_provider` | `a76` | ✅ Actualizada |
|
||||
| **Client & Provider** | `client_provider_address` | `a76` | ✅ Actualizada |
|
||||
| **Client & Provider** | `client_provider_programs` | `a76` | ✅ Actualizada |
|
||||
| **GParts** | `parts` | `a76` | ✅ Actualizada |
|
||||
| **Class** | `classes` | `a76` | ✅ Actualizada |
|
||||
| **Licenses** | `licenses` | `a76` | ✅ Ya estaba |
|
||||
| **Licenses** | `license_usage` | `a76` | ✅ Ya estaba |
|
||||
| **Tenants** | `tenants` | `a76` | ✅ Ya estaba |
|
||||
|
||||
### 🔄 Cambios Realizados
|
||||
|
||||
#### 1. Configuración de Schema
|
||||
```python
|
||||
# ANTES
|
||||
class Company(Base):
|
||||
__tablename__ = "company"
|
||||
|
||||
# DESPUÉS
|
||||
class Company(Base):
|
||||
__tablename__ = "company"
|
||||
__table_args__ = {"schema": "a76"}
|
||||
```
|
||||
|
||||
#### 2. Foreign Keys Actualizadas
|
||||
```python
|
||||
# ANTES
|
||||
client_id = Column(String(8), ForeignKey('client_provider.client_id'), ...)
|
||||
|
||||
# DESPUÉS
|
||||
client_id = Column(String(8), ForeignKey('a76.client_provider.client_id'), ...)
|
||||
```
|
||||
|
||||
### 🏗️ Estructura de Schemas
|
||||
|
||||
```
|
||||
PostgreSQL Database
|
||||
├── Schema: public
|
||||
│ ├── countries
|
||||
│ ├── currency_types
|
||||
│ ├── material_types
|
||||
│ └── ... (reference data)
|
||||
│
|
||||
└── Schema: a76
|
||||
├── tenants
|
||||
├── licenses
|
||||
├── license_usage
|
||||
├── company
|
||||
├── client_provider
|
||||
├── client_provider_address
|
||||
├── client_provider_programs
|
||||
├── parts
|
||||
└── classes
|
||||
```
|
||||
|
||||
### 🔗 Relaciones Mantenidas
|
||||
|
||||
Las relaciones entre schemas funcionan correctamente:
|
||||
|
||||
- **A76 → Public**: Los modelos A76 pueden referenciar datos de referencia en `public`
|
||||
- **A76 → A76**: Las relaciones internas del schema A76 están actualizadas
|
||||
- **Composite Keys**: Las relaciones con claves compuestas funcionan correctamente
|
||||
|
||||
#### Ejemplos de Relaciones Cross-Schema:
|
||||
```python
|
||||
# Part (a76) → Country (public)
|
||||
country_of_origin = Column(String(3), ForeignKey('public.countries.m3_key'))
|
||||
|
||||
# Part (a76) → CurrencyType (public)
|
||||
currency_key = Column(String(3), ForeignKey('public.currency_types.code'))
|
||||
|
||||
# Class (a76) → MaterialType (public)
|
||||
material_key = Column(String(10), ForeignKey('public.material_types.key'))
|
||||
```
|
||||
|
||||
### 🎯 Beneficios de la Separación
|
||||
|
||||
1. **Organización**: Datos de negocio separados de datos de referencia
|
||||
2. **Seguridad**: Permisos granulares por schema
|
||||
3. **Mantenimiento**: Facilita respaldos y migraciones selectivas
|
||||
4. **Escalabilidad**: Permite distribuir schemas en el futuro
|
||||
5. **Claridad**: Separación lógica de responsabilidades
|
||||
|
||||
### ⚠️ Consideraciones Importantes
|
||||
|
||||
1. **Migraciones**: Las nuevas migraciones deben especificar el schema `a76`
|
||||
2. **Permisos DB**: El usuario de base de datos necesita permisos en ambos schemas
|
||||
3. **Testing**: Los tests deben considerar la estructura de schemas
|
||||
4. **Backup**: Configurar respaldos para incluir ambos schemas
|
||||
|
||||
### 📝 Próximos Pasos
|
||||
|
||||
1. **Crear migraciones de Alembic** con el schema correcto
|
||||
2. **Verificar permisos** de base de datos para el usuario de aplicación
|
||||
3. **Actualizar tests** para considerar la estructura de schemas
|
||||
4. **Documentar convenciones** de naming para futuros modelos
|
||||
|
||||
---
|
||||
|
||||
### 🔧 Comando de Verificación
|
||||
|
||||
Para verificar que todos los modelos tienen el schema correcto:
|
||||
|
||||
```bash
|
||||
grep -r "__table_args__ = {\"schema\": \"a76\"}" backend/api/v1/modules/a76/*/models.py
|
||||
```
|
||||
|
||||
**Resultado esperado:** 8 coincidencias (una por cada modelo A76)
|
||||
|
||||
---
|
||||
|
||||
*Actualización completada el 5 de noviembre de 2025*
|
||||
Reference in New Issue
Block a user