2026-03-11 11:36:11 -06:00
2026-03-11 11:36:11 -06:00
2026-02-27 09:16:08 -07:00
2026-02-23 13:01:24 -07:00
2026-03-11 11:36:11 -06:00
2026-03-10 13:46:30 -06:00
2026-03-09 13:40:28 -06:00
2026-03-03 09:29:53 -07:00
2026-01-12 08:17:17 -07:00
2026-02-12 14:00:04 -07:00
2026-03-11 09:26:36 -06:00
2026-03-04 13:31:38 -07:00
2026-03-11 11:36:11 -06:00
2026-03-11 11:36:11 -06:00
2026-03-11 11:36:11 -06:00
2026-03-04 13:31:38 -07:00

ServiceManagerWeb — Mesa de Ayuda B2B

Versión actual: v1.15.1 — Módulo de reportes implementado

Sistema multi-tenant de Mesa de Ayuda / Soporte Técnico empresarial desarrollado para Aduanasoft. Arquitectura Modular Monolith con Clean Architecture, preparado para escalar a microservicios.


Tabla de Contenidos

  1. Requisitos previos
  2. Inicio rápido con Docker (recomendado)
  3. Configuración de variables de entorno
  4. Cargar datos de prueba
  5. URLs y puertos por defecto
  6. Credenciales de prueba
  7. Desarrollo local sin Docker
  8. Arquitectura del proyecto
  9. Roles y permisos
  10. Comandos útiles
  11. Pruebas (testing)
  12. Solución de problemas
  13. Contribución
  14. Historial de versiones

Requisitos previos

Antes de clonar el proyecto, asegúrate de tener instalado:

Herramienta Versión mínima Descarga
Git 2.x https://git-scm.com/downloads
Docker Desktop 24.x https://www.docker.com/products/docker-desktop
Docker Compose v2.x (incluido en Docker Desktop)

Nota para desarrolladores que quieran editar código localmente (sin Docker): también necesitarás Python 3.11+ y Node.js 18+. Ver sección Desarrollo local sin Docker.

Verificar que Docker esté corriendo

docker --version        # Debe mostrar Docker version 24.x o superior
docker compose version  # Debe mostrar Docker Compose version v2.x

Si docker compose version falla, prueba docker-compose --version (versión standalone).


Inicio rápido con Docker (recomendado)

Este es el método más simple y funciona igual en Windows, Linux y macOS. Solo necesitas Docker Desktop instalado y corriendo.

Paso 1 — Clonar el repositorio

git clone https://git.aduanasoft.com/ADUANASOFT/service_manager.git
cd service_manager

Paso 2 — Crear el archivo de variables de entorno

Linux / macOS:

cp .env.example .env

Windows (PowerShell):

Copy-Item .env.example .env

Windows (CMD):

copy .env.example .env

Importante: El archivo .env nunca se sube a git (está en .gitignore). Para desarrollo local los valores del .env.example funcionan sin cambios. En producción debes generar claves secretas únicas (ver sección de variables de entorno).

Paso 3 — Levantar todos los servicios

docker compose up -d

Este comando descarga las imágenes, construye los contenedores e inicia todo el stack. La primera vez tarda entre 3 y 8 minutos dependiendo de la conexión a internet.

Alternativa con herramientas de desarrollo (Adminer, MailHog, Redis Commander):

docker compose --profile dev up -d

Paso 4 — Verificar que todo esté funcionando

docker compose ps

Deberías ver todos los servicios con estado Up o healthy:

NAME                            STATUS
servicemanager-db               Up (healthy)
servicemanager-redis            Up (healthy)
servicemanager-backend          Up (healthy)
servicemanager-worker           Up
servicemanager-beat             Up
servicemanager-client-frontend  Up
servicemanager-internal-...     Up
servicemanager-nginx            Up

Si algún servicio muestra Exit o Restarting, revisa la sección Solución de problemas.

Paso 5 — Cargar datos de ejemplo (opcional pero recomendado)

docker exec servicemanager-backend python /scripts/seed_data.py

Esto crea el tenant de demostración, categorías, usuarios y tickets de prueba.

¡Listo! Abre el navegador

Aplicación URL
Portal de clientes http://localhost:3000
Panel interno (staff) http://localhost:3001
API REST http://localhost:8000
Documentación API (Swagger) http://localhost:8000/docs
Documentación API (ReDoc) http://localhost:8000/redoc
Health check http://localhost:8000/health

Con perfil dev activo también tendrás:


Configuración de variables de entorno

El archivo .env controla todo el comportamiento de la aplicación. Copia .env.example como .env y revisa los valores siguientes:

Variables críticas

Variable Descripción Valor por defecto (dev)
SECRET_KEY Clave secreta general de Flask/FastAPI (cambiar en producción)
JWT_SECRET_KEY Clave para firmar tokens JWT (cambiar en producción)
DATABASE_URL Cadena de conexión a PostgreSQL postgresql+asyncpg://servicemanager:...@postgres:5432/servicemanager
REDIS_URL URL de conexión a Redis redis://redis:6379/0
ENVIRONMENT Entorno actual development
DEBUG Modo debug (muestra errores detallados) true

Generar claves seguras para producción

Linux / macOS:

openssl rand -base64 32   # Genera SECRET_KEY
openssl rand -base64 32   # Genera JWT_SECRET_KEY

Windows (PowerShell):

[Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Maximum 256 }))

Advertencia: Nunca uses las claves del .env.example en producción. Cambiar las claves en producción invalida todas las sesiones activas.

Desarrollo local vs Docker

En .env.example las URLs apuntan a nombres de servicio Docker (postgres, redis, backend). Si ejecutas el backend directamente en tu máquina (sin Docker), cambia:

# Para desarrollo local sin Docker:
DATABASE_URL=postgresql+asyncpg://servicemanager:servicemanager123@localhost:5432/servicemanager
REDIS_URL=redis://localhost:6379/0
CELERY_BROKER_URL=redis://localhost:6379/0

Cargar datos de prueba

El script seed_data.py crea datos iniciales en la base de datos.

Con Docker (recomendado):

docker exec servicemanager-backend python /scripts/seed_data.py

Sin Docker:

cd backend
python ../scripts/seed_data.py

El script crea:

  • Tenant de demostración: aduanasoft-demo
  • Categorías de tickets (Soporte Técnico, Facturación, Incidentes Críticos, etc.)
  • Sistemas registrados
  • Usuarios de prueba con distintos roles

URLs y puertos por defecto

Servicio Puerto Descripción
Frontend Clientes 3000 Portal para usuarios clientes
Frontend Interno 3001 Panel para staff (agentes, admins)
Backend API 8000 FastAPI — endpoints REST
PostgreSQL 5432 Base de datos (no exponer en producción)
Redis 6379 Cache y broker Celery (no exponer en producción)
Nginx 80 Reverse proxy
Adminer (perfil dev) 8080 GUI para PostgreSQL
MailHog (perfil dev) 8025 Capturador de emails en desarrollo
Redis Commander (perfil dev) 8081 GUI para Redis

¿Conflicto de puertos?

Si algún puerto ya está en uso en tu máquina, edita docker-compose.yml y cambia el número izquierdo del mapeo host:container. Por ejemplo, para backend en el 8080:

ports:
  - "8080:8000"   # ahora accesible en localhost:8080

Credenciales de prueba

Después de ejecutar el seed, puedes iniciar sesión con:

Campo Valor
Email admin@aduanasoft.com
Contraseña admin123
Tenant aduanasoft-demo
Rol ADMIN

Otros usuarios creados por el seed tienen el mismo sufijo de contraseña (123). Revisa scripts/seed_data.py para ver la lista completa.


Desarrollo local sin Docker

Útil cuando necesitas depurar el código con breakpoints o acelerar el ciclo de desarrollo. Requiere que PostgreSQL y Redis sí corran en Docker (o instalación nativa).

Requisitos adicionales

Herramienta Versión Descarga
Python 3.11 o 3.12 https://www.python.org/downloads/
Node.js (con npm) 18 LTS https://nodejs.org/
pip incluido con Python

Iniciar solo la base de datos y Redis

docker compose up -d postgres redis

Backend (FastAPI)

cd backend

# Crear entorno virtual (solo la primera vez)
python -m venv ../.venv

# Activar entorno virtual
# Linux / macOS:
source ../.venv/bin/activate
# Windows (PowerShell):
..\.venv\Scripts\Activate.ps1
# Windows (CMD):
..\.venv\Scripts\activate.bat

# Instalar dependencias (solo la primera vez o cuando cambie requirements.txt)
pip install -r requirements.txt

# Ejecutar migraciones de base de datos
alembic upgrade head

# Iniciar servidor de desarrollo
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

Si uvicorn no se encuentra, asegúrate de que el entorno virtual está activado ((.venv) debe aparecer en tu terminal).

Frontend Clientes

cd frontend-client

# Instalar dependencias (solo la primera vez)
npm install

# Iniciar servidor de desarrollo en puerto 3000
npm run dev

Frontend Interno (staff)

cd frontend-internal

# Instalar dependencias (solo la primera vez)
npm install

# Iniciar servidor de desarrollo en puerto 3001
npm run dev

Los dos frontends tienen puertos distintos (3000 y 3001) para que no haya conflicto cuando corren al mismo tiempo.

Workers Celery (opcional en desarrollo)

Necesario solo si desarrollas funcionalidades de notificaciones o SLAs automáticos.

cd workers

# Activar el mismo entorno virtual del backend:
# Linux / macOS:
source ../.venv/bin/activate
# Windows:
..\.venv\Scripts\Activate.ps1

pip install -r requirements.txt

# Worker principal
celery -A app.celery worker --loglevel=info

# Scheduler de tareas periódicas (en otra terminal)
celery -A app.celery beat --loglevel=info --schedule=/tmp/celerybeat-schedule

Arquitectura del proyecto

ServiceManagerWeb/
├── backend/                    # Aplicación FastAPI (Python 3.11)
│   ├── app/
│   │   ├── main.py             # Punto de entrada, lifespan, middlewares
│   │   ├── api/v1/
│   │   │   ├── router.py       # Registro de todos los routers
│   │   │   └── endpoints/      # Endpoints REST por dominio
│   │   ├── core/               # Config, seguridad, base de datos, caché
│   │   ├── models/             # Modelos SQLAlchemy (ORM)
│   │   ├── services/           # Lógica de negocio
│   │   └── middleware/         # Tenant context, Correlation ID
│   ├── migrations/             # Migraciones Alembic
│   ├── tests/                  # Pruebas backend
│   └── requirements.txt        # Dependencias Python
│
├── frontend-client/            # Portal de clientes (SvelteKit + TypeScript)
│   └── src/routes/             # Páginas: login, tickets, perfil
│
├── frontend-internal/          # Panel de staff (SvelteKit + TypeScript)
│   └── src/routes/             # Páginas: dashboard, tickets, reportes, auditoría
│
├── workers/                    # Tareas asíncronas Celery
│   └── app/tasks/              # email_tasks.py, sla_tasks.py, etc.
│
├── docker/                     # Dockerfiles y configuración Nginx
├── db/                         # schema.sql inicial
├── docs/                       # Documentación técnica adicional
├── scripts/                    # seed_data.py, setup-dev.sh, etc.
├── docker-compose.yml          # Orquestación completa
└── .env.example                # Plantilla de variables de entorno

Stack tecnológico

Backend: Python 3.11 · FastAPI · Pydantic v2 · SQLAlchemy 2.0 (async) · Alembic · Argon2 · PyJWT · Celery · Redis

Frontend: Node.js 18 · SvelteKit · TypeScript · TailwindCSS · Zod

Infraestructura: PostgreSQL 15 · Redis 7 · Docker Compose · Nginx


Roles y permisos

Personal interno (staff)

Rol Descripción
ADMIN Control total del sistema
SUPPORT_MANAGER Gestión de equipos y configuración de SLAs
AGENT Atención y resolución de tickets
AUDITOR Solo lectura para revisiones y cumplimiento

Clientes

Rol Descripción
CLIENT_ADMIN Gestión de su organización cliente
CLIENT_USER Creación y seguimiento de sus propios tickets

Comandos útiles

Docker Compose

# Levantar todos los servicios (segundo plano)
docker compose up -d

# Levantar con herramientas de desarrollo
docker compose --profile dev up -d

# Ver logs en tiempo real de todos los servicios
docker compose logs -f

# Ver logs de un servicio específico
docker compose logs -f backend
docker compose logs -f frontend-internal

# Detener todos los servicios (mantiene los datos)
docker compose down

# Detener Y borrar todos los volúmenes (¡borra la base de datos!)
docker compose down -v

# Reconstruir imagen de un servicio (después de cambiar Dockerfile o requirements)
docker compose build backend
docker compose up -d backend

# Reiniciar un servicio
docker compose restart backend

Base de datos (Alembic)

# Aplicar todas las migraciones pendientes
cd backend
alembic upgrade head

# Ver estado de migraciones
alembic current

# Revertir última migración
alembic downgrade -1

# Crear nueva migración (después de modificar models/)
alembic revision --autogenerate -m "nombre descriptivo del cambio"

# Con Docker:
docker exec servicemanager-backend alembic upgrade head

Calidad de código

cd backend

# Linter y auto-fix
ruff check . --fix

# Formateador
black .

# Verificación de tipos
mypy .

# Todo de una vez
ruff check . --fix && black . && mypy .

Pruebas (testing)

Backend

cd backend

# Ejecutar todas las pruebas
pytest

# Con cobertura detallada
pytest --cov=app --cov-report=html

# Abrir reporte de cobertura (Linux/macOS)
open htmlcov/index.html
# Windows
start htmlcov/index.html

# Prueba específica
pytest tests/test_auth.py -v

# Con Docker
docker exec servicemanager-backend pytest -v --cov=app

Frontend

cd frontend-internal   # o frontend-client
npm test               # Ejecutar una vez
npm run test:watch     # Modo observador

Solución de problemas

El backend no inicia — error en DATABASE_URL

Síntoma: El contenedor servicemanager-backend reinicia continuamente.

Causa frecuente: El archivo .env no existe o tiene DATABASE_URL apuntando a localhost en lugar del nombre del servicio Docker postgres.

Solución:

# Verificar que .env existe
ls .env   # Linux/macOS
dir .env  # Windows

# Si no existe, crearlo
cp .env.example .env     # Linux/macOS
Copy-Item .env.example .env  # Windows PowerShell

# Verificar el valor correcto en .env:
# DATABASE_URL=postgresql+asyncpg://servicemanager:servicemanager123@postgres:5432/servicemanager
#                                                                      ^^^^^^^
#                                                          Nombre de servicio Docker, NO localhost

Error 500 en login / "connect ECONNREFUSED"

Síntoma: El frontend muestra error 500 al hacer login, o la consola del navegador muestra ECONNREFUSED 127.0.0.1:8000.

Causa: El proxy de Vite no encuentra el backend.

Solución en Docker: El proxy ya está configurado para usar PUBLIC_API_URL. Verifica en docker-compose.yml que frontend-internal y frontend-client tienen:

environment:
  - PUBLIC_API_URL=http://backend:8000

Después reinicia:

docker compose restart frontend-internal frontend-client

Solución en desarrollo local: Asegúrate de que el backend está corriendo:

curl http://localhost:8000/health
# Debe responder: {"status": "ok", ...}

El frontend-internal y frontend-client usan el mismo puerto localmente

Síntoma: Al correr ambos frontends sin Docker, uno de los dos falla con Port 3000 is already in use.

Solución:

  • frontend-client → usa el puerto 3000 (por defecto con npm run dev)
  • frontend-internal → usa el puerto 3001 (configurado en vite.config.js)

Nunca hay conflicto si los iniciaste con npm run dev en cada carpeta por separado. Si aún hay conflicto, mata el proceso en ese puerto:

# Linux / macOS
lsof -ti:3000 | xargs kill -9

# Windows (PowerShell)
Get-Process -Id (Get-NetTCPConnection -LocalPort 3000).OwningProcess | Stop-Process -Force

El tenant slug es incorrecto al hacer login

Síntoma: Login falla con "credenciales inválidas" aunque el email y contraseña son correctos.

Causa: El campo tenant_slug no corresponde a ningún tenant en la base de datos.

Solución:

# Ver los tenants disponibles
docker exec servicemanager-backend python -c "
import asyncio
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy import text
import os
async def main():
    engine = create_async_engine(os.environ['DATABASE_URL'])
    async with AsyncSession(engine) as s:
        result = await s.execute(text('SELECT slug, name FROM tenants'))
        for row in result:
            print(row)
asyncio.run(main())
"

Tenant por defecto (después del seed): aduanasoft-demo


Puerto ocupado — cambiar puertos de los servicios

Edita docker-compose.yml y modifica solo el número izquierdo del mapeo de puertos:

# Ejemplo: mover el backend al puerto 9000
backend:
  ports:
    - "9000:8000"   # accesible en localhost:9000

# Ejemplo: mover el frontend al puerto 4000
frontend-client:
  ports:
    - "4000:3000"   # accesible en localhost:4000

Migraciones fallidas — alembic upgrade head da error

# Verificar el estado actual
docker exec servicemanager-backend alembic current

# Si hay conflicto, hacer downgrade hasta la base y volver a subir
docker exec servicemanager-backend alembic downgrade base
docker exec servicemanager-backend alembic upgrade head

Módulo Python no encontrado (ModuleNotFoundError)

Con Docker: El módulo no está en requirements.txt o la imagen no fue reconstruida.

# Reconstruir la imagen del backend
docker compose build backend
docker compose up -d backend

Local: El entorno virtual no está activado.

# Verificar que el venv está activo (debe aparecer (.venv) en el prompt)
which python   # Linux/macOS — debe apuntar a .venv/
# Windows:
where python   # debe apuntar a .venv\Scripts\python.exe

npm: command not found o versión de Node incorrecta

node --version   # Debe ser v18.x o superior
npm --version    # Debe ser 9.x o superior

Si Node no está instalado, descárgalo desde https://nodejs.org/ (elige "LTS").

En macOS con Homebrew:

brew install node@18

En Linux (Ubuntu/Debian):

curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

docker-compose no se reconoce como comando

En versiones modernas de Docker Desktop, el comando es docker compose (con espacio, sin guion). Si tienes instalación separada de Docker Compose v1, usa docker-compose (con guion).


Logs de los contenedores

# Ver qué está fallando
docker compose logs backend --tail=50
docker compose logs frontend-internal --tail=50
docker compose logs postgres --tail=20

Contribución

  1. Haz fork del proyecto
  2. Crea una rama de funcionalidad: git checkout -b feature/nombre-funcionalidad
  3. Realiza tus cambios siguiendo las convenciones del proyecto
  4. Ejecuta las pruebas: pytest y el linter: ruff check .
  5. Haz commit con un mensaje descriptivo: git commit -m "feat: agregar exportación a CSV"
  6. Sube tu rama: git push origin feature/nombre-funcionalidad
  7. Abre un Pull Request hacia main

Convenciones de nombres

  • Modelos: PascalCaseUser, Ticket, TenantOrganization
  • Endpoints (URL): kebab-case/api/v1/user-management/
  • Componentes Svelte: PascalCase.svelteTicketCard.svelte
  • Stores: camelCaseticketStore.ts

Historial de versiones

Versión Descripción
v1.15.1 Módulo de reportes implementado
v1.14.x Mejoras al módulo de auditoría
v1.13.x Sistema de SLAs automático
v1.12.x Notificaciones por email
v1.0.0 MVP inicial — tickets, tenants, autenticación

Licencia

Propietario — Aduanasoft © 2026. Todos los derechos reservados.

Description
sistema interno de gestion de tickets
https://servicemanager.aduanasoft.com
Readme 2.4 MiB
Languages
Python 53.1%
Svelte 38.3%
TypeScript 3.4%
PowerShell 1.7%
PLpgSQL 1.2%
Other 2.3%