docs: README completo para Windows/Linux/macOS + fix conflicto de puertos
- README.md reescrito con instrucciones detalladas para principiantes y expertos * Tabla de contenidos con 14 secciones * Inicio rápido con Docker (Windows, Linux, macOS) * Configuración de variables de entorno con explicaciones * Sección de desarrollo local sin Docker * Comandos útiles (Docker, Alembic, calidad de código, testing) * Solución de problemas extensa (puertos, módulos, tenant, migraciones, Node.js) * Historial de versiones - Fix: conflicto de puertos cuando ambos frontends corren en local * frontend-internal/vite.config.js: usa PORT=3001 por defecto (3000 en Docker) * frontend-internal/package.json: dev script sin puerto hardcodeado * docker-compose.yml: frontend-internal recibe PORT=3000 como variable de env
This commit is contained in:
835
README.md
835
README.md
@@ -1,178 +1,755 @@
|
||||
# ServiceManagerWeb - Mesa de Ayuda B2B
|
||||
# ServiceManagerWeb — Mesa de Ayuda B2B
|
||||
|
||||
Sistema multi-tenant de Mesa de Ayuda/Soporte Técnico empresarial para Aduanasoft.
|
||||
> **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.
|
||||
|
||||
## Arquitectura
|
||||
---
|
||||
|
||||
- **Frontend**: SvelteKit + TypeScript (portal clientes + panel interno)
|
||||
- **Backend**: Python FastAPI + Pydantic v2
|
||||
- **Workers**: Celery + Redis (notificaciones, SLAs, jobs)
|
||||
- **BD**: PostgreSQL + Alembic migrations
|
||||
- **Auth**: JWT + Refresh tokens + 2FA opcional (TOTP)
|
||||
- **Infra**: Docker Compose local, preparado para producción
|
||||
## Tabla de Contenidos
|
||||
|
||||
## Estructura del Monorepo
|
||||
1. [Requisitos previos](#requisitos-previos)
|
||||
2. [Inicio rápido con Docker (recomendado)](#inicio-rápido-con-docker-recomendado)
|
||||
3. [Configuración de variables de entorno](#configuración-de-variables-de-entorno)
|
||||
4. [Cargar datos de prueba](#cargar-datos-de-prueba)
|
||||
5. [URLs y puertos por defecto](#urls-y-puertos-por-defecto)
|
||||
6. [Credenciales de prueba](#credenciales-de-prueba)
|
||||
7. [Desarrollo local sin Docker](#desarrollo-local-sin-docker)
|
||||
8. [Arquitectura del proyecto](#arquitectura-del-proyecto)
|
||||
9. [Roles y permisos](#roles-y-permisos)
|
||||
10. [Comandos útiles](#comandos-útiles)
|
||||
11. [Pruebas (testing)](#pruebas-testing)
|
||||
12. [Solución de problemas](#solución-de-problemas)
|
||||
13. [Contribución](#contribución)
|
||||
14. [Historial de versiones](#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](#desarrollo-local-sin-docker).
|
||||
|
||||
### Verificar que Docker esté corriendo
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
git clone https://git.aduanasoft.com/ADUANASOFT/service_manager.git
|
||||
cd service_manager
|
||||
```
|
||||
|
||||
### Paso 2 — Crear el archivo de variables de entorno
|
||||
|
||||
**Linux / macOS:**
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
**Windows (PowerShell):**
|
||||
```powershell
|
||||
Copy-Item .env.example .env
|
||||
```
|
||||
|
||||
**Windows (CMD):**
|
||||
```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
|
||||
|
||||
```bash
|
||||
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):
|
||||
> ```bash
|
||||
> docker compose --profile dev up -d
|
||||
> ```
|
||||
|
||||
### Paso 4 — Verificar que todo esté funcionando
|
||||
|
||||
```bash
|
||||
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](#solución-de-problemas).
|
||||
|
||||
### Paso 5 — Cargar datos de ejemplo (opcional pero recomendado)
|
||||
|
||||
```bash
|
||||
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:
|
||||
> - Adminer (gestor visual de PostgreSQL): http://localhost:8080
|
||||
> - MailHog (pruebas de email): http://localhost:8025
|
||||
> - Redis Commander (inspector de Redis): http://localhost:8081
|
||||
|
||||
---
|
||||
|
||||
## 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:**
|
||||
```bash
|
||||
openssl rand -base64 32 # Genera SECRET_KEY
|
||||
openssl rand -base64 32 # Genera JWT_SECRET_KEY
|
||||
```
|
||||
|
||||
**Windows (PowerShell):**
|
||||
```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:
|
||||
|
||||
```dotenv
|
||||
# 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):**
|
||||
```bash
|
||||
docker exec servicemanager-backend python /scripts/seed_data.py
|
||||
```
|
||||
|
||||
**Sin Docker:**
|
||||
```bash
|
||||
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:
|
||||
|
||||
```yaml
|
||||
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
|
||||
|
||||
```bash
|
||||
docker compose up -d postgres redis
|
||||
```
|
||||
|
||||
### Backend (FastAPI)
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
cd frontend-client
|
||||
|
||||
# Instalar dependencias (solo la primera vez)
|
||||
npm install
|
||||
|
||||
# Iniciar servidor de desarrollo en puerto 3000
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Frontend Interno (staff)
|
||||
|
||||
```bash
|
||||
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.
|
||||
|
||||
```bash
|
||||
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/ # FastAPI app
|
||||
├── frontend-client/ # SvelteKit app para clientes
|
||||
├── frontend-internal/ # SvelteKit app para staff interno
|
||||
├── workers/ # Celery tasks
|
||||
├── db/ # Migrations y esquemas
|
||||
├── docker/ # Dockerfiles específicos
|
||||
├── docs/ # Documentación adicional
|
||||
├── scripts/ # Scripts de desarrollo/despliegue
|
||||
├── 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 # Variables de entorno
|
||||
└── .env.example # Plantilla de variables de entorno
|
||||
```
|
||||
|
||||
## Stack Tecnológico
|
||||
### Stack tecnológico
|
||||
|
||||
### Backend (Python)
|
||||
- FastAPI (async)
|
||||
- Pydantic v2
|
||||
- SQLAlchemy 2.0 (async)
|
||||
- Alembic (migrations)
|
||||
- Argon2 (hashing passwords)
|
||||
- PyJWT
|
||||
- Celery + Redis
|
||||
**Backend:** Python 3.11 · FastAPI · Pydantic v2 · SQLAlchemy 2.0 (async) · Alembic · Argon2 · PyJWT · Celery · Redis
|
||||
|
||||
### Frontend (JavaScript/TypeScript)
|
||||
- SvelteKit
|
||||
- TypeScript
|
||||
- TailwindCSS
|
||||
- shadcn/ui o similar
|
||||
- Zod (validación)
|
||||
**Frontend:** Node.js 18 · SvelteKit · TypeScript · TailwindCSS · Zod
|
||||
|
||||
### Infraestructura
|
||||
- PostgreSQL 15+
|
||||
- Redis 7+
|
||||
- Docker & Docker Compose
|
||||
- Nginx (reverse proxy)
|
||||
**Infraestructura:** PostgreSQL 15 · Redis 7 · Docker Compose · Nginx
|
||||
|
||||
## Dominios del Sistema
|
||||
---
|
||||
|
||||
1. **Auth**: Usuarios, roles, permisos, 2FA
|
||||
2. **Tenants**: Multi-tenancy, organizaciones
|
||||
3. **Tickets**: Gestión de tickets, estados, SLAs
|
||||
4. **Notifications**: Email, plantillas, logs
|
||||
5. **Audit**: Bitácora de acciones
|
||||
## Roles y permisos
|
||||
|
||||
## Roles de Usuario
|
||||
|
||||
### Internos (Staff)
|
||||
- `ADMIN`: Control total del sistema
|
||||
- `SUPPORT_MANAGER`: Gestión de equipos y SLAs
|
||||
- `AGENT`: Atención de tickets
|
||||
- `AUDITOR`: Solo lectura para auditoría
|
||||
### 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
|
||||
- `CLIENT_ADMIN`: Gestión de organización cliente
|
||||
- `CLIENT_USER`: Creación y seguimiento de tickets
|
||||
| Rol | Descripción |
|
||||
|-----|-------------|
|
||||
| `CLIENT_ADMIN` | Gestión de su organización cliente |
|
||||
| `CLIENT_USER` | Creación y seguimiento de sus propios tickets |
|
||||
|
||||
## Quick Start
|
||||
---
|
||||
|
||||
## Comandos útiles
|
||||
|
||||
### Docker Compose
|
||||
|
||||
```bash
|
||||
# Clonar y configurar
|
||||
git clone <repo>
|
||||
cd ServiceManagerWeb
|
||||
cp .env.example .env
|
||||
# Levantar todos los servicios (segundo plano)
|
||||
docker compose up -d
|
||||
|
||||
# Levantar servicios
|
||||
docker-compose up -d
|
||||
# Levantar con herramientas de desarrollo
|
||||
docker compose --profile dev up -d
|
||||
|
||||
# Verificar estado
|
||||
docker-compose ps
|
||||
# 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
|
||||
```
|
||||
|
||||
## URLs por Defecto
|
||||
|
||||
- Frontend Clientes: http://localhost:3000
|
||||
- Frontend Interno: http://localhost:3001
|
||||
- API Backend: http://localhost:8000
|
||||
- API Docs: http://localhost:8000/docs
|
||||
- Adminer (DB): http://localhost:8080
|
||||
|
||||
## Scripts de Desarrollo
|
||||
### Base de datos (Alembic)
|
||||
|
||||
```bash
|
||||
# Backend
|
||||
# Aplicar todas las migraciones pendientes
|
||||
cd backend
|
||||
python -m uvicorn app.main:app --reload --port 8000
|
||||
alembic upgrade head
|
||||
|
||||
# Frontend Cliente
|
||||
cd frontend-client
|
||||
npm run dev -- --port 3000
|
||||
# Ver estado de migraciones
|
||||
alembic current
|
||||
|
||||
# Frontend Interno
|
||||
cd frontend-internal
|
||||
npm run dev -- --port 3001
|
||||
# Revertir última migración
|
||||
alembic downgrade -1
|
||||
|
||||
# Workers
|
||||
cd workers
|
||||
celery -A app.worker worker --loglevel=info
|
||||
celery -A app.worker beat --loglevel=info
|
||||
# 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
|
||||
```
|
||||
|
||||
## Testing
|
||||
### Calidad de código
|
||||
|
||||
```bash
|
||||
# Backend tests
|
||||
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
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
|
||||
# Ejecutar todas las pruebas
|
||||
pytest
|
||||
|
||||
# Frontend tests
|
||||
cd frontend-client
|
||||
npm test
|
||||
cd ../frontend-internal
|
||||
npm test
|
||||
# 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
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error 500 en Login / Proxy Error
|
||||
|
||||
**Síntoma**: Error 500 al intentar hacer login, o error de proxy de Vite "connect ECONNREFUSED".
|
||||
|
||||
**Causa**: Configuración incorrecta de la comunicación entre servicios de Docker.
|
||||
|
||||
**Solución**:
|
||||
1. En desarrollo con Docker, los servicios usan nombres de servicio (no `localhost`)
|
||||
2. Verificar `vite.config.js`: el proxy debe apuntar a `http://backend:8000`
|
||||
3. Verificar `docker-compose.yml`: `PUBLIC_API_URL` debe ser `http://backend:8000`
|
||||
4. Después de cambios, reiniciar contenedor: `docker-compose restart frontend-internal`
|
||||
|
||||
**Nota**: Para desarrollo local sin Docker, cambiar el proxy a `http://localhost:8000`.
|
||||
|
||||
### Tenant Slug Incorrecto
|
||||
|
||||
**Síntoma**: Error de autenticación incluso con credenciales correctas.
|
||||
|
||||
**Causa**: El `tenant_slug` en el login no coincide con los tenants en la BD.
|
||||
|
||||
**Solución**:
|
||||
1. Verificar tenants existentes: `docker exec servicemanager-backend python check_tenants.py`
|
||||
2. Actualizar el tenant_slug en el código de login
|
||||
3. Tenants por defecto: `aduanasoft-demo`, `test-tenant`
|
||||
|
||||
### Credenciales de Prueba
|
||||
### Frontend
|
||||
|
||||
```bash
|
||||
cd frontend-internal # o frontend-client
|
||||
npm test # Ejecutar una vez
|
||||
npm run test:watch # Modo observador
|
||||
```
|
||||
Email: admin@aduanasoft.com
|
||||
Password: admin123
|
||||
Tenant: aduanasoft-demo
|
||||
Role: ADMIN
|
||||
|
||||
---
|
||||
|
||||
## 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:**
|
||||
```bash
|
||||
# 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:
|
||||
```yaml
|
||||
environment:
|
||||
- PUBLIC_API_URL=http://backend:8000
|
||||
```
|
||||
Después reinicia:
|
||||
```bash
|
||||
docker compose restart frontend-internal frontend-client
|
||||
```
|
||||
|
||||
**Solución en desarrollo local:** Asegúrate de que el backend está corriendo:
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
# 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:**
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```yaml
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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.
|
||||
```bash
|
||||
# Reconstruir la imagen del backend
|
||||
docker compose build backend
|
||||
docker compose up -d backend
|
||||
```
|
||||
|
||||
**Local:** El entorno virtual no está activado.
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
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:
|
||||
```bash
|
||||
brew install node@18
|
||||
```
|
||||
|
||||
En Linux (Ubuntu/Debian):
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
# 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. Fork del proyecto
|
||||
2. Crear feature branch (`git checkout -b feature/nueva-funcionalidad`)
|
||||
3. Commit cambios (`git commit -am 'Agregar nueva funcionalidad'`)
|
||||
4. Push a branch (`git push origin feature/nueva-funcionalidad`)
|
||||
5. Crear Pull Request
|
||||
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**: `PascalCase` → `User`, `Ticket`, `TenantOrganization`
|
||||
- **Endpoints (URL)**: `kebab-case` → `/api/v1/user-management/`
|
||||
- **Componentes Svelte**: `PascalCase.svelte` → `TicketCard.svelte`
|
||||
- **Stores**: `camelCase` → `ticketStore.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
|
||||
Propietario — Aduanasoft © 2026. Todos los derechos reservados.
|
||||
@@ -189,6 +189,7 @@ services:
|
||||
- NODE_ENV=${ENVIRONMENT:-development}
|
||||
- PUBLIC_API_URL=http://backend:8000
|
||||
- PUBLIC_APP_NAME=ServiceManager Admin
|
||||
- PORT=3000 # El contendor corre en 3000; docker mapea 3001:3000 al host
|
||||
volumes:
|
||||
- ./frontend-internal:/app
|
||||
- /app/node_modules
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite dev --port 3000 --host 0.0.0.0",
|
||||
"dev": "vite dev --host 0.0.0.0",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview --port 3000 --host 0.0.0.0",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
|
||||
@@ -4,7 +4,8 @@ import { defineConfig } from 'vite';
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()],
|
||||
server: {
|
||||
port: 3000,
|
||||
// Puerto: 3001 por defecto en local; Docker lo sobreescribe con PORT=3000
|
||||
port: parseInt(process.env.PORT || '3001'),
|
||||
host: '0.0.0.0',
|
||||
watch: {
|
||||
usePolling: true,
|
||||
@@ -19,7 +20,7 @@ export default defineConfig({
|
||||
}
|
||||
},
|
||||
preview: {
|
||||
port: 3000,
|
||||
port: parseInt(process.env.PORT || '3001'),
|
||||
host: '0.0.0.0'
|
||||
},
|
||||
build: {
|
||||
|
||||
Reference in New Issue
Block a user