← all branches

feat/ui-impact

needs attentionviewing older commit
027e5ea · incrementalpre-PRreviewed 2026-07-24 20:04 UTC4H · 9M · 8L · 3I
The branch
Purpose
feat/ui-impact builds the Energía dashboard UI for Grupo Axo — bill analysis, anomaly detection, portfolio comparisons, demand/ESG views, findings system, and payment reconciliation.
Goal
Add MXN (peso spend) as a selectable unit alongside kWh in the Comparativo page using the same DiD cohort model.
Sub-goals
  • SG-1: Add mxn field to MonthPoint and Tuple; backfill 23 stores with real bill totals from Supabase
  • SG-2: Make analyzeStore unit-aware (Unit='kwh'|'mxn'); has() guard treats mxn=0 as missing
  • SG-3: Unidad toggle UI; all formatters, charts, KPIs, table columns, CSV exports branch on unit
The changes (whole branch)
What
anomaly.ts: Unit type + unit param on analyzeStore. realConsumption.ts: mxn field on MonthPoint with Supabase bill totals for 23 stores. page.tsx: Unidad toggle and all views unit-aware.
Why
Grupo Axo needs peso spend comparisons for budget/finance reporting alignment.
Areas
apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/_lib/anomaly.ts+258apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/_lib/realConsumption.ts+3022apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/page.tsx+9055
Blast
3 files, ~+145/-85 in this increment; branch total: 69 files +25547/-4 across energia dashboard, utility/finding domain, platform API.
hardcoded-data no-tests-for-new-path
CI· No PR — no CI rollup availableCodeRabbit· No .coderabbit.yaml in repotypecheck· Not run in push-triggered path without CI

Findings · 20

correctness3

medium

BASE_WINDOW guard weakened — can proceed with < 7 total series entries

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/_lib/anomaly.ts:77

Old guard: store.series.length. New guard: filter(has).length. Correct intent but relaxation is undocumented.

medium

Sparse MXN cohort produces non-contiguous baseline months

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/_lib/anomaly.ts:100

Peers with mxn=0 excluded from cohortValueAt; BASE_WINDOW points may span non-contiguous months.

low

points filtered by has — index-based consumers may misalign

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/_lib/anomaly.ts:110

security1

info

?tienda= URL param safe — bounded to hardcoded STORES array

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/page.tsx:153

conventions6

high

excessKwhDia field is unit-dependent but named kWh

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/_lib/anomaly.ts:49

AnomalyResult.excessKwhDia is $/día when metric='mxn'. Rename to excessPerDay or thread Unit into AnomalyResult.

medium

Repeated 'Gasto'/'Consumo' ternaries — 6 sites exceed abstraction threshold

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/page.tsx:491

Project rule: three similar lines > premature abstraction. Extract noun(u) helper.

medium

JSDoc comments on formatters describe WHAT, not WHY

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/page.tsx:44

fmtNorm, fmtCfe, rawVal, colRaw JSDoc restate the signature. Remove or replace with WHY.

low

axisLabel double ternary — prefer Record<Unit, Record<Metric, string>>

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/page.tsx:49

low

t17 mxn=18090 with exact=false contradicts 'dated bills' doc comment

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/_lib/realConsumption.ts:154

info

kwhDia still exported — verify no external consumers before removing

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/_lib/realConsumption.ts:82

tests4

high

analyzeStore MXN path has zero test coverage

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/_lib/anomaly.ts:77

No __tests__/ dir. Missing: mxn=0→null; <BASE_WINDOW+1 mxn>0→null; valid MXN result; cohort sparsity divergence from kWh mode.

high

MonthPoint Tuple positional slot added — no regression test for S() mapping

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/_lib/realConsumption.ts:45

kwh and mxn are both number — a positional swap passes TS but silently misaps values.

high

valOf divides by p.dias — no zero guard, no test

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/_lib/anomaly.ts:85

dias is always ≥1 in practice but NaN would silently propagate into DiD KPIs if dias=0 reached valOf.

medium

normRowsFor/portfolioRows MXN column keys untested

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/page.tsx:70

A mismatch in colRaw/colDia would silently produce wrong CSV headers.

improvement6

medium

kwhDia, sumKwh, meanKwhDia are dead exports

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/_lib/realConsumption.ts:82

anomaly.ts removed its kwhDia import; sumKwh and meanKwhDia have no consumers. Delete or un-export.

medium

rawVal/hasVal in page.tsx duplicate num/has closures in anomaly.ts

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/page.tsx:51

Identical logic in two files. Export a standalone pointValue(p, u) from anomaly.ts.

medium

Table cell renderer is three-level nested ternary

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/page.tsx:564

Extract to formatCell(h, v, unit) for testability and readability.

low

portfolioRows recomputed on export click — rows memo holds this data

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/page.tsx:532

low

portfolioStats and portfolioDiD both iterate all STORES separately

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/page.tsx:225

info

Unit type conceptually belongs in realConsumption.ts alongside MonthPoint

apps/platform/src/app/[locale]/(dashboard)/energia/comparativo/_lib/anomaly.ts:32

History · 15 commits

  1. 96ca7d7needs attentionincremental0H · 9M · 12L2026-07-25 16:40
  2. 25516f7needs attentionincremental5H · 7M · 8L2026-07-25 03:29
  3. a7f8d64needs attentionincremental0H · 4M · 5L2026-07-25 01:56
  4. 7fc4ef0needs attentionincremental2H · 6M · 8L2026-07-24 21:04
  5. 027e5eaneeds attentionincremental4H · 9M · 8L2026-07-24 20:04current
  6. 95a101eneeds attentionincremental3H · 6M · 5L2026-07-24 16:09
  7. 5d0d186needs attentionincremental1H · 3M · 5L2026-07-24 15:36
  8. c3c5121needs attentionincremental2H · 1M · 5L2026-07-24 15:17
  9. ded4e61needs attentionincremental2H · 3M · 9L2026-07-24 14:22
  10. 312a1f4needs attentionincremental1H · 4M · 4L2026-07-24 04:01
  11. b48af56needs attentionincremental1H · 6M · 6L2026-07-24 03:14
  12. 6d07cc8needs attentionincremental2H · 4M · 5L2026-07-24 00:50
  13. 261b55eneeds attentionincremental5H · 11M · 6L2026-07-24 00:38
  14. 5b8a252needs attentionincremental3H · 6M · 9L2026-07-24 00:19
  15. f29cc5bneeds attentionfull9H · 17M · 11L2026-07-23 23:07