Skip to content

Conversation

CoriglianoLucas
Copy link

Invera ToDo-List Challenge

API REST en Django + DRF para gestionar una lista de tareas con autenticación JWT, filtros, logs, tests y despliegue con Docker.

Funcionalidades

  • Registro y autenticación de usuarios vía JWT.
  • CRUD de tareas:
    • Crear, listar, actualizar y eliminar.
    • Marcar como completadas.
  • Filtros:
    • Por contenido (?search=...)
    • Por fecha de creación (?created_after=YYYY-MM-DD)
  • Logs:
    • Access logs vía middleware (método, path, status, usuario, duración).
    • Business logs vía signals (creación, actualización, completado, borrado).
  • Tests de integración (DRF APIClient).
  • Despliegue en Docker con Gunicorn y SQLite persistente.

Instalación y ejecución

Local (sin Docker)

# Crear entorno y activar
python -m venv venv
source venv/bin/activate   # Windows: venv\Scripts\activate

# Instalar dependencias
pip install -r requirements.txt

# Migraciones y superusuario
python manage.py migrate
python manage.py createsuperuser

# Levantar servidor
python manage.py runserver

Con Docker

Requiere Docker y Docker Compose.

  1. Crear archivo .env:
SECRET_KEY=changeme-super-secret
DEBUG=0
ALLOWED_HOSTS=*
ACCESS_TOKEN_DAYS=7
REFRESH_TOKEN_DAYS=30
  1. Construir y levantar:
docker compose up --build
  1. Crear superusuario (opcional):
docker compose run --rm web python manage.py createsuperuser

Endpoints principales

Autenticación

  • POST /api/register/ → Registro de usuario
  • POST /api/login/ → Obtener access y refresh tokens
  • POST /api/refresh/ → Renovar token access

Tareas

  • GET /api/tasks/ → Listar tareas propias
    • Filtros: ?search=... y/o ?created_after=YYYY-MM-DD
  • POST /api/tasks/ → Crear tarea
  • GET /api/tasks/{id}/ → Detalle de tarea
  • PUT /api/tasks/{id}/ → Actualizar tarea
  • DELETE /api/tasks/{id}/ → Eliminar tarea
  • PUT /api/tasks/{id}/complete/ → Marcar como completada

Ejemplos con curl

Registro

curl -X POST http://localhost:8000/api/register/  -H "Content-Type: application/json"  -d '{"username":"lucas","email":"lucas@mail.com","password":"12345678"}'

Login

curl -X POST http://localhost:8000/api/login/  -H "Content-Type: application/json"  -d '{"username":"lucas","password":"12345678"}'

Crear tarea

curl -X POST http://localhost:8000/api/tasks/  -H "Authorization: Bearer <ACCESS_TOKEN>"  -H "Content-Type: application/json"  -d '{"title":"Estudiar Django","description":"Challenge Invera"}'

Marcar como completada

curl -X PUT http://localhost:8000/api/tasks/1/complete/  -H "Authorization: Bearer <ACCESS_TOKEN>"

Filtrar

# Por texto
curl -X GET "http://localhost:8000/api/tasks/?search=estudiar"  -H "Authorization: Bearer <ACCESS_TOKEN>"

# Por fecha
curl -X GET "http://localhost:8000/api/tasks/?created_after=2025-08-01"  -H "Authorization: Bearer <ACCESS_TOKEN>"

Logs

  • Access logs: logs/access.log
    Middleware AccessLogMiddleware registra método, path, status, usuario y duración.

  • Business logs: logs/app.log
    Signals (tasks/signals.py) registran:

    • task created
    • task updated
    • task completed
    • task uncompleted
    • task deleted

Ejemplo access log

ts=2025-08-06T12:34:57-0300 level=INFO logger=http.access method=POST path=/api/tasks/ status=201 user=lucas duration_ms=32 msg=request completed

Ejemplo business log

12:35:10 [INFO] tasks: task completed by lucas

Tests

Para correr los tests:

# Local
python manage.py test -v 2

# Docker
docker compose run --rm web python manage.py test -v 2

Los tests (tasks/test.py) cubren:

  • Registro y login
  • Auth obligatoria
  • Crear tarea
  • Listar (solo propias)
  • Filtros por texto y fecha
  • Update
  • Acción complete
  • Delete
  • Aislamiento de usuarios

Diagramas

Secuencia: Request → Middleware → ViewSet/DRF → Signals → Loggers

sequenceDiagram
    autonumber
    participant C as Client
    participant M as AccessLogMiddleware
    participant V as DRF ViewSet
    participant ORM as Django ORM
    participant S as Signals
    participant L1 as Logger http.access
    participant L2 as Logger tasks
    C->>M: HTTP Request (JWT)
    M->>V: get_response(request)
    V->>ORM: create/update/delete Task
    ORM-->>S: emitir signals
    S->>L2: business logs
    V-->>M: Response
    M->>L1: access log
    M-->>C: HTTP Response
Loading

Componentes

flowchart LR
    subgraph Django App
        A[settings.py]
        B[tasks/apps.py]
        C[tasks/middleware.py]
        D[tasks/models.py]
        E[tasks/signals.py]
        F[tasks/views.py]
        G[tasks/serializers.py]
    end
    subgraph Logging
        H[(logs/access.log)]
        I[(logs/app.log)]
        L1[[http.access]]
        L2[[tasks]]
    end
    Client --> C --> F --> D
    D --> E --> L2 --> I
    C --> L1 --> H
    A -.-> C
    A -.-> L1
    A -.-> L2
    B --> E
Loading

Estructura del proyecto

todo_challenge/
├── todo_challenge/       # Configuración del proyecto
├── tasks/                # App de tareas
│   ├── migrations/
│   ├── models.py
│   ├── views.py
│   ├── serializers.py
│   ├── urls.py
│   ├── middleware.py
│   ├── signals.py
│   └── test.py
├── logs/                 # Logs persistentes
├── db/                   # Base SQLite persistente (Docker)
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── README.md

Notas finales

  • JWT configurable vía .env (ACCESS_TOKEN_DAYS, REFRESH_TOKEN_DAYS).
  • SQLite para simplicidad, pero fácilmente migrable a PostgreSQL/MySQL.
  • Logs preparados para ser enviados a Loki/Grafana si se requiere.
  • Tests listos para CI/CD (puede agregarse GitHub Actions fácilmente).

… models, serializers, views, and URL configuration
…ts; enhance settings with logging configuration and .gitignore updates
…, and permissions. Enhance task completion endpoint with URL name
…essages are in English for better readability
…nment variables; update .gitignore for .env tracking
… completion, and improve display of task attributes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant