content/auto-draft
safeviewing older commit0795a9d · incrementalPR #325reviewed 2026-07-20 22:42 UTC0H · 0M · 2L · 2I- Purpose
- Auto-drafted blog post comparing GDMTO vs GDMTH CFE tariffs for Mexican commercial/industrial energy consumers — a target keyword cluster (tarifa GDMTH, GDMTO vs GDMTH) from the SEO content strategy.
- Goal
- Publish a data-accurate, interactive blog post with real jun-2026 CFE tariff rates, SVG charts, and locked unit tests so arithmetic drift is caught before it misleads readers.
- Sub-goals
- SG-1: GDMTO-vs-GDMTH blog post content (178 lines MDX)
- SG-2: Pure tariff math module (charts.tariffs.ts) — SSOT for RATES, bill functions, load profiles
- SG-3: SVG chart components (charts.tsx) — cost comparison, load profiles, decision chart
- SG-4: Locked unit tests (charts.calculations.test.ts) — pin published peso figures independently
- SG-5: llms.txt + calendar.yml updates
- What
- This incremental commit tightens the test suite: adds dmaxMonth to imports, converts Math.round() total assertions to toBeCloseTo(x,2) cent-precision, adds a dfCap binding structural test with a spiky profile, strengthens the GDMTH structural test to verify both capacidad (punta peak) and distribución (month peak) independently, and cleans up multi-line JSDoc blocks to concise single-line comments per project convention. The charts.tsx import is moved from bottom to top.
- Why
- Previous review (incremental from 48227544) flagged energía bar read as grey (fixed), band overflow (fixed), hero clip (fixed), and WHAT-comments (cleaned up). This commit addresses the remaining loop-review nits: tighter test precision, structural demand-base assertions, and comment alignment.
- Areas
- apps/web/content/blog/gdmto-vs-gdmth.mdx+178−0apps/web/src/components/blog+438−1apps/web/src/app/(marketing)/blog+2−2apps/web/public/llms.txt+6−0apps/web/content/calendar.yml+1−1
- Blast
- 7 files, +625/−4 — entirely within apps/web blog + components. No platform, domain, or infra changes.
Findings · 4
tests3
GDMTH structural test doesn't assert the binding constraint is inactive
apps/web/src/components/blog/charts.calculations.test.ts
The test asserts gh.capacidad ≈ dmaxPunta × RATES.gdmth.cap and gh.distribucion ≈ dmaxMonth × RATES.gdmth.dist. These pass today because dfCap(90000, 0.57)≈219 kW sits above both dmaxPunta=103 and dmaxMonth=206, so the measured peaks bind. But nothing in the test asserts that ordering. If RATES.gdmth.fc or the profile changed so dfCap dropped below dmaxPunta, the test would silently pivot to exercising the cap path while still claiming to verify the punta-peak wiring. Fix: add expect(dmaxPunta(concentrado)).toBeLessThan(dfCap(blockKWh(concentrado).total, RATES.gdmth.fc)) as a precondition.
GDMTH cap-binding path (dfCap < dmaxPunta or dfCap < dmaxMonth) is never exercised
apps/web/src/components/blog/charts.calculations.test.ts
The dfCap 'binds' test proves billGdmto uses the capped demand on a spiky profile. No equivalent test covers billGdmth when dfCap < dmaxPunta (binding capacidad) or dfCap < dmaxMonth (binding distribución). Both Math.min branches in billGdmth remain untested under a load-factor constraint. A high-fc, low-energy profile would exercise this.
dmaxPunta has no direct unit assertion against a known output
apps/web/src/components/blog/charts.calculations.test.ts
dmaxPunta is imported and used only through the GDMTH structural test. Unlike dmaxMonth (directly verified as 500 for the spiky profile), dmaxPunta is never asserted against a concrete input/output pair. A wrong slice bound (e.g. [18,23) instead of [18,22)) would be caught only indirectly.
improvement1
toBeCloseTo precision=1 on dfCap assertions is loose but safe
apps/web/src/components/blog/charts.calculations.test.ts
dfCap(90000, 0.57)=219.2982 vs asserted 219.3 — error 0.0018, well within ±0.05 tolerance of precision=1. Numerically safe, but precision=2 (±0.005) would provide tighter formula-locking without changing the test's intent.
History · 14 commits
- c27ea57needs attentionincremental3H · 5M · 4L2026-08-04 17:46
- ff69645needs attentionincremental0H · 6M · 8L2026-07-28 18:21
- 0257d74safeincremental0H · 0M · 0L2026-07-20 23:00
- 0795a9dsafeincremental0H · 0M · 2L2026-07-20 22:42current
- 5c57414needs attentionincremental2H · 7M · 10L2026-07-20 22:29
- 5a57a8fneeds attentionincremental0H · 5M · 8L2026-07-20 17:14
- cc9056eneeds attentionfull1H · 3M · 9L2026-07-20 16:40
- 8b79d33needs attentionincremental5H · 7M · 11L2026-07-14 18:10
- f0c337cneeds attentionincremental1H · 1M · 5L2026-07-14 17:15
- 5c9de97needs attentionincremental0H · 5M · 7L2026-07-14 17:02
- 92cce08needs attentionincremental1H · 4M · 3L2026-07-14 02:00
- b7dd610needs attentionincremental0H · 6M · 7L2026-07-14 01:43
- 8c43554needs attentionfull0H · 2M · 1L2026-07-14 01:15
- 2149391blockedfull8H · 6M · 7L2026-07-10 17:30