Proyecto backend-first · API REST con Django
Flujos con dependencias, permisos explícitos y transiciones de estado auditables.
QuestBoard es una API backend con Python y Django para trabajo colaborativo con dependencias y revisión. A diferencia de un CRUD básico de tareas, controla qué trabajo puede comenzar, quién puede aprobarlo y mantiene los cambios relevantes de forma coherente y auditable.
- Python
- Django
- Django REST Framework
- PostgreSQL
- Docker
- Gunicorn
Resumen
El proyecto se concentra en reglas backend que los endpoints habituales de creación, actualización y borrado no expresan bien: elegibilidad del flujo, autoridad dentro del proyecto, integridad de dependencias, separación de la revisión e historial de auditoría duradero.
Flujo explícito
Los cambios de estado utilizan una operación de transición dedicada en lugar de un PATCH sin restricciones. Cada transición legal aplica sus propios permisos y precondiciones, incluido un retorno controlado desde REVIEW a IN_PROGRESS.
BACKLOGREADYIN_PROGRESSREVIEWDONE
Progresión basada en dependencias
Las dependencias forman un grafo validado dentro de cada proyecto. Las operaciones de planificación rechazan aristas inválidas antes de insertarlas y las restricciones PostgreSQL refuerzan las relaciones duplicadas o autorreferenciales. Los prerrequisitos determinan directamente si una quest puede pasar de BACKLOG a READY.
- Self-dependencies are rejected
- Dependencies must remain within one project
- Duplicate edges and cycles are rejected
- Every prerequisite must be DONE before READY
Permisos contextuales e invariantes
La autorización se evalúa según la membresía del proyecto, el rol, la asignación y el estado del flujo. La autoridad de OWNER y REVIEWER se separa de la ejecución de CONTRIBUTOR, y una persona asignada no puede aprobar su propio trabajo.
Auditabilidad
QuestEvent persiste las mutaciones relevantes de creación, asignación, dependencias y estado con actor, fecha y contexto estructurado. quest_id_snapshot conserva el identificador histórico tras el borrado legal de una quest.
Transacciones y concurrencia
Las mutaciones de dominio utilizan transaction.atomic. Las filas Quest se bloquean para cambios de estado concurrentes, mientras que los bloqueos select_for_update a nivel de proyecto serializan las escrituras del grafo y los cambios de membresía cuyas invariantes abarcan varias filas.
transaction.atomicFila Quest · select_for_updateFila Project · grafo e invariantes de OWNER
Reto de ingeniería
Un fallo específico de PostgreSQL reveló una forma inválida de SELECT FOR UPDATE a través de la relación nullable con assignee. La solución mantuvo el bloqueo: transition_quest bloquea únicamente la fila Quest y resuelve la relación nullable por separado, conservando el límite transaccional y las invariantes del flujo.
Testing y entrega
GitHub Actions ejecuta el backend sobre PostgreSQL 17 y valida calidad de código, migraciones, configuración de Django, contrato OpenAPI, tests de dominio/API y construcción de la imagen Docker. El mismo runtime Docker se despliega con Gunicorn en Render y PostgreSQL gestionado.
PostgreSQL 17Ruff lint and formatMigration driftDjango system checksOpenAPI validationBackend/API testsDocker image build