API REST para gestión y envío de emails con plantillas HTML, autenticación JWT, verificación de cuentas y administración de usuarios. Está construida con FastAPI, PostgreSQL y una arquitectura en capas basada en principios SOLID.
- Registro y autenticación con JWT
- Verificación de email con token
- Endpoint interno de email transaccional para aplicaciones integradas
- Bandeja de salida paginada
- Reenvío de emails enviados
- Envío con texto plano, HTML o plantillas Jinja2
- Guardado de clave SMTP personal
- Gestión administrativa de usuarios y estados
app/
docs/
prds/
Dockerfile
docker-compose.yml
requirements.txt
cp .env.example .env
docker compose up -d postgres
docker compose run --rm email-api alembic upgrade head
docker compose up --build email-apiQueda disponible en:
- API:
http://localhost:8001 - Swagger:
http://localhost:8001/docs - Healthcheck:
http://localhost:8001/health - PostgreSQL:
localhost:${POSTGRES_HOST_PORT:-5432}
La guía Docker detallada está en docs/docker.md.
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
alembic upgrade head
uvicorn app.main:app --reload --port 8001Si ejecutas la base de datos fuera de Docker, ajusta PGHOST, PGPORT, PGUSER, PGPASSWORD y PGDATABASE en tu .env.
Si el puerto 5432 ya está ocupado en tu máquina, cambia POSTGRES_HOST_PORT en .env por otro valor, por ejemplo 5433.
El esquema ya no se crea automaticamente al iniciar la API. Debes aplicar migraciones antes de levantar el servidor:
alembic upgrade headComandos utiles:
alembic current
alembic history
alembic downgrade -1database.sql se mantiene como bootstrap completo para entornos nuevos, pero Alembic es la fuente de verdad para la evolucion incremental del esquema.
Ejemplo mínimo:
PORT=8001
HOST=0.0.0.0
DOMAIN=http://localhost:8001/
ENVIRONMENT=development
SECRET_KEY=change-this-secret-key-in-production
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
PGHOST=localhost
PGPORT=5432
POSTGRES_HOST_PORT=5432
PGUSER=admin
PGPASSWORD=admin123
PGDATABASE=email_db
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=
SMTP_PASSWORD=
# Integración con SoftStack u otros servicios internos
INTERNAL_API_KEY=replace-with-a-long-random-secretNotas:
ENVIRONMENT=developmentusaMockEmailSenderENVIRONMENT=productionusa SMTP realPOST /emails/transactionalrequiereX-Internal-API-Keyy usa el sender configurado; no crea registros en la bandeja PostgreSQLINTERNAL_API_KEYdebe coincidir con la variableEMAIL_SERVICE_API_KEYdel backend consumidor- En Docker Compose,
PGHOSTse sustituye porpostgres POSTGRES_HOST_PORTsolo controla el puerto expuesto en tu máquina host
curl -X POST http://localhost:8001/api/auth/register \
-H "Content-Type: application/json" \
-d '{"name":"Juan","email":"juan@example.com","password":"mipassword123"}'curl -X POST http://localhost:8001/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"juan@example.com","password":"mipassword123"}'curl http://localhost:8001/api/users/me \
-H "Authorization: Bearer <token>"Las plantillas viven en app/templates/ y se resuelven por nombre desde los endpoints de envío. Algunas plantillas existentes:
welcome.htmlaccount_approved.htmlwelcome_active_count_educonnect.htmlwelcome_inactive_count_educonnect.html
- docs/README.md: índice navegable de documentación para Obsidian
- docs/obsidian-map.md: mapa gráfico y relacional de documentación
- prds/README.md: índice funcional de PRDs agrupado por dominio
- docs/docker.md: guía de Docker y Compose
- docs/API_REFERENCE.md: referencia de endpoints
- docs/architecture.md: arquitectura en capas
- docs/TROUBLESHOOTING.md: problemas comunes
- docs/System_Artifact.md: artefacto general del sistema
- docs/alembic.md: que es Alembic, como usarlo y flujo en este proyecto
- docs/gitflow.md: flujo de trabajo Git
La suite de tests unitarios cubre servicios, repositorios, schemas, seguridad, middlewares y un smoke test de la app, sin necesidad de PostgreSQL ni SMTP (usa fakes y SQLite en memoria).
pip install -r requirements-dev.txt
pytestGuía completa (estructura, estrategia y cobertura) en docs/testing.md.
Durante desarrollo, la app expone autorecarga cuando se ejecuta con docker compose o uvicorn --reload. Para correos reales con Gmail, usa contraseña de aplicación y no la contraseña normal de la cuenta.