movilba
MOVILBA-164
· child of MOVILBA-158 Reportes: dashboard de reportes por rol, reportes a medida, filtros y rangos de fecha Deferred
Reportes a medida: alcance, persistencia y permisos
In progress low
cmcoder03assistant-mba-l-ca
Parte del epic MOVILBA-158. 'Reportes custom' pedido por Elazar 2026-08-31. SIN DEFINIR, y la diferencia cambia todo el trabajo: (a) elegir columnas y filtros sobre datasets fijos - acotado, sin SQL de usuario; o (b) un constructor libre - mucho mayor, y abre superficie de inyeccion y de consultas que tumban la base. Recomendacion: (a). (b) no se construye para un go-live. A RESOLVER IGUAL: si un reporte a medida se guarda, si se guarda por usuario o se comparte, y con que permiso se comparte. Un reporte compartido puede exponer a un usuario datos que su grupo no habilita - el permiso se evalua al EJECUTAR contra el usuario que mira, nunca contra el que lo guardo. Depende del catalogo de reportes y del recurso RBAC.
Activity
-
parent=#3162
-
coder03assistant-mba-l-ca
-
Decision packet for Elazar: (1) Query scope: A) fixed, reviewed datasets with bounded columns/filters (recommended; no user SQL), or B) free-form query builder (higher injection and resource-exhaustion risk; not recommended). (2) Persistence: A) do not save definitions/results in the first release (recommended; users rerun a bounded report), or B) save a named definition privately per user. (3) Sharing: A) no sharing initially (recommended), or B) explicitly share a definition; authorization must be checked at execution for the viewing user, never inherited from the creator. Recommendation: A/A/A for a bounded first release; add sharing only with a report-specific permission model and a measured use case. No code or schema changes until these choices are decided.
-
Decision packet is recorded; implementation is held for Elazar's choice of query scope, persistence, and sharing policy.
-
Elazar decision 2026-10-09: implement fixed, reviewed datasets only (no free-form SQL); do not save report definitions or results; check the executing viewer's permissions at run time. Sole route restriction: /reportes/liquidacion is limited to tramites people regardless of group. Proceed on this scope.
-
Scope decided by Elazar: fixed datasets, no saved definitions/results, viewer permission checked at execution; liquidacion remains restricted to tramites people regardless of group.
-
Implemented the decided access slice: authenticated users receive the fixed report catalogue; Liquidación is listed and its page, server action, and XLSX endpoint each require direct TRAMITES_PARQUE membership (independent of other permissions). Existing report data routes retain their viewer-specific execution checks. No report definition/result persistence was introduced. Code handoff pending audit; no lint/typecheck/tests run per coder handoff protocol.
-
audit-mba-l-cc 2026-10-09: reviewed per-hunk for access behavior and fail-closed. Scope decision confirmed in item history (Elazar 2026-10-09: fixed datasets, no persistence, viewer permission at execution, liquidacion restricted regardless of other group membership). rbac.ts hasGroupMembership(): direct FK join on usersGroups+groups, fail-open path (false) only on a generic caught error; RbacConnectionError is rethrown, not swallowed, so a DB-connection failure propagates as an exception at every one of the 4 call sites (all of which negate the awaited boolean) rather than resolving to an implicit allow - fail-closed confirmed. All 4 callers checked: reportes/page.tsx, reportes/liquidacion/page.tsx, actions/reportes.ts, api/reportes/liquidacion/route.ts. Liquidacion's three surfaces (server page redirect, server action, XLSX route) each independently call hasGroupMembership(userId,'TRAMITES_PARQUE') - confirmed membership is checked directly, not derived from any other group's permission bundle. reportes/page.tsx removal of the old canRead('reportes')/canRead('vehiculos') catalogue gating: verified NOT a regression - /api/reportes/vehiculos-historico independently checks hasPermission(userId,'vehiculos','read') (own grep initially missed this, found on second pass), and /vehiculos itself was never gated by the old reportes-page check (only reachable via proxy.ts's session-only protectedRoutes entry, pre-existing, unchanged) - so removing the link-level gate only changes which links are shown, not what is reachable to someone who already knew the direct URL. Grep confirms zero leftover canRead('reportes')/canPerformAction('reportes') references anywhere, and no INSERT/UPDATE/.set( added - persistence claim holds. Client component (LiquidacionPageClient.tsx) correctly dropped its now-redundant client-side permission gate since the server page redirects before it ever renders. Gates run fresh: typecheck rc=0, test:source 71/71, test:tools 120/120.
-
audit pass: rbac.ts hasGroupMembership + its 4 call sites (reportes/page.tsx, liquidacion/page.tsx, actions/reportes.ts, api/reportes/liquidacion/route.ts) + new LiquidacionPageClient.tsx; fail-closed behavior; catalogue-gate removal impact on vehiculos-historico/vehiculos; gates run fresh
payload
{"scope":"rbac.ts hasGroupMembership + its 4 call sites (reportes/page.tsx, liquidacion/page.tsx, actions/reportes.ts, api/reportes/liquidacion/route.ts) + new LiquidacionPageClient.tsx; fail-closed behavior; catalogue-gate removal impact on vehiculos-historico/vehiculos; gates run fresh","outcome":"pass","evidence":"RbacConnectionError rethrown not swallowed at all 4 negated call sites; vehiculos-historico route independently checks hasPermission(vehiculos,read); /vehiculos gated only by proxy session check pre-existing/unchanged; zero leftover canRead(reportes) references; no INSERT/UPDATE added; typecheck rc=0; test:source 71/71; test:tools 120/120","reportRef":null} -
Audit PASS recorded 2026-10-09: fail-closed group check confirmed; the Liquidacion page, action, and XLSX route independently require direct TRAMITES_PARQUE membership. The /reportes catalogue gate removal is safe because vehicle report endpoints enforce viewer permission at execution. Gates: typecheck 0; test:source 71/71; test:tools 120/120. Ready for ship; item remains open until deployment is confirmed.
feature
6w ago by wi-cli-venus
1w ago