← all branches

claude/vigorous-stonebraker-41cc2d

needs attentionviewing older commit
64dc83d · incrementalpre-PRreviewed 2026-07-13 20:03 UTC0H · 1M · 7L · 1I
The branch
Purpose
Interactive public energy map of Mexico's SEN grid — showcasing CFE generation, transmission, tarifas, and planned projects
Goal
Add a 'private generation' layer: 18 privately-approved solar/wind projects from CNE's 1ª Convocatoria de Atención Prioritaria (planeación vinculante, Dec 2025)
Sub-goals
  • SG-1: New data file private_generation.json with 18 projects (CNE/SENER source)
  • SG-2: Wire fetch → GeoJSON FeatureCollection → map source/layer
  • SG-3: Click popup with project name, MW, storage, COD year, developer, location, MIA, source attribution
  • SG-4: Layer toggle button ('Generación privada (planeación vinculante)', #c084fc, off by default)
  • SG-5: Coordinate precision encoded in circle opacity (exact=0.6, near/muni=0.35)
The changes (whole branch)
What
New file apps/web/public/atlas/data/private_generation.json (18 projects). apps/web/public/atlas/index.html: adds 7th Promise.all fetch, builds privFC FeatureCollection, adds privgen source/layer, click handler, GROUPS/TOGS entry.
Why
Completes the branch's full planned-capacity picture alongside CFE's own construction/planning layer and Plan SEN transmission — giving users visibility into both public and private capacity additions.
Areas
apps/web/public/atlas/data/private_generation.json+240apps/web/public/atlas/index.html+74
Blast
2 files, +31/-4. Entire change is within the standalone atlas app (apps/web/public/atlas/). No backend, no API, no database, no other app affected. Static asset change only.
static-data-only no-tests-by-design public-facing-map
ci· no CI runs found for this branchcoderabbit· no .coderabbit.yaml in repo

Findings · 9

correctness2

low

Three Singuilucan projects render as overlapping circles — two may be unclickable

apps/web/public/atlas/data/private_generation.json:9

Saturno Solar (19.9713, -98.5750), Akuwa Solar (19.9660, -98.5680), and Delfín Solar (19.95, -98.56) are co-located in Singuilucan, Hidalgo. At default zoom levels the lower-z-order circles are occluded, making them unclickable. No clustering or jitter logic is present in the layer. Acceptable given 'muni' precision for Delfín, but worth noting.

low

mia field mixes MIA expedient codes with free-text status notes

apps/web/public/atlas/data/private_generation.json:17

Most entries use structured SEMARNAT codes (e.g. '13HI2025E0096'). Three entries use prose: 'aprobada 2026', 'aprobada', 'MIA-R 2025'; one uses a project name 'P.E. Panabá 1A/1B'. These render literally as 'MIA aprobada 2026' in the popup. If the field is ever used for registry lookup or URL-linking these will fail. Use '' for unknown codes and keep mia as a code-only field.

security1

low

Unsanitized field interpolation in popup HTML template

apps/web/public/atlas/index.html:304

Popup is built via template literals: `<b>${p.n}</b>`, `${p.dev}`, `${p.mia}`, etc., passed to a pop() function that likely sets innerHTML. Risk is low because the data source is a static, checked-in JSON file — not user input. However, if the JSON file is ever compromised or the source changes to a dynamic API, all string fields become an XSS vector. Mitigation: add a small escapeHtml(s) = s.replace(/&/g,'&amp;').replace(/</g,'&lt;') and wrap all interpolated fields.

conventions3

medium

About panel 'Fuentes de datos' missing CNE/SENER and Plan SEN entries

apps/web/public/atlas/index.html:136

The about panel lists 6 data sources but omits CNE/SENER (private_generation.json: '1ª Convocatoria de Atención Prioritaria') and CFE/Plan SEN (transmission.json added in the prior commit). The established convention is every dataset visible on the map has a corresponding 'Fuentes de datos' entry. Add: '<b>CNE · SENER</b> — proyectos aprobados (planeación vinculante, 1ª Convocatoria); <b>CFE · Plan SEN 2025-2030</b> — transmisión planeada'.

low

dev: 'n/d' sentinel bypasses empty-string fallback — renders literally in popup

apps/web/public/atlas/data/private_generation.json:22

The privFC mapping uses p.dev||'' and the popup uses p.dev?'<br>'+p.dev:''. The 'n/d' string is truthy, so it renders as a developer line reading 'n/d' rather than omitting the line. The consistent sentinel for 'unknown developer' in this codebase is '' (empty string).

low

GROUPS key order does not match TOGS render order

apps/web/public/atlas/index.html:307

GROUPS defines keys as {..., tx, privgen} (tx before privgen) but TOGS renders them as [..., privgen, tx]. The prior convention was to keep GROUPS and TOGS in the same logical order for readability. Move 'privgen:['privgen']' before 'tx:[...]' in GROUPS to match.

tests1

info

No data-integrity validation for atlas JSON files

apps/web/public/atlas/data/private_generation.json

The atlas has no test suite (standalone HTML, intentional). A lightweight Node/Vitest data integrity script checking required fields, valid lat/lng ranges, and numeric capacity would be the highest-leverage first test to add — catching entry errors like invalid mia codes or out-of-Mexico coordinates at CI time.

improvement2

low

Silent fetch failure — no console.warn when private_generation.json fails to load

apps/web/public/atlas/index.html:244

The .catch(()=>({projects:[]})) swallows all fetch errors. A 404 (e.g. during a deploy gap) would render the toggle button functional but the layer empty with no diagnostic. Add console.warn('privgen fetch failed', err) in the catch to aid debugging.

low

Projects with cod=0 show no COD indicator — consider 'año desconocido' label

apps/web/public/atlas/index.html:304

Three projects (Central Eólica 24, Global Hidalgo 2, Vientos del Caribe) have cod:0 (unknown). The popup renders `p.cod?' · op. '+p.cod:''` — so cod=0 shows nothing (0 is falsy — correct, no spurious '0'). However, users have no way to know COD is unknown vs simply not shown. Consider 'op. año desconocido' fallback for these three.

History · 10 commits

  1. a081002safeincremental0H · 0M · 0L2026-07-14 01:23
  2. 64dc83dneeds attentionincremental0H · 1M · 7L2026-07-13 20:03current
  3. ec4eea3needs attentionincremental1H · 3M · 7L2026-07-13 18:42
  4. f4b4129safeincremental0H · 0M · 3L2026-07-13 04:34
  5. 8ea0c8asafeincremental0H · 0M · 3L2026-07-13 04:21
  6. 37ce28asafeincremental0H · 2M · 3L2026-07-10 17:22
  7. d28c6daneeds attentionincremental0H · 3M · 10L2026-07-10 16:59
  8. 754a65dneeds attentionincremental0H · 3M · 4L2026-07-10 16:39
  9. a9190b2safeincremental0H · 0M · 5L2026-07-10 16:14
  10. 0bf12a0blockedfull1H · 2M · 4L2026-07-10 16:06