# GreenITESO: QA del estado actual

31 comprobaciones: **21 PASS, 8 FAIL, 1 NOT IMPLEMENTED, 1 NOT RUN**. Resultado de un recorrido local acotado; no representa cobertura completa ni porcentaje global de calidad.

## Versiones

- Backend dev: b77f5ec34c6c72b2fceb1be84d21ae9388cbc54b
- Frontend dev: 1f3fae1faefba90593dae853cd2406307506faae
- Infra main: 30825daaae38eb9777247248dca50e72907ebfbc
- PostgreSQL 18 local, Django real, Vite con proxy externo para /api. Datos sintéticos; sesiones JWT de prueba. No valida Microsoft Entra ni despliegue compartido.

## Hallazgos a priorizar

- **QA01 — Compilación de producción del frontend**: Código 2: cuatro errores TypeScript relacionados con FeedPost/Post/ACTION_LOG. [Evidencia](frontend-build.log).
- **QA04 — Registro UI persiste una acción**: Vista previa; 0 POST action-logs y 0 registros nuevos. [Evidencia](evidence/02-registro-preview.png).
- **QA05B — Reintento idempotente de acción**: HTTP 500. [Evidencia](evidence/QA05B.json).
- **QA06C — Bandeja UI de auditoría carga pendientes**: GET de pendientes → HTTP 405. [Evidencia](evidence/QA06C.json).
- **QA08B — Ranking de equipos disponible en UI**: GET de ranking de clanes → HTTP 404. [Evidencia](evidence/QA08B.json).
- **QA09D — Autor dispone de controles de edición en UI**: Identificador fijo en UI no coincide con Ana; publicación propia sin controles. [Evidencia](evidence/06-feed.png).
- **QA10B — UI refleja notificaciones reales**: Lista de ejemplo; 0 solicitudes a API de notificaciones. [Evidencia](evidence/07-notificaciones.png).
- **QA12A — Administrador modifica catálogo y persiste**: HTTP 200, pero el nombre sigue Rellené mi termo; no persiste el cambio solicitado. [Evidencia](evidence/QA12A.json).

## Orden propuesto de trabajo

1. Recuperar npm run build del frontend (QA01).
2. Conectar registro y auditoría UI con el contrato API real (QA04, QA06C).
3. Reconciliar #101/#139 y sus dependencias de DB; repetir reintentos, conflictos de payload, cuota y concurrencia sobre el grafo final (QA05B).
4. Integrar correcciones de identidad del feed y notificaciones persistidas; validar recarga con dos usuarios (QA09D, QA10B).
5. Terminar CRUD administrativo del catálogo y comprobar persistencia, permisos y errores controlados (QA12A).
6. Completar ranking de clanes e insignias en perfil; repetir QA08B/QA10C.
7. Despliegue y migraciones compartidas tras revisión/autorización del procedimiento. Consultar evidencia del agente de DB.

Son propuestas de avance, no tareas asignadas ni comentarios publicados. Las referencias de PR indican trabajo relacionado fuera del snapshot; no garantizan que resuelva el caso sin repetirlo.

## Resultados

| Caso | Área | Estado | Observado |
|---|---|---|---|
| QA01 | [Compilación de producción del frontend](frontend-build.log) | FAIL | Código 2: cuatro errores TypeScript relacionados con FeedPost/Post/ACTION_LOG |
| QA02A | [Catálogo sin sesión](evidence/QA02A.json) | PASS | HTTP 401 |
| QA03 | [Catálogo UI con backend real](evidence/01-catalogo.png) | PASS | Bicicleta 10, limpieza 20, termo 5; validación y factores visibles |
| QA04 | [Registro UI persiste una acción](evidence/02-registro-preview.png) | FAIL | Vista previa; 0 POST action-logs y 0 registros nuevos |
| QA05A | [Acción sin fotografía acredita puntos](evidence/QA05A.json) | PASS | HTTP 201 |
| QA05B | [Reintento idempotente de acción](evidence/QA05B.json) | FAIL | HTTP 500 |
| QA06A | [Referencia PHOTO queda pendiente sin acreditar](evidence/QA06A.json) | PASS | HTTP 201 |
| QA06B | [Estudiante no puede auditar](evidence/QA06B.json) | PASS | HTTP 403 |
| QA06C | [Bandeja UI de auditoría carga pendientes](evidence/QA06C.json) | FAIL | GET de pendientes → HTTP 405 |
| QA06D | [Administrador aprueba PHOTO por API](evidence/QA06D.json) | PASS | HTTP 200 |
| QA06E | [Revocación revierte puntos y misión](evidence/QA06E.json) | PASS | HTTP 200 |
| QA07A | [Progreso de misión derivado de acción aprobada](evidence/QA07A.json) | PASS | HTTP 200 |
| QA07B | [Inscripción a campaña desde UI](evidence/04-campanas.png) | PASS | 2 participaciones totales; inició con 1 |
| QA08A | [Ranking de usuarios](evidence/QA08A.json) | PASS | HTTP 200 |
| QA08B | [Ranking de equipos disponible en UI](evidence/QA08B.json) | FAIL | GET de ranking de clanes → HTTP 404 |
| QA09A | [Crear publicación propia en feed](evidence/QA09A.json) | PASS | HTTP 201 |
| QA09B | [Otro usuario no edita publicación ajena](evidence/QA09B.json) | PASS | HTTP 403 |
| QA09C | [Autor edita publicación por API](evidence/QA09C.json) | PASS | HTTP 200 |
| QA09D | [Autor dispone de controles de edición en UI](evidence/06-feed.png) | FAIL | Identificador fijo en UI no coincide con Ana; publicación propia sin controles |
| QA10A | [Evento de insignia persistido y consultable](evidence/QA10A.json) | PASS | HTTP 200 |
| QA10B | [UI refleja notificaciones reales](evidence/07-notificaciones.png) | FAIL | Lista de ejemplo; 0 solicitudes a API de notificaciones |
| QA11A | [Perfil editable por propietario](evidence/QA11A.json) | PASS | HTTP 200 |
| QA11B | [Consulta del perfil e impacto aprobado](evidence/QA11B.json) | PASS | HTTP 200 |
| QA11C | [Límite de un liderazgo privado por usuario](evidence/QA11C.json) | PASS | HTTP 400 |
| QA12A | [Administrador modifica catálogo y persiste](evidence/QA12A.json) | FAIL | HTTP 200, pero el nombre sigue Rellené mi termo; no persiste el cambio solicitado |
| QA02B | [Estudiante no accede a pantalla administrativa](evidence/08-control-acceso.png) | PASS | Acceso Restringido; se mostró Error 403 · Prohibido |
| QA11D | [Crear clan privado con usuario elegible](evidence/QA11D.json) | PASS | HTTP 201 |
| QA11E | [No propietario no elimina clan privado](evidence/QA11E.json) | PASS | HTTP 403 |
| QA11F | [Propietario elimina clan mediante borrado lógico](evidence/QA11F.json) | PASS | HTTP 204 |
| QA10C | [Perfil muestra insignias ganadas](evidence/QA11B.json) | NOT IMPLEMENTED | UserBadge existe y la notificación se genera; profile/me devuelve badges: [] como placeholder |
| QA13 | [Despliegue real / infraestructura compartida](db-context.md) | NOT RUN | La grabación es local; no se aplicó Terraform ni se modificó Neon |

## Límites y trazabilidad

- Las referencias PHOTO son sintéticas. No se verificó carga GCS ni URL firmada.
- No se probó login institucional, tiempo real, concurrencia, restore de nube ni deployment.
- Insignias en profile/me son placeholder (NOT IMPLEMENTED); las insignias y sus notificaciones sí se persistieron por separado.
- Hub/vídeo alternan capturas de UI real y paneles explicativos construidos con respuestas registradas. La consola QA no es una pantalla del producto.
- FAIL incluye funcionalidades incompletas frente al escenario esperado; no significa automáticamente que sea una regresión introducida en la última PR.
- Reutilizamos el ensayo del agente de DB sin volver a ejecutarlo; su revisión y versión constan en db-evidence.
- Un intento auxiliar de clan con token de fixture vencido fue un error del harness; se conservó separado, se renovó la sesión y se repitió. No cuenta como fallo del producto.
- QA02B y QA11C se ajustaron al texto y a la regla real observados; las respuestas y capturas originales permanecen disponibles.

[Snapshot](snapshot.json) · [Resultados JSON](results.json) · [CSV](results.csv) · [Guion](narration-es.md) · [Reproducción](scripts/README.md)

## Coordinación de idempotencia con DB

El agente de DB revisó QA05B y recomendó reutilizar las pruebas existentes de #101 en la integración final. Añadir aceptación del payload exacto de este recorrido, con is_shared_publicly=true, y verificar que el reintento no duplica publicaciones del feed. La política al cambiar ese valor debe quedar explícita. [Nota de coordinación](db-evidence/qa-follow-up.md). No se ejecutó ni aprobó #101 como parte de esta grabación.
