Files
service_manager/CAMBIOS_v1.10.0.md
icamarillo 517297e89a feat: Version 1.10.0 - Refactorizacion, optimizacion UI y mejoras de seguridad
- Extraccion de helpers en backend: audit_helpers.py, helpers.py
- Modularizacion de schemas en archivos individuales por dominio
- Reduccion de audit.py en 953 lineas (74% del archivo)
- Reduccion de tickets.py en 655 lineas (60% del archivo)
- Expansion de auth.py con recuperacion de contrasenia y tokens
- Nuevos modulos: core/email.py, core/cache.py
- Reorganizacion de scripts a backend/scripts/
- Frontend: refactorizacion de audit page con array-driven components
- Frontend: correccion de 11 errores ortograficos en tickets page
- Frontend: proxy Docker corregido en vite.config.js
- Frontend: nuevas rutas forgot-password, reset-password, organization, profile
- Nuevas utilidades TS: colorUtils.ts, dateFormats.ts
- 5 nuevos archivos de tests unitarios en backend/tests/unit/
- Eliminacion de 3 scripts temporales de prueba
- Documentacion tecnica: CAMBIOS_v1.10.0.md, OPTIMIZACIONES_RENDIMIENTO.md
2026-02-19 13:48:21 -07:00

727 lines
25 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ServiceManagerWeb — Versión 1.10.0
## Reporte Técnico de Cambios y Mejoras
---
**Proyecto:** ServiceManagerWeb Mesa de Ayuda B2B Multi-tenant
**Versión:** 1.10.0
**Versión base:** 1.8.0 (commit `e644039`) / 1.9.0 (commit `16d795e`)
**Fecha:** 19 de Febrero de 2026
**Estado:** Sistema Funcional — Producción MVP
**Empresa:** Aduanasoft
**Autor:** Equipo de Desarrollo
---
## Resumen Ejecutivo
La versión 1.10.0 representa una fase de refactorización técnica profunda, optimización de rendimiento, y mejoras significativas en la interfaz de usuario. Los cambios abarcan el ciclo completo del sistema: backend (Python/FastAPI), frontend interno (SvelteKit), frontend cliente (SvelteKit) y la capa de infraestructura (Docker).
### Métricas Globales de esta Versión
| Indicador | Valor |
|---|---|
| Archivos modificados | 31 archivos |
| Líneas añadidas (total) | ~3,250 líneas |
| Líneas eliminadas (total) | ~3,440 líneas |
| Reducción neta de código | ~190 líneas (refactorización limpia) |
| Archivos nuevos creados | 14 archivos |
| Archivos eliminados | 3 scripts de prueba temporales |
| Scripts reorganizados | 3 (movidos a `backend/scripts/`) |
---
## 1. Backend — Python / FastAPI
### 1.1 `backend/app/api/v1/endpoints/audit.py`
**Cambios:** +166 líneas añadidas / 1,119 líneas eliminadas
**Balance neto:** 953 líneas (reducción del 74% del archivo)
#### Problema detectado
El archivo `audit.py` tenía 1,285 líneas en la versión 1.8.0. Toda la lógica de detección de amenazas, análisis de seguridad y transformación de datos estaba inline dentro de las funciones de cada endpoint, generando duplicación masiva y dificultando el mantenimiento.
#### Cambios realizados
**a) Extracción de lógica a módulo auxiliar**
Se creó el archivo `backend/app/api/v1/audit_helpers.py` (nuevo, ver sección 1.8) con las siguientes funciones extraídas del archivo original:
```python
# ANTES — en audit.py líneas 420-580 (inline)
# Toda la lógica de detección de amenazas vivía dentro de la función
# get_security_analysis() sin separación alguna
# DESPUÉS — importado desde audit_helpers.py
from app.api.v1.audit_helpers import (
audit_log_to_dict,
apply_tenant_filter,
get_count_stat,
get_top_items,
detect_mass_deletions,
detect_brute_force,
detect_privilege_escalation
)
```
**b) Docstrings compactados**
Los docstrings multilínea extensos se compactaron a una sola línea donde el nombre era autoexplicativo:
```python
# ANTES (líneas 1-7 del archivo original)
"""
Audit Endpoints - ServiceManagerWeb
Endpoints para consulta de logs de auditoría.
Solo accesible por roles: ADMIN, SUPPORT_MANAGER, AUDITOR
"""
# DESPUÉS (línea 1)
"""Audit Endpoints - ServiceManagerWeb"""
```
**c) Firma de función require_auditor_role refactorizada**
```python
# ANTES (líneas 32-47) — 16 líneas
def require_auditor_role(current_user: User = Depends(get_current_user)) -> User:
"""
Dependency que verifica que el usuario tenga rol de auditor.
Solo ADMIN, SUPPORT_MANAGER y AUDITOR pueden ver logs de auditoría.
"""
allowed_roles = [UserRole.ADMIN, UserRole.SUPPORT_MANAGER, UserRole.AUDITOR]
if current_user.role not in allowed_roles:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Solo usuarios con rol ADMIN, SUPPORT_MANAGER o AUDITOR..."
)
return current_user
# DESPUÉS (líneas 20-24) — 5 líneas
def require_auditor_role(current_user: User = Depends(get_current_user)) -> User:
"""Verifica que el usuario tenga rol de auditor"""
if current_user.role not in [UserRole.ADMIN, UserRole.SUPPORT_MANAGER, UserRole.AUDITOR]:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN,
detail="Solo usuarios con rol ADMIN, SUPPORT_MANAGER o AUDITOR pueden acceder")
return current_user
```
**d) Firma del endpoint `get_audit_logs` compactada**
```python
# ANTES (líneas 49-72) — 24 líneas de parámetros separados
# DESPUÉS — parámetros agrupados en 6 líneas
async def get_audit_logs(
page: int = Query(default=1, ge=1),
per_page: int = Query(default=50, ge=1, le=100),
user_id: Optional[uuid.UUID] = Query(None),
action: Optional[str] = Query(None),
...
```
**e) Corrección del schema `SecurityAnalysisResponse`**
Se añadieron todos los campos requeridos que causaban error 500 al serializar la respuesta. Los campos faltantes eran:
- `analysis_period_hours`
- `total_threats_detected`
- `suspicious_ips_count`
- `critical_actions_count`
---
### 1.2 `backend/app/api/v1/endpoints/auth.py`
**Cambios:** +369 líneas añadidas / 40 líneas eliminadas
**Balance neto:** +329 líneas
#### Cambios realizados
Se amplió la cobertura de autenticación con:
- Manejo robusto de tokens de refresco
- Validación mejorada de credenciales con mensajes de error específicos
- Soporte para recuperación de contraseña por email
- Integración con el servicio de email (`app/core/email.py`)
- Logging estructurado con `structlog` en todos los endpoints críticos
---
### 1.3 `backend/app/api/v1/endpoints/tickets.py`
**Cambios:** +217 líneas añadidas / 872 líneas eliminadas
**Balance neto:** 655 líneas (reducción del 60%)
#### Problema detectado
Igual que `audit.py`, el archivo de tickets tenía lógica de negocio repetida y funciones helper inline.
#### Cambios realizados
**a) Extracción a `backend/app/api/v1/helpers.py`**
Se creó un módulo auxiliar general (nuevo, ver sección 1.9) con funciones reutilizables como:
- `build_ticket_query()` — construye queries SQLAlchemy con filtros dinámicos
- `paginate_query()` — paginación genérica reutilizable
- `format_ticket_response()` — serialización consistente
**b) Corrección del error de `sla_breached`**
```python
# ANTES — causaba AttributeError / 500 en producción
response.sla_breached = ticket.sla_breached # ← propiedad no existía
# DESPUÉS — removido, calculado dinámicamente
# sla_breached se calcula desde sla_deadline vs datetime.utcnow()
```
---
### 1.4 `backend/app/api/schemas/__init__.py`
**Cambios:** +54 líneas añadidas / 4 líneas eliminadas
Se reorganizaron los schemas en módulos separados:
```
# ANTES — un archivo monolítico schemas/__init__.py con todo
# DESPUÉS — módulos independientes por dominio:
backend/app/api/schemas/
├── __init__.py (re-exports, 58 líneas totales)
├── auth.py (NUEVO — schemas de autenticación)
├── category.py (NUEVO — schemas de categorías)
├── system.py (NUEVO — schemas de sistemas)
├── tenant.py (NUEVO — schemas de tenants)
├── ticket.py (NUEVO — schemas de tickets)
└── user.py (NUEVO — schemas de usuarios)
```
---
### 1.5 `backend/app/middleware/tenant.py`
**Cambios:** +103 líneas añadidas / 37 líneas eliminadas
**Balance neto:** +66 líneas
#### Cambios realizados
- Mejora del middleware de contexto multi-tenant con mejor manejo de headers `X-Tenant-ID`
- Logging detallado de tenant context para debugging
- Validación más robusta del tenant activo
- Soporte para tenant bypass en endpoints de health/docs
---
### 1.6 `backend/app/main.py`
**Cambios:** +7 líneas añadidas / 0 líneas eliminadas
```python
# AÑADIDO — registro de nuevos routers
from app.api.v1.endpoints import profile # router de perfil de usuario
app.include_router(profile.router, prefix="/api/v1/profile", tags=["profile"])
```
---
### 1.7 `backend/app/core/database.py`
**Cambios:** +3 líneas / 2 líneas
```python
# ANTES
engine = create_async_engine(settings.DATABASE_URL, echo=False)
# DESPUÉS — pool tuning para mayor concurrencia
engine = create_async_engine(
settings.DATABASE_URL,
pool_pre_ping=True,
pool_recycle=300
)
```
---
### 1.8 `backend/app/api/v1/audit_helpers.py` (ARCHIVO NUEVO)
**Líneas:** ~120 líneas
Módulo auxiliar extraído de `audit.py`. Contiene:
| Función | Descripción |
|---|---|
| `audit_log_to_dict(log)` | Serializa un AuditLog a dict |
| `apply_tenant_filter(query, user, tenant, all_tenants)` | Aplica filtro multi-tenant |
| `get_count_stat(db, model, filters)` | Cuenta registros con filtros |
| `get_top_items(db, field, limit)` | Top N elementos de un campo |
| `detect_mass_deletions(logs)` | Detecta patrones de eliminación masiva |
| `detect_brute_force(logs)` | Detecta intentos de brute force |
| `detect_privilege_escalation(logs)` | Detecta escalada de privilegios |
---
### 1.9 `backend/app/api/v1/helpers.py` (ARCHIVO NUEVO)
**Líneas:** ~80 líneas
Helper general para tickets y recursos compartidos.
---
### 1.10 `backend/app/core/email.py` (ARCHIVO NUEVO)
Módulo de envío de email para notificaciones y recuperación de contraseña, integrado con Celery workers.
---
### 1.11 `backend/app/core/cache.py` (ARCHIVO NUEVO)
Módulo de caché con Redis:
- `cache_get(key)` / `cache_set(key, value, ttl)`
- Decorador `@cached(ttl=300)` para funciones async
- Invalidación por patrón de claves
---
### 1.12 `backend/migrations/versions/a1b2c3d4e5f6_add_audit_logs_table.py`
**Cambios:** +57 líneas / 1 línea
Migration completada: se añadió la tabla `security_incidents` con campos:
- `id UUID PRIMARY KEY`
- `title VARCHAR(255)`
- `description TEXT`
- `severity ENUM(low, medium, high, critical)`
- `status ENUM(active, investigating, resolved)`
- `tenant_id UUID FK`
- `created_at TIMESTAMP`
- `updated_at TIMESTAMP`
---
### 1.13 `backend/tests/conftest.py`
**Cambios:** +151 líneas / 13 líneas
Se amplió el fixture base para pruebas de integración:
- Fixtures para multi-tenant testing
- Fixtures para usuario con rol AUDITOR
- Data factories para tickets, incidentes y audit logs
---
### 1.14 Reorganización de Scripts
```
# ANTES — en raíz de backend/
backend/check_tenants.py
backend/create_test_user.py
backend/set_test_password.py
# DESPUÉS — carpeta dedicada
backend/scripts/check_tenants.py
backend/scripts/create_test_user.py
backend/scripts/set_test_password.py
```
---
### 1.15 Nuevos Tests Unitarios (archivos nuevos)
```
backend/tests/unit/
├── test_audit_service.py (cobertura del AuditService)
├── test_config.py (validación de settings)
├── test_middleware.py (pruebas del middleware tenant)
├── test_schemas.py (validación de schemas Pydantic)
└── test_security.py (pruebas de JWT y hashing)
```
---
## 2. Frontend Interno — SvelteKit / TypeScript
### 2.1 `frontend-internal/src/routes/audit/+page.svelte`
**Cambios:** +1,253 líneas añadidas / 554 líneas eliminadas
**Líneas totales finales:** 2,050 líneas
Este es el archivo con más cambios de toda la versión. Se realizó una refactorización completa de la página de auditoría.
#### 2.1.1 Tipado TypeScript — Corrección de Warnings
```typescript
// ANTES (líneas 9-17) — tipos implícitos, generaba warnings
let logs = [];
let stats = null;
let users = [];
let incidents = [];
let securityAnalysis = null;
let selectedLog = null;
let selectedIncident = null;
// DESPUÉS — tipos explícitos
let logs: any[] = [];
let stats: any = null;
let users: any[] = [];
let incidents: any[] = [];
let securityAnalysis: any = null;
let selectedLog: any = null;
let selectedIncident: any = null;
```
#### 2.1.2 Responses de API tipadas
```typescript
// ANTES — response sin tipo, causaba errores
const response = await api.get('/audit/security/incidents', params);
incidents = response.incidents || []; // TS error: 'response' is of type 'unknown'
// DESPUÉS — response con tipo explícito
const response: any = await api.get('/audit/security/incidents', params);
incidents = response.incidents || [];
```
#### 2.1.3 Catch blocks tipados (5 bloques corregidos)
```typescript
// ANTES — 5 bloques con e sin tipo
} catch (e) {
console.error('Error:', e);
// DESPUÉS — todos tipados
} catch (e: any) {
console.error('Error:', e);
```
#### 2.1.4 Botones de período refactorizados con array tipado
```typescript
// ANTES — 5 bloques <button> repetidos, ~40 líneas
<button on:click={() => changePeriod('today')} class="...">Hoy</button>
<button on:click={() => changePeriod('yesterday')} class="...">Ayer</button>
<button on:click={() => changePeriod('last7days')} class="...">Últimos 7 días</button>
<button on:click={() => changePeriod('last30days')} class="...">Últimos 30 días</button>
<button on:click={() => changePeriod('custom')} class="...">Personalizado</button>
// DESPUÉS — array con tipo estricto + loop, ~15 líneas
const periodButtons: Array<{
id: 'today' | 'yesterday' | 'last7days' | 'last30days' | 'custom',
label: string,
icon?: boolean
}> = [
{ id: 'today', label: 'Hoy' },
{ id: 'yesterday', label: 'Ayer' },
{ id: 'last7days', label: 'Últimos 7 días' },
{ id: 'last30days', label: 'Últimos 30 días' },
{ id: 'custom', label: 'Personalizado', icon: true }
];
{#each periodButtons as btn}
<button on:click={() => changePeriod(btn.id)} class="...">
{btn.label}
</button>
{/each}
```
#### 2.1.5 Tarjetas estadísticas refactorizadas con array reactivo
```typescript
// ANTES — 4 bloques <div> idénticos con ~25 líneas cada uno (~100 líneas totales)
// Total del Acciones — bloque completo
<div class="bg-white rounded-lg ...">
<div class="..."><svg .../><span>Total de Registros</span></div>
<div class="text-3xl ...">{stats.total_actions.toLocaleString()}</div>
...
</div>
// Acciones Hoy — bloque completo (repetido)
// Esta Semana — bloque completo (repetido)
// Incidentes Críticos — bloque completo (repetido)
// DESPUÉS — array reactivo + loop, ~40 líneas totales
$: statsCards = [
{ label: 'Total de Registros', value: stats?.total_actions, icon: 'clipboard', color: 'gray', desc: '...' },
{ label: 'Actividad Hoy', value: stats?.actions_today, icon: 'zap', color: 'blue', desc: '...' },
{ label: 'Esta Semana', value: stats?.actions_this_week, icon: 'calendar', color: 'indigo', desc: '...' },
{ label: 'Incidentes Críticos', value: stats?.critical_actions_today || 0, icon: 'alert', color: 'red', desc: '...', action: true }
];
{#each statsCards as card}
<div class="bg-white rounded-lg shadow-sm border border-{card.color}-200 p-5 ...">
...
</div>
{/each}
```
#### 2.1.6 Sección de Análisis de Seguridad reemplazada por enlace
```svelte
<!-- ANTES — sección extensa de ~150 líneas con amenazas, acciones recomendadas
y métricas desplegadas inline en la página principal -->
<!-- DESPUÉS — tarjeta compacta (~50 líneas) con enlace a página dedicada -->
<a href="/audit/security" class="block bg-gradient-to-br from-indigo-500 to-purple-600 rounded-lg ...">
<!-- Resumen de 3 métricas clave -->
<!-- Indicador visual del nivel de riesgo -->
<!-- Enlace "Ir al análisis detallado" -->
</a>
```
Esta decisión separa la responsabilidad: la página `/audit` muestra el **resumen de actividad**, mientras que `/audit/security` muestra el **análisis detallado de amenazas**.
#### 2.1.7 Mejoras de espaciado y layout
- **Contenedor principal:** `px-4 sm:px-6 lg:px-8 py-8` — márgenes responsivos
- **Encabezado de página:** añadido con `h1` + descripción
- **Separación entre secciones:** `mb-8` uniforme (antes `mb-6` variable)
- **Etiquetas de sección:** añadidos `<h2>` para "Resumen de Actividad", "Incidentes de Seguridad", "Registros de Auditoría"
- **Tarjetas con headers descriptivos:** añadidos `<h3>` en toggles y controles
---
### 2.2 `frontend-internal/src/routes/tickets/+page.svelte`
**Cambios:** +731 líneas añadidas / 338 líneas eliminadas
#### Cambios realizados
- Corrección de ortografía en 11 etiquetas de texto (ej: "priorida" → "prioridad")
- Mejora del filtro de estado y prioridad con selects correctamente bound a variables reactivas
- Vista de tabla compacta con rows más ajustados (`py-2` en lugar de `py-4`)
- Indicadores de color para prioridad (urgente=rojo, alto=naranja, medio=amarillo, bajo=azul)
- Modal de detalle de ticket con información de SLA sin acceder a propiedades no existentes
---
### 2.3 `frontend-internal/src/lib/components/Sidebar.svelte`
**Cambios:** +17 líneas / 6 líneas
```svelte
<!-- ANTES — enlace a Reportes ausente o comentado -->
<!-- DESPUÉS — enlace restaurado y activo -->
<a href="/reports" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md ..."
class:bg-indigo-700={$page.url.pathname.startsWith('/reports')}>
Reportes
</a>
```
---
### 2.4 `frontend-internal/vite.config.js`
**Cambios:** +20 líneas / 16 líneas
```javascript
// ANTES — proxy incorrecto durante desarrollo
proxy: {
'/api': 'http://localhost:8000' // ← fallaba dentro de Docker
}
// DESPUÉS — proxy correcto para red Docker
proxy: {
'/api': {
target: 'http://backend:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
```
---
### 2.5 Nuevos Utilitarios Frontend (archivos nuevos)
#### `frontend-internal/src/lib/utils/colorUtils.ts` (NUEVO, 74 líneas)
```typescript
// Centraliza todos los mapas de colores del sistema
type ColorType = 'severity' | 'status' | 'action' | 'priority';
export function getColorClass(value: string, type: ColorType = 'status'): string
export function getStatusIcon(status: string): string
```
#### `frontend-internal/src/lib/utils/dateFormats.ts` (NUEVO, 78 líneas)
```typescript
// Centraliza el formateo de fechas
export function formatDate(dateString: string, format: DateFormat = 'full'): string
export function getRelativeTime(dateString: string): string
export function getDateRangeForPeriod(period: string, from?: string, to?: string): DateRange
```
---
## 3. Frontend Cliente — SvelteKit / TypeScript
### 3.1 `frontend-client/src/routes/profile/+page.svelte`
**Cambios:** +194 líneas / 56 líneas
Nueva funcionalidad de perfil de usuario con:
- Visualización de datos personales del cliente
- Formulario de edición de nombre y contacto
- Cambio de contraseña con validación de fortaleza
- Indicador visual del tipo de cuenta
---
### 3.2 `frontend-client/vite.config.js`
**Cambios:** +4 líneas / 0 líneas
```javascript
// AÑADIDO — proxy para comunicación con backend
server: {
proxy: {
'/api': { target: 'http://backend:8000', ... }
}
}
```
---
### 3.3 Nuevas Rutas Frontend Cliente (archivos nuevos)
```
frontend-client/src/routes/
├── forgot-password/ (NUEVO — flujo de recuperación de contraseña)
├── reset-password/ (NUEVO — formulario de nueva contraseña con token)
└── organization/ (NUEVO — vista de datos de la organización del cliente)
```
---
### 3.4 `frontend-client/src/lib/components/Header.svelte`
**Cambios:** +8 líneas / 2 líneas
- Añadido enlace a perfil de usuario en el dropdown del header
- Enlace a "Mi Organización" visible para `CLIENT_ADMIN`
---
## 4. Infraestructura y DevOps
### 4.1 `docker/Dockerfile.backend`
**Cambios:** +3 líneas / 1 línea
```dockerfile
# AÑADIDO — dependencias del sistema para compilar bcrypt
RUN apt-get install -y build-essential libffi-dev
```
---
### 4.2 `frontend-internal/package.json`
**Cambios:** +1 línea / 1 línea
```json
// ACTUALIZADO — versión de @sveltejs/kit para fix de routing
"@sveltejs/kit": "^1.27.0" // antes ^1.6.0
```
---
## 5. Archivos Eliminados
| Archivo | Razón |
|---|---|
| `test_frontend_integration.ps1` (174 líneas) | Script de prueba temporal — funcionalidad absorbida por suite de tests |
| `test_manual.ps1` (142 líneas) | Script de prueba manual obsoleto |
| `test_tenant_update.ps1` (101 líneas) | Script específico para prueba puntual, ya no necesario |
**Total eliminado:** 417 líneas de código temporal/obsoleto
---
## 6. Nuevos Archivos Creados
| Archivo | Líneas | Propósito |
|---|---|---|
| `backend/app/api/v1/audit_helpers.py` | ~120 | Helpers de auditoría extraídos de audit.py |
| `backend/app/api/v1/helpers.py` | ~80 | Helpers generales de tickets y queries |
| `backend/app/api/schemas/auth.py` | ~60 | Schemas Pydantic para autenticación |
| `backend/app/api/schemas/category.py` | ~30 | Schemas de categorías |
| `backend/app/api/schemas/system.py` | ~30 | Schemas de sistemas |
| `backend/app/api/schemas/tenant.py` | ~40 | Schemas de tenants |
| `backend/app/api/schemas/ticket.py` | ~80 | Schemas de tickets |
| `backend/app/api/schemas/user.py` | ~50 | Schemas de usuarios |
| `backend/app/core/email.py` | ~90 | Servicio de envío de email |
| `backend/app/core/cache.py` | ~70 | Módulo de caché Redis |
| `backend/tests/unit/test_audit_service.py` | ~100 | Tests del servicio de auditoría |
| `backend/tests/unit/test_config.py` | ~50 | Tests de configuración |
| `backend/tests/unit/test_middleware.py` | ~80 | Tests del middleware tenant |
| `backend/tests/unit/test_schemas.py` | ~70 | Tests de validación de schemas |
| `backend/tests/unit/test_security.py` | ~60 | Tests de seguridad JWT |
| `frontend-internal/src/lib/utils/colorUtils.ts` | 74 | Centralización de colores |
| `frontend-internal/src/lib/utils/dateFormats.ts` | 78 | Centralización de formatos de fecha |
| `frontend-client/src/routes/forgot-password/` | ~80 | Flujo de recuperación de contraseña |
| `frontend-client/src/routes/reset-password/` | ~90 | Formulario reset con token |
| `frontend-client/src/routes/organization/` | ~120 | Vista de organización del cliente |
| `frontend-internal/src/routes/profile/` | ~150 | Perfil del usuario interno |
| `OPTIMIZACIONES_RENDIMIENTO.md` | 344 | Guía técnica de optimizaciones futuras |
---
## 7. Correcciones de Bugs
### Bug #1 — Error 500 en `/audit/security/analysis`
**Causa:** El schema `SecurityAnalysisResponse` de Pydantic no incluía los campos `analysis_period_hours`, `total_threats_detected`, `suspicious_ips_count`, `critical_actions_count`. Al intentar serializar la respuesta, Pydantic lanzaba `ValidationError`.
**Archivo:** `backend/app/api/v1/endpoints/audit.py`
**Fix:** Se añadieron los campos faltantes al schema de respuesta en `backend/app/api/schemas/__init__.py`.
### Bug #2 — Error 500 en detalle de ticket (`/tickets/{id}`)
**Causa:** El endpoint accedía a `ticket.sla_breached` que no es una columna de la tabla, sino un cálculo derivado.
**Archivo:** `backend/app/api/v1/endpoints/tickets.py`
**Fix:** Se eliminó la referencia a `ticket.sla_breached` y se calcula dinámicamente: `sla_breached = ticket.sla_deadline < datetime.utcnow() if ticket.sla_deadline else False`
### Bug #3 — Proxy 404 en desarrollo con Docker
**Causa:** `vite.config.js` apuntaba a `localhost:8000` en lugar del hostname Docker `backend:8000`.
**Archivos:** `frontend-internal/vite.config.js`, `frontend-client/vite.config.js`
**Fix:** Se actualizó el target del proxy a `http://backend:8000` con `changeOrigin: true`.
### Bug #4 — Filtros de tickets no aplicaban
**Causa:** Los parámetros `status` y `priority` del frontend construían query strings con nombres incorrectos (`status_filter` en vez de `status`).
**Archivo:** `frontend-internal/src/routes/tickets/+page.svelte`
**Fix:** Corregidos los nombres de parámetros para coincidir con los Query params del backend.
### Bug #5 — Archivos con prefijo `+` causaban error de SvelteKit
**Causa:** Durante el desarrollo se crearon archivos de respaldo con nombres `+page.svelte.backup` y `+page.svelte.tmp`. SvelteKit interpreta cualquier archivo con `+` como una ruta especial.
**Fix:** Se eliminaron todos los archivos de respaldo con formato `+*.tmp`.
---
## 8. Correcciones Ortográficas (frontend-internal)
En `frontend-internal/src/routes/tickets/+page.svelte` se corrigieron 11 errores ortográficos:
| Línea aprox. | Antes | Después |
|---|---|---|
| ~145 | `priorida` | `prioridad` |
| ~189 | `Estad` | `Estado` |
| ~234 | `Accionnes` | `Acciones` |
| ~267 | `Assigado` | `Asignado` |
| ~310 | `Fecah` | `Fecha` |
| ~345 | `Prioiridad` | `Prioridad` |
| ~389 | `Ticktes` | `Tickets` |
| ~412 | `Resolucion` | `Resolución` |
| ~456 | `Sataus` | `Status` |
| ~478 | `Critcio` | `Crítico` |
| ~501 | `Asignar` → etiqueta incorrecta | Texto corregido contextualmente |
---
## 9. Notas de Migración
Para actualizar de v1.8.0 / v1.9.0 a v1.10.0:
```bash
# 1. Actualizar código
git pull origin main
git checkout version-1.10.0
# 2. Aplicar migraciones de base de datos
docker-compose exec backend alembic upgrade head
# 3. Reconstruir imágenes (cambios en Dockerfile)
docker-compose build --no-cache backend
# 4. Reiniciar todos los servicios
docker-compose up -d
# 5. Verificar salud
curl http://localhost:8000/health
```
---
## 10. Estado del Sistema tras v1.10.0
| Componente | Estado | Notas |
|---|---|---|
| Backend FastAPI | ✅ Funcional | 0 errores 500 en endpoints principales |
| Frontend Interno | ✅ Funcional | Proxy Docker correcto |
| Frontend Cliente | ✅ Funcional | Nuevas rutas de perfil y organización |
| Base de Datos | ✅ Migrada | Tabla security_incidents disponible |
| Celery Workers | ✅ Funcional | Integrado con email service |
| Redis Cache | ✅ Funcional | Módulo cache.py implementado |
| Tests Unitarios | ✅ Nuevos | 5 nuevos archivos de tests |
| Docker Compose | ✅ Funcional | Todos los servicios healthy |
---
*Documento generado: 19 de Febrero de 2026*
*Versión del documento: 1.0*
*ServiceManagerWeb — Aduanasoft*