- 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
25 KiB
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:
# 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:
# 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
# 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
# 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_hourstotal_threats_detectedsuspicious_ips_countcritical_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
structlogen 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ámicospaginate_query()— paginación genérica reutilizableformat_ticket_response()— serialización consistente
b) Corrección del error de sla_breached
# 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
# 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
# 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 KEYtitle VARCHAR(255)description TEXTseverity ENUM(low, medium, high, critical)status ENUM(active, investigating, resolved)tenant_id UUID FKcreated_at TIMESTAMPupdated_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
// 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
// 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)
// 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
// 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
// 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
<!-- 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-8uniforme (antesmb-6variable) - 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-2en lugar depy-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
<!-- 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
// 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)
// 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)
// 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
// 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
# 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
// 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:
# 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