Skip to content

Repository files navigation

Taskito

El desarrollo de Taskito se guio por principios SOLID y una arquitectura por capas (routers → servicios → repositorios/ORM → esquemas), priorizando seguridad, mantenibilidad y pruebas desde el inicio. Se optó por un enfoque iterativo: primero un “esqueleto” funcional end-to-end, luego endurecimiento de seguridad y validaciones, y finalmente observabilidad y experiencia de usuario.

En el frontend se usó Next.js (App Router) para (mayoritariamente client-side para velocidad de desarrollo) y una SPA fluida, con TailwindCSS para estilos utilitarios y shadcn/ui para componentes accesibles y consistentes. La gestión de estado global se resolvió con Redux Toolkit, y se alinearon las validaciones con el backend para evitar discrepancias (errores claros en formularios y reglas compartidas). Nginx actúa como reverse proxy y punto de terminación TLS, sirviendo estáticos y enrutando a la API.

El backend se implementó con FastAPI por su tipado, rendimiento y documentación automática. Pydantic define esquemas de entrada/salida y garantiza validación robusta. SQLAlchemy se emplea como ORM, aprovechando el binding de parámetros para mitigar inyecciones SQL y mantener una capa de persistencia limpia y testeable. La autenticación se basa en JWT con expiración configurable y control de permisos (roles), y se añadieron middlewares y políticas de seguridad (CORS, CSP estricta para reducir superficie de XSS y carga de recursos no confiables, y SSL en el proxy). Para protección en formularios se utilizó el patrón de doble envío (double submit) de CSRF en las interacciones que lo requieren. Redis apoya almacenamiento del rate limiting; SlowAPI impone límites diferenciados para endpoints de autenticación y generales.

Las pruebas: Pytest para unitarias y de servicios (incluyendo rutas críticas de error y seguridad), mientras que Cypress cubre flujos end-to-end y componentes del frontend (autenticación, CRUD de tareas, filtros y paginación). Se priorizó la trazabilidad de errores mediante respuestas HTTP consistentes y mensajes de validación comprensibles. En integración local, Docker Compose orquesta todos los contenedores (frontend, api, db, redis, nginx y observabilidad), garantizando reproducibilidad y un entorno cercano a producción.

En observabilidad, Grafana + Loki + Promtail permiten centralizar logs y paneles básicos para salud del sistema. La API expone healthchecks y métricas esenciales, y el proxy facilita diagnóstico con access logs. Finalmente, se mantuvo coherencia entre frontend y backend: mismas reglas de validación, manejo de errores uniforme y tipado estricto, lo que redujo defectos y aceleró la iteración.

Herramientas y tecnologías clave:

  • Frontend: Next.js, TailwindCSS, shadcn/ui, Redux Toolkit, Cypress.
  • Backend: FastAPI, SQLAlchemy, Pydantic, Pytest, SlowAPI (rate limiting).
  • Infra/observabilidad: Docker Compose, Nginx (SSL), Redis, Grafana, Loki, Promtail.
  • Seguridad: JWT, CSRF (double submit), CSP estricta, CORS, SQL parametrizado, TLS.

Guía de instalación y puesta en marcha

Esta guía explica cómo instalar y ejecutar todo el proyecto Taskito en tu entorno local usando Docker Compose. Incluye frontend (Next.js), backend (FastAPI), base de datos (PostgreSQL), Redis, Nginx (con SSL autofirmado), Grafana y Loki/Promtail para logs.

Resumen

  • Frontend: Next.js (puerto interno 5173) servido tras Nginx.
  • Backend: FastAPI (puerto interno 8000) tras Nginx con prefijo /api.
  • DB: PostgreSQL 14 (volumen persistente).
  • Cache/Queue: Redis 7 (volumen persistente).
  • Observabilidad: Grafana + Loki + Promtail.
  • Reverse proxy: Nginx (HTTP 80 / HTTPS 443) con certificado autofirmado.

Rutas rápidas:

1) Requisitos previos (Windows)

  • Docker Desktop (con WSL2 habilitado)
  • Git
  • Puertos libres: 80, 443, 5173, 8000, 3000, 3100, 5432, 6379
  • Nota SSL: el certificado es autofirmado (desarrollo). El navegador mostrará advertencia la primera vez: acepta la excepción para continuar.

Opcional (solo si quieres correr sin Docker):

  • Python 3.11
  • Node.js 18+ y npm 9+

2) Clonar el repositorio

git clone https://github.com/ReylanLugo/taskito.git
cd taskito

3) Crear archivo de entorno .env.local (raíz)

Docker Compose utiliza este archivo para configurar api, postgres y frontend. Crea ./.env.local con el contenido:

# Database configurationPOSTGRES_USER=postgresPOSTGRES_PASSWORD=dev_passwordPOSTGRES_DB=taskitoPOSTGRES_PORT=5432# Redis configurationREDIS_HOST=redisREDIS_PORT=6379# API configurationAPI_PORT=8000# Additional app settingsDEBUG=TrueSECRET_KEY=taskito_dev_secret_key# Authentication settingsALGORITHM=HS256ACCESS_TOKEN_EXPIRE_MINUTES=30REFRESH_TOKEN_SECRET="anything"REFRESH_TOKEN_EXPIRE_MINUTES=3600RATE_LIMIT_ENABLED=TrueRATE_LIMIT_REQUESTS=100RATE_LIMIT_WINDOW="minutes"RATE_LIMIT_AUTH_REQUESTS=100RATE_LIMIT_AUTH_WINDOW="minutes"CORS_ALLOW_ORIGINS=["http://localhost:3000", "http://localhost:5173", "https://localhost"]## FrontendAUTH_SECRET="sF7of/9pD2Hsq7MeCgI2x1qyAxABTpPxCPEKCM1VnYQ="AUTH_TRUST_HOST=trueNEXTAUTH_URL=http://localhost:3000NEXTAUTH_SECRET="sF7of/9pD2Hsq7MeCgI2x1qyAxABTpPxCPEKCM1VnYQ="NEXT_PUBLIC_BACKEND_URL=http://api:8000NEXT_PUBLIC_API_URL=http://localhost:3000

Notas:

  • El backend (backend/app/config.py) ya define CORS para http(s)://localhost y :3000.
  • El docker-compose.yml exporta al frontend: NEXT_PUBLIC_API_URL=https://localhost/api y NODE_TLS_REJECT_UNAUTHORIZED=0 (permite SSL autofirmado en dev).

4) Levantar todo con Docker

(Pydantic necesita tener instalado rust y su compilador) Desde la raíz del proyecto:

docker compose up -d --build
Si algo sale mal para un hard reset y limpieza de todos los contenedores:
docker compose down -v --rmi all --remove-orphans; docker compose build --no-cache; docker compose up -d

Servicios que se levantarán (según docker-compose.yml):

  • nginx: reverse proxy, puertos 80/443.
  • api: FastAPI en 8000 (volumen ./backend:/app). Ejecuta startup.sh (espera DB, aplica migraciones, inicia Uvicorn).
  • postgres: 14 (volumen persistente postgres-data).
  • redis: 7 (volumen persistente redis-data).
  • loki y promtail: recolección de logs.
  • grafana: dashboards (puerto interno 3000), accesible por Nginx en /grafana.
  • frontend: Next.js (puerto interno 5173), accesible por Nginx en /.

5) Verificar estado

  • Ver contenedores:
docker compose ps
  • Revisar logs (Grafana):
(user: `admin`, pass: `admin`)
http://localhost:3000/d/taskito-logs/taskito-logs?orgId=1&from=now-1h&to=now&timezone=browser
  • Probar en el navegador:

Si el navegador advierte por certificado, acepta la excepción (SSL autofirmado de desarrollo).

6) Comandos rápidos

Migraciones Alembic (autogenerar)

docker compose exec api alembic revision --autogenerate -m "Initial migration"

Aplicar migraciones

docker compose exec api alembic upgrade head

Tests backend con cobertura (local)

cd backend
winget install -e --id Python.Python.3.11 (3.11.9)
py -3.11-m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
pytest --cov=app --cov-report=term-missing --cov-report=html

Tests de componentes (Cypress)

cd frontend
npm install
npx cypress run --component

7) Puertos y rutas expuestas

  • Nginx: 80 y 443
  • API: 8000 (interno), accesible vía Nginx en https://localhost/api
  • API Docs: 8000 (interno), accesible vía Nginx en https://localhost/api/docs
  • Frontend: 5173 (interno), accesible vía Nginx en https://localhost/
  • Grafana: 3000 (interno), accesible vía Nginx en https://localhost/grafana/
  • Loki: 3100 (interno)
  • Postgres: 5432 (mapeado)
  • Redis: 6379 (mapeado)

8) Problemas comunes

  • SSL autofirmado: el navegador mostrará advertencia; acepta la excepción para https://localhost.
  • Conflicto de puertos: libera el puerto o ajusta mapeos en docker-compose.yml.
  • .env.local faltante o variables incorrectas: el api no conectará a Postgres/Redis. En Docker, usa postgres y redis como hosts.
  • Fin de línea en startup.sh (Windows): si ves /bin/bash^M, convierte a LF y reconstruye.
  • Migraciones: si el modelo cambió, crea migración autogenerada y aplica alembic upgrade head.

9) Parar y limpiar

docker compose down # Parar
docker compose down -v # Parar y borrar volúmenes (pierdes datos de Postgres/Redis)

Créditos y notas

  • Backend: FastAPI + SQLAlchemy + Alembic + Redis + SlowAPI (rate limiting) + middlewares de seguridad, CORS, CSP y CSRF.
  • Frontend: Next.js + Redux Toolkit + Cypress.
  • Observabilidad: Grafana + Loki + Promtail.

Diagrama de arquitectura

 ┌──────────────────────────┐
│ Usuario │
│ Navegador(NextJs/Redux)│
└───────────┬──────────────┘
│ HTTP(S)
│
┌──────────────────────────┐ ┌──────────▼───────────┐
│ Contenedor: nginx │ │ Contenedor: frontend │
│ Reverse Proxy / Static │ │ (App Router) │
│ - TLS/terminación (HTTPS)│ │ - Sirve UI │
│ - Rutas /gzip /caché │ │ - Habla con API │
└──────────┬───────────────┘ └──────────┬────────────┘
│ HTTP(S)
│
▼
┌───────────────────────────────────────────────────────────────┐
│ Contenedor: api (FastAPI) │
│ App: Taskito │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Routers: │ │
│ │ - /auth (login, register, perfil, roles) │ │
│ │ - /tasks (CRUD, filtros, stats, comentarios) │ │
│ │ - /users (CRUD propositos admin) │ │
│ │ - /ws (websocket) │ │
│ │ - /health, / │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Servicios (SOLID): │ │
│ │ - UserService (hash, JWT, roles, activación) │ │
│ │ - TaskService (CRUD, filtros, paginación, orden) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Schemas (Pydantic): User*, Task*, Filters, Token* │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Middleware/Seguridad: │ │
│ │ - Rate limiting (slowapi: auth vs general) │ │
│ │ - JWT auth │ │
│ │ - Validaciones coherentes front/back │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │ │
│ │SQLAlchemy │Rate limit store │
└──────┼───────────────┬────────────────┼───────────────┬───────┘
│ │ │
▼ │ ▼
┌──────────────────┐ │ ┌──────────────────────┐
│ Contenedor: db │ │ │ Contenedor: redis │
│ PostgreSQL │ │ │ (opcional) │
│ - Datos de users │ │ │ - Store para limiter │
│ y tasks │ │ └──────────────────────┘
└──────────────────┘ │ │
│ (logs, métricas opcionales)
▼
┌──────────────────────────────┐
│ Contenedor: monitoring/logs │
│ (Loki/Grafana) │
└──────────────────────────────┘

Conclusiones y próximos pasos

Estado actual:

  • Backend (FastAPI) con autenticación JWT, validaciones sólidas y rate limiting (auth vs general).
  • Base de datos PostgreSQL y Redis disponibles en Compose.
  • Frontend funcionando detrás de Nginx con HTTPS en desarrollo, integración con API y documentación de Swagger protegida por políticas CSP.
  • Observabilidad básica con Loki + Grafana.

Próximos pasos propuestos:

  1. Notificaciones de tareas próximas a vencerse (background jobs)
  • Objetivo: alertar a usuarios cuando una tarea esté por vencer (por ejemplo, 24h/1h antes) y cuando se venza.
  • Tecnologías: Celery (workers) + Redis (broker y opcionalmente backend de resultados) + Celery Beat (scheduler).
  • Acciones:
    • Añadir servicios al docker-compose.yml: celery-worker y celery-beat que apunten al mismo código del backend y compartan .env.
    • Definir tareas en backend/app/tasks/notifications.py (ej.: send_due_soon_notifications, send_overdue_notifications).
    • Programar jobs en Celery Beat (crontab o interval) para revisar tareas con due_date cercano y emitir notificaciones (email, WebSocket, o push interno).
    • Exponer configuración (ventanas de aviso, plantillas de mensaje) en config.py y variables de entorno.
    • Registrar métricas y logs de ejecución para auditoría (ej.: cuántas notificaciones enviadas, errores, reintentos).
  1. SSR con Next.js y ajuste de Nginx
  • Objetivo: migrar el frontend a SSR con Next.js (App Router), mejorando SEO, performance inicial y rutas dinámicas.
  • Acciones:
    • Migrar el frontend a Next.js (si no está completo) y unificar entorno en puerto 3000.
    • Actualizar frontend/Dockerfile para producción SSR (build + start) y development según necesidad.
    • Refactorizar nginx para:
      • Proxyear / al SSR de Next.js (puerto 3000), /api al backend (puerto 8000) y /ws si aplica.
      • Habilitar HTTP/2, gzip/brotli, cache estático agresivo para _next/static y headers de seguridad.
      • Mantener compatibilidad con CSP (actualizar hashes si se inyecta JS en Swagger/NextAuth).

Checklist sugerido:

  • Añadir celery[redis] al requirements.txt y crear módulo app/celery.py con la instancia.
  • Crear celery-worker y celery-beat en docker-compose.yml con healthchecks.
  • Implementar tareas de notificación y pruebas de integración (fixtures con Redis y DB).
  • Añadir endpoints/flags para activar/desactivar notificaciones por usuario.
  • Migrar frontend a Next.js SSR y ajustar variables (NEXTAUTH_URL, NEXT_PUBLIC_*).
  • Refactor de nginx.conf para enrutar SSR/estático/API/WS con compresión y caché adecuados.
  • Actualizar documentación (README) y diagramas.

About

Sistema de manejo de tareas (Monorepo)

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages