Saltar a contenido

Sprint 02 — Inventario completo + seguridad base

Instancia de sprint. Generado desde templates/SPRINT_TEMPLATE.md.


1. Datos del sprint

Campo Valor
Número 02
Objetivo Cerrar el módulo de inventario con trazabilidad de movimientos y asegurar los endpoints de auth contra fuerza bruta
Estado CERRADO
Tag git sprint-02

2. Tareas planificadas

Antes de pasar una tarea a EN_PROGRESO: leer su prompt en prompts/sprint-02-tarea-XX-*.md.

# Tarea Agente Rama git Depende de Estado
T1 Rate limiting + deuda técnica Sprint 1 Backend + DevOps feat/sprint-02-rate-limiting-deuda CERRADA — PR #24 mergeado
T2 MovimientoStock backend — modelo + API Backend feat/sprint-02-movimiento-stock-backend CERRADA — PR #25 mergeado
Tbug Fix CI: throttle en tests + TenantAPIClient Backend fix/sprint-02-throttle-en-tests T1, T2 CERRADA — PR #26 mergeado
T3 MovimientoStock frontend — historial de movimientos Frontend feat/sprint-02-movimiento-stock-frontend T2 CERRADA — PR #27 mergeado
T4 Reportes de stock bajo por sucursal (opcional) Backend + Frontend feat/sprint-02-reportes-stock-bajo T2 CERRADA — PR #28 mergeado
Tsec Fix security: scope bypass en ajustar stock (IDOR) Backend fix/sprint-02-scope-bypass-ajustar-stock T2 CERRADA — PR #29 mergeado

3. Agentes involucrados

  • Backend Agent — T1, T2, T4 backend
  • DevOps Agent — T1 (throttle config en settings)
  • Frontend Agent — T3, T4 frontend
  • QA Agent — subagente en Fase 4 de cada tarea
  • Security Agent — subagente en Fase 5 de T1, T2, T4

4. Definition of Done — proceso

El sprint está completo cuando:

  • [ ] Todas las ramas de T1, T2 y T3 mergeadas a main (T4 es opcional).
  • [ ] Todos los PRs aprobados con PR_CHECKLIST.md.
  • [ ] Tests ejecutados y sin regresiones (≥ 68 backend, ≥ 83 frontend como piso).
  • [ ] Documentación actualizada: ARCHITECTURE.md si aplica, FOLDER_STRUCTURE.md si hay carpetas nuevas.
  • [ ] Tag sprint-02 creado en main.
  • [ ] docs/PROJECT_STATUS.md actualizado.
  • [ ] docs/NEXT_ACTION.md actualizado.
  • [ ] Esta instancia marcada como CERRADO en SPRINT_INDEX.md.

5. Definition of Done — técnico

Condiciones observables y verificables en ejecución.

  • [ ] POST /api/auth/token/ con 6 requests rápidos consecutivos desde el mismo IP → los primeros 5 pasan, el 6to retorna 429 Too Many Requests
  • [ ] GET /api/inventario/categorias/ sin JWT → retorna 401 Unauthorized (no 403)
  • [ ] GET /api/inventario/stock/ sin JWT → retorna 401 Unauthorized
  • [ ] PATCH /api/inventario/stock/{id}/ con cantidad válida → se crea automáticamente un registro en MovimientoStock con usuario, sucursal, producto, cantidad y motivo
  • [ ] GET /api/inventario/movimientos/ con JWT de sucursal_admin → retorna solo movimientos de su sucursal (no ve movimientos de otras sucursales)
  • [ ] GET /api/inventario/movimientos/ con JWT de empresa_admin → retorna movimientos de todas las sucursales del tenant
  • [ ] MovimientosPage en frontend accesible para sucursal_admin y empresa_admin; redirige o muestra 403 para cajero
  • [ ] (T4 opcional) GET /api/inventario/stock/alertas/ retorna solo productos con stock_actual ≤ stock_minimo

6. Resumen de cierre

Completar solo al cerrar el sprint.

Completado

  • T1 (PR #24): LoginRateThrottle 5/min, UserRateThrottle 100/min, NUM_PROXIES=1, seed idempotente
  • Tbug (PR #26): Fix CI — cache.clear() en setUp de todos los TenantTestCase, TenantAPIClient con force_authenticate y _encode_data
  • T2 (PR #25): MovimientoStock modelo + migración, ajustar_stock con auditoría automática, GET /api/inventario/movimientos/ con scope y filtros
  • T3 (PR #27): MovimientosPage frontend — historial paginado, filtros URL-shareables, guard de rol
  • T4 (PR #28): GET /api/inventario/stock/alertas/ + AlertasStockPage con badges de criticidad — endpoint y frontend completos
  • Tsec (PR #29): Fix IDOR en ajustar — scope check sucursal_id__in para sucursal_admin (detectado por Security Agent en cierre de sprint)
  • Suite final: 106 backend + 99 frontend = 205 tests, 0 fallos, CI verde

Pendiente / movido al backlog

  • GET /api/inventario/movimientos/ — sin tests de backend (scope, RBAC, filtros). Deuda de cobertura para Sprint 3.
  • Rate limiting 429 — no hay test que afirme el 6° request retorna 429. Deuda para Sprint 3.
  • AlertasStockPage — sin guard de rol frontend (inconsistencia con MovimientosPage). Backlog.
  • Decisión pendiente: ¿viewer puede ver GET /api/inventario/movimientos/? Actualmente 403 (más restrictivo). Confirmar en Sprint 3.

Decisiones tomadas

  • AlertaStock es interfaz independiente (no extiende StockSucursal): el serializer no devuelve bajo_minimo ni updated_at.
  • viewer y vendedor reciben 403 en /alertas — alertas son datos operativos de inventario, no reportes de ventas. Documentado en tests.
  • Filtro ORM usa stock_actual__lt=F("stock_minimo") (strict), consistente con @property bajo_minimo del modelo.
  • IDOR en ajustar corregido en sprint (no diferido): riesgo real en cuanto se creen sucursal_admin reales en producción.

Estado de salida

SPRINT_02_STATUS: CERRADO