Base para el flujo de ramas por cliente. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
184 lines
7.4 KiB
Markdown
184 lines
7.4 KiB
Markdown
# Arquitectura General
|
|
|
|
## Diagrama de Componentes
|
|
|
|
```mermaid
|
|
graph TB
|
|
subgraph "FastAPI Application"
|
|
M[main.py\nEntry Point]
|
|
C[context.py\nRequest ID Context]
|
|
L[logger_config.py\nStructured Logging]
|
|
|
|
subgraph "Core"
|
|
SAP[core/sap.py\nSAP Session & Proxy]
|
|
SES[core/session.py\nEmployee Sessions]
|
|
end
|
|
|
|
subgraph "Routers"
|
|
A[auth.py\nLogin / Logout]
|
|
BP[business_partners.py\nSocios de Negocio]
|
|
IT[items.py\nArtículos]
|
|
SL[sales.py\nFacturas / Pedidos]
|
|
PR[purchases.py\nÓrdenes / Facturas Compra]
|
|
CT[catalogs.py\nCatálogos]
|
|
BT[batch.py\nLotes]
|
|
PM[permissions.py\nPermisos de Menú]
|
|
end
|
|
|
|
MP[menu_permissions.json]
|
|
end
|
|
|
|
subgraph "External"
|
|
SAP_SL[SAP B1 Service Layer]
|
|
end
|
|
|
|
M --> C
|
|
M --> L
|
|
C --> L
|
|
|
|
M --> A
|
|
M --> BP
|
|
M --> IT
|
|
M --> SL
|
|
M --> PR
|
|
M --> CT
|
|
M --> BT
|
|
M --> PM
|
|
|
|
A --> SAP
|
|
A --> SES
|
|
BP --> SAP
|
|
IT --> SAP
|
|
SL --> SAP
|
|
PR --> SAP
|
|
CT --> SAP
|
|
BT --> SAP
|
|
PM --> MP
|
|
|
|
SAP --> SAP_SL
|
|
SES --> SAP
|
|
```
|
|
|
|
## Pipeline de Middleware
|
|
|
|
Las peticiones atraviesan los siguientes middleware en orden:
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
REQ[Request] --> CORS[CORSMiddleware\nallow_origins=*]
|
|
CORS --> CID[correlation_id_middleware\nX-Request-ID]
|
|
CID --> SES_MW[session_middleware\nValida X-Session-Token]
|
|
SES_MW --> ROUTER{Router}
|
|
ROUTER -->|/api/Login| A[auth.py]
|
|
ROUTER -->|Otros /api/*| SAP_CORE[core/sap.py]
|
|
```
|
|
|
|
### Detalle de Middleware
|
|
|
|
| Middleware | Función |
|
|
| -------------------------- | ----------------------------------------------------------- |
|
|
| `CORSMiddleware` | Permite peticiones desde cualquier origen |
|
|
| `correlation_id_middleware` | Genera o extrae `X-Request-ID` para trazabilidad en logs |
|
|
| `session_middleware` | Valida token de sesión, adjunta `emp_id` a `request.state` |
|
|
|
|
## Arquitectura de Sesiones
|
|
|
|
Existen **dos capas de sesión independientes**:
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
subgraph Employee["Employee Session"]
|
|
T["Token aleatorio → emp_id"]
|
|
E["employee_sessions dict"]
|
|
TK["active_tokens dict"]
|
|
T --> TK
|
|
TK --> E
|
|
end
|
|
|
|
subgraph SAP["SAP B1 Session"]
|
|
S["sap_session_store"]
|
|
M["Manager Credentials (.env)"]
|
|
S -.->|Renueva en 401| M
|
|
end
|
|
```
|
|
|
|
| Capa | Almacenamiento | Ámbito | Timeout | Renovación |
|
|
| ------------- | ----------------- | -------- | ------------- | -------------------- |
|
|
| SAP B1 | `sap_session_store` | Global | Gestionado SAP | Automática al recibir 401 |
|
|
| Empleado | `active_tokens` | Por empleado | 30 min inactividad | Login manual |
|
|
|
|
## Estructura de Rutas
|
|
|
|
| Método | Ruta | Router | Descripción |
|
|
| -------- | --------------------------------- | -------------------- | ------------------------ |
|
|
| `POST` | `/api/Login` | `auth.py` | Autenticar empleado |
|
|
| `POST` | `/api/Logout` | `auth.py` | Cerrar sesión |
|
|
| `GET` | `/api/BusinessPartners` | `business_partners` | Listar socios |
|
|
| `GET` | `/api/BusinessPartners/{code}` | `business_partners` | Obtener socio |
|
|
| `POST` | `/api/BusinessPartners` | `business_partners` | Crear socio |
|
|
| `PATCH` | `/api/BusinessPartners/{code}` | `business_partners` | Actualizar socio |
|
|
| `GET` | `/api/Items` | `items.py` | Listar artículos |
|
|
| `GET` | `/api/Items/{code}` | `items.py` | Obtener artículo |
|
|
| `POST` | `/api/Items` | `items.py` | Crear artículo |
|
|
| `PATCH` | `/api/Items/{code}` | `items.py` | Actualizar artículo |
|
|
| `GET` | `/api/Invoices` | `sales.py` | Listar facturas |
|
|
| `GET` | `/api/Invoices/{key}` | `sales.py` | Obtener factura |
|
|
| `POST` | `/api/Invoices` | `sales.py` | Crear factura |
|
|
| `PATCH` | `/api/Invoices/{key}` | `sales.py` | Actualizar factura |
|
|
| `GET` | `/api/Orders` | `sales.py` | Listar pedidos |
|
|
| `GET` | `/api/Orders/{key}` | `sales.py` | Obtener pedido |
|
|
| `POST` | `/api/Orders` | `sales.py` | Crear pedido |
|
|
| `PATCH` | `/api/Orders/{key}` | `sales.py` | Actualizar pedido |
|
|
| `GET` | `/api/PurchaseOrders` | `purchases.py` | Listar órdenes de compra |
|
|
| `GET` | `/api/PurchaseOrders/{key}` | `purchases.py` | Obtener orden de compra |
|
|
| `PATCH` | `/api/PurchaseOrders/{key}` | `purchases.py` | Actualizar orden compra |
|
|
| `GET` | `/api/PurchaseInvoices` | `purchases.py` | Listar facturas compra |
|
|
| `GET` | `/api/PurchaseInvoices/{key}` | `purchases.py` | Obtener factura compra |
|
|
| `PATCH` | `/api/PurchaseInvoices/{key}` | `purchases.py` | Actualizar factura compra|
|
|
| `GET` | `/api/Currencies` | `catalogs.py` | Listar monedas |
|
|
| `GET` | `/api/BusinessPartnerGroups` | `catalogs.py` | Listar grupos de socios |
|
|
| `GET` | `/api/Warehouses` | `catalogs.py` | Listar almacenes |
|
|
| `GET` | `/api/ItemGroups` | `catalogs.py` | Listar grupos artículos |
|
|
| `GET` | `/api/SalesTaxCodes` | `catalogs.py` | Listar códigos de IVA |
|
|
| `GET` | `/api/BatchNumberDetails` | `batch.py` | Listar lotes |
|
|
| `GET` | `/api/BatchNumberDetails/{id}` | `batch.py` | Obtener lote |
|
|
| `PATCH` | `/api/BatchNumberDetails/{id}` | `batch.py` | Actualizar lote |
|
|
| `GET` | `/api/user/menu` | `permissions.py` | Obtener menú permitido |
|
|
|
|
## Dependencias del Proyecto
|
|
|
|
```mermaid
|
|
graph TD
|
|
main --> context
|
|
main --> logger_config
|
|
logger_config --> context
|
|
main --> auth
|
|
main --> business_partners
|
|
main --> items
|
|
main --> sales
|
|
main --> purchases
|
|
main --> catalogs
|
|
main --> batch
|
|
main --> permissions
|
|
auth --> sap_core
|
|
auth --> session_core
|
|
business_partners --> sap_core
|
|
items --> sap_core
|
|
sales --> sap_core
|
|
purchases --> sap_core
|
|
catalogs --> sap_core
|
|
batch --> sap_core
|
|
permissions --> menu_json[menu_permissions.json]
|
|
```
|
|
|
|
## Configuración por Entorno
|
|
|
|
La aplicación carga siempre `.env` (un solo archivo, sin sufijos de entorno).
|
|
`.env.aberio` se conserva como plantilla de referencia; para desplegar contra
|
|
ese entorno, copiar su contenido dentro de `.env`.
|
|
|
|
| Archivo | URL SAP | Company DB |
|
|
| ------------------ | ------------------------------- | ----------------------- |
|
|
| `.env` | `192.168.1.175:50000` | `SBO_PRUEBA_TAGUM_22` |
|
|
| `.env.aberio` | `192.168.9.3:50000` | `PRUEBA_20260609` |
|