Skip to content

feat: [TESIS-107] read the integrations listing out of the envelope - #50

Merged
TomasMartin2004 merged 2 commits into
masterfrom
TESIS-107-response-envelope
Sep 26, 2026
Merged

TomasMartin2004 merged 2 commits into
masterfrom
TESIS-107-response-envelope

Conversation

@TomasMartin2004

Copy link
Copy Markdown
Contributor

🔗 Link

https://proyectofinalfrlp.atlassian.net/browse/TESIS-107

⚠️ Va después de proyectoFinalFRLP/proyecto-api#86

Es el lado del frontend de la misma card. El backend fija la convención de respuesta y envuelve GET /integrations, que era el único listado que contestaba un array pelado.

El orden es: api#86 primero, éste después. Al revés, el panel se queda sin integraciones el rato que pase entre los dos.

📝 Descripción

Lee el listado de integraciones desde el envelope y borra los comentarios que describían la inconsistencia.

Los comentarios eran el síntoma de la card. Había tres repartidos por la frontera:

  • hooks/useIntegrations.ts: «acá no hay ApiResponse<T>… la respuesta es un array plano y no { data: [...] }»
  • dashboard/types.ts: «Responde un array plano, sin el envoltorio { data } de ApiResponse»
  • inventory/api.ts: «index envuelve en { data: [...] }, pero show y update devuelven el objeto pelado»

Si la regla existiera, ninguno haría falta. Los tres se reemplazan por la regla misma, que ahora está escrita en el ADR-015 del backend: una colección viaja envuelta, un recurso solo viaja pelado. El de inventory conserva lo que sí es propio de ese recurso y no es deducible —que index usa ProductListSerializer y no trae stocks—, porque eso no es una inconsistencia sino un dato del endpoint.

🛠️ Cambios realizados

  • features/dashboard/hooks/useIntegrations.ts — lee data.data con ApiResponse<IntegrationNode[]>, como el resto de los hooks de la feature.
  • features/dashboard/types.ts, features/inventory/api.ts, features/orders/api.ts — los comentarios-trampa, reemplazados por la regla.
  • Tests: useIntegrations.test.tsx, nuevo. El hook no tenía ninguno.

🧪 Cómo probarlo (Opcional)

Precondiciones: backend con api#86 mergeado corriendo en localhost:3000, seeds del tenant norte, sesión iniciada.

  1. Ir a /dashboard. La tarjeta Integraciones lista los nodos igual que antes, con su estado de sincronización.
  2. Con el feature flag integrations encendido, /integrations muestra la sección completa.
  3. En la pestaña de red, GET /integrations responde { "data": [ ... ] } y la pantalla lo consume sin tocar nada más.
  4. Con la API caída, la tarjeta muestra su error en vez de una lista vacía.

📸 Evidencia (Opcional)

Antes Después
Idéntico en pantalla: cambia la forma de la respuesta, no lo que se ve (adjuntar captura del panel con la tarjeta de Integraciones)

¿Afecta la arquitectura o genera un nuevo patrón?
No para el frontend: al contrario, elimina la excepción. Ahora los cuatro api.ts consumen la misma regla y ningún hook necesita explicar la suya.

Verificación: npm run lint, prettier --check ., npm run build y npm run test (455 tests, 0 fallas; eran 452).

Los tests tienen dientes: cambié el hook para que devolviera la respuesta cruda y el ejemplo del envelope se puso en rojo.


🤖 Generated with Claude Code

https://claude.ai/code/session_012xAtddb53LRNVLuyTXyELp

The backend settles the response convention in ADR-015: a collection travels
wrapped in `data`, a single resource travels bare. `GET /integrations` was
the one listing answering a bare array, and it now wraps like the rest.

The hook carried a comment explaining that this endpoint was the exception.
That comment was the symptom the card is about — if the rule existed, nobody
would need to be reminded per endpoint. It is gone, and so are the two other
notes describing the inconsistency in the inventory and orders frontiers,
replaced by the rule itself.

Three examples cover the hook, which had none. One of them fails if anyone
reads the response as a bare array again.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012xAtddb53LRNVLuyTXyELp
@TomasMartin2004
TomasMartin2004 requested a review from a team as a code owner September 23, 2026 21:18
@TomasMartin2004
TomasMartin2004 requested review from Sanntinat and removed request for a team September 23, 2026 21:18

@Sanntinat Sanntinat left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revisión — TESIS-107 front (PR #50) · El listado de integraciones sale del envelope

Revisión contra origin/master de proyecto-web, sobre TESIS-107-response-envelope (dc40af4), con la card TESIS-107 y su lado del backend (proyecto-api#86, revisado aparte) al lado.

Check Resultado
npm run test (local, sobre la rama) 54 archivos · 455 tests · 0 failures (3 nuevos)
npm run lint · prettier --check . · npm run build (local) Limpios
CI (GitHub Actions) Lint & Format · Branch Naming Convention · Unit Tests · Build: success
Rama vs master 3 commits atrás (TESIS-117, TESIS-58, TESIS-61). El merge es limpio: 59 archivos · 538 tests · 0 failures
Conflictos con los demás PRs abiertos Ninguno

✅ El cambio es el que corresponde, y el único que hacía falta

  • useIntegrations lee data.data con ApiResponse<IntegrationNode[]>, igual que el resto de los hooks de la feature. Es el único consumidor de /integrations: lo busqué en todo src/, y el resto de las apariciones son la ruta de la pantalla y su test de navegación, que no tocan la respuesta.
  • Los tres comentarios-trampa se reemplazan por la regla. El de inventory/api.ts conserva lo que sí es propio del recurso (index no trae stocks), que es un dato del endpoint y no una inconsistencia. Es la lectura correcta del criterio de la card.
  • El contrato cierra de los dos lados: api#86 lo fija en integrations_spec.rb y api_contract_spec.rb (keys == ['data']), y este PR en useIntegrations.test.tsx.

✅ El test nuevo tiene dientes

Hice que el hook devolviera la respuesta cruda (return data) y falló reads the listing out of the data envelope, solo. Los otros dos siguen verdes, y está bien que así sea: prueban la URL y que un error no se disfrace de lista vacía.

🟡 Menores

  • Una falla local que no es de este PR: en la primera corrida me falló por timeout ProductDetailPage.test.tsx › opens the edit form when it is reached with the intent of editing (5159 ms contra un límite de 5000). Estaba corriendo la suite de la API en paralelo. Aislado pasa, y sin carga la suite entera pasa dos veces seguidas. Este PR no toca esa pantalla, pero es un test que, con la máquina cargada, queda al borde del timeout.
  • Evidencia: la tabla todavía dice «(adjuntar captura del panel con la tarjeta de Integraciones)».
  • Con #87 (TESIS-108) encima, /integrations suma meta y pasa a paginar de a 100. No cambia nada acá: el hook lee data y el panel no pagina.

⚠️ Orden de merge (bien anunciado)

Es un cambio que rompe: con este PR y sin api#86, el hook lee data.data de un array y el panel queda sin integraciones. api#86 primero y éste inmediatamente después, como dice la descripción. Como pedí cambios en api#86, este PR espera a que ese se resuelva, aunque por sí mismo está listo.

Los criterios de la card (lado front)

  • El frontend consume la forma nueva.
  • No quedan comentarios describiendo inconsistencias. Los tres se reemplazaron por la regla.
  • Hay un test que falla si alguien rompe el envelope. Verificado rompiéndolo.

Veredicto

APPROVE.

Chico, preciso y con el test que faltaba: el hook no tenía ninguno. Para mergear, esperar a api#86, y conviene traer master antes (el merge es limpio).

@TomasMartin2004
TomasMartin2004 merged commit d37c808 into master Sep 26, 2026
4 checks passed
@TomasMartin2004
TomasMartin2004 deleted the TESIS-107-response-envelope branch September 26, 2026 01:54
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.

2 participants