Elie Habib
ce797da3a4
chore(energy-atlas): backfill productClass on oil pipelines + enforce enum ( #3383 )
...
* chore(energy-atlas): backfill productClass on all oil pipelines + enforce enum
Prior state: 12/75 oil pipelines carried a `productClass: "crude"` tag;
63/75 did not. The field had zero consumers anywhere in the codebase
(no validator, no server handler, no frontend reader) — orphan metadata
from partial curation. Inconsistency spotted during the energy-data
audit after the Energy Atlas PR chain landed.
Changes:
1. Backfill all 63 missing entries with one of three values based on
the pipeline's name/operator/route:
- `crude` (70 total): crude-oil trunks, gathering lines, export
systems. Covers Druzhba, Enbridge Mainline, Keystone-XL, CPC,
BTC, ESPO, Sumed, Forties, Brent, OCP, OCENSA, EACOP, LAPSSET,
etc.
- `products` (4 total): explicit refined-product pipelines —
Abqaiq-Yanbu Products Line, Vadinar-Kandla, Yangzi-Hefei-Hangzhou,
Tuxpan-Mexico City.
- `mixed` (1 total): Salina Cruz-Minatitlán, the only dual-use
crude/products bridge in the set.
2. Promote productClass from orphan metadata to a schema invariant:
- Oil pipelines MUST declare one of {crude, products, mixed}.
- Gas pipelines MUST NOT carry the field (commodity IS its own
class there).
- Enforced in scripts/_pipeline-registry.mjs::validateRegistry.
3. Five new test assertions in tests/pipelines-registry.test.mts
cover both the data invariant (every oil entry has a valid value;
no gas entry has one) and the validator behavior (rejects missing,
rejects unknown enum value, rejects gas-with-productClass).
File formatting: the oil registry mixes two styles — multi-line (each
field on its own line) and compact (several fields packed onto one
line). The insertion preserves the local style for each entry by
reusing the whitespace that follows `"commodityType": "oil",`.
No runtime consumers yet; this lands the data hygiene so future
downstream work (crude-vs-products split on the map, refined-product
shock calcs) can rely on the field being present and valid.
* fix(energy-atlas): import VALID_OIL_PRODUCT_CLASSES in tests instead of redefining
Greptile P2 on #3383 : the test file defined its own inline
`const VALID = new Set(['crude', 'products', 'mixed'])`, mirroring the
registry's `VALID_OIL_PRODUCT_CLASSES`. If a future PR adds a new class
(e.g. `condensate`) to the registry, the inline copy wouldn't update —
the data test would start reporting valid pipelines as failing before
the validator rejects them, creating a confusing diagnostic gap.
Export `VALID_OIL_PRODUCT_CLASSES` from `scripts/_pipeline-registry.mjs`
and import it in the test. Single source of truth; no drift possible.
2026-04-24 23:36:51 +04:00
..
2026-04-24 19:09:36 +04:00
2026-04-22 16:44:12 +04:00
2026-04-23 22:21:25 +04:00
2026-04-03 10:27:37 +04:00
2026-03-21 17:15:29 +04:00
2026-04-22 21:37:25 +04:00
2026-04-24 18:13:22 +04:00
2026-04-04 12:35:23 +04:00
2026-03-30 08:10:37 +04:00
2026-03-29 16:59:24 +04:00
2026-04-13 21:57:11 +04:00
2026-04-13 20:35:16 +04:00
2026-04-13 15:05:44 +04:00
2026-04-23 07:34:07 +04:00
2026-04-19 15:18:12 +04:00
2026-04-18 12:30:08 +04:00
2026-04-23 11:25:05 +04:00
2026-04-21 08:58:02 +04:00
2026-04-23 11:50:19 +04:00
2026-04-19 14:15:59 +04:00
2026-04-18 21:49:17 +04:00
2026-04-24 16:25:14 +04:00
2026-04-21 22:25:54 +04:00
2026-04-24 16:25:14 +04:00
2026-04-21 13:46:21 +04:00
2026-04-18 23:32:48 +04:00
2026-04-19 14:15:59 +04:00
2026-04-19 14:15:59 +04:00
2026-04-19 14:15:59 +04:00
2026-04-18 20:27:08 +04:00
2026-04-22 08:21:01 +04:00
2026-04-16 07:58:18 +04:00
2026-04-04 18:24:15 +04:00
2026-04-22 16:08:43 +04:00
2026-04-22 16:08:43 +04:00
2026-04-22 15:07:22 +04:00
2026-04-22 15:07:22 +04:00
2026-04-22 15:42:35 +04:00
2026-04-22 23:37:46 +04:00
2026-04-22 15:47:57 +04:00
2026-04-24 19:09:36 +04:00
2026-04-12 21:34:38 +04:00
2026-04-07 22:51:16 +04:00
2026-03-14 23:27:27 +04:00
2026-03-14 17:14:46 +04:00
2026-03-27 12:21:23 +04:00
2026-03-26 10:13:10 +04:00
2026-04-05 09:22:07 +04:00
2026-04-04 08:11:49 +04:00
2026-04-04 08:11:49 +04:00
2026-04-13 19:44:25 +04:00
2026-03-04 20:42:51 +04:00
2026-04-22 09:55:59 +03:00
2026-04-22 09:55:59 +03:00
2026-03-15 02:40:33 +04:00
2026-03-14 21:29:21 +04:00
2026-04-12 20:29:50 +04:00
2026-03-15 15:42:27 +04:00
2026-04-13 08:04:50 +04:00
2026-04-10 17:35:21 +04:00
2026-04-04 15:38:02 +04:00
2026-04-15 09:16:27 +04:00
2026-03-07 18:23:32 +04:00
2026-04-13 19:44:25 +04:00
2026-04-01 23:27:54 +04:00
2026-03-23 23:23:06 +04:00
2026-03-08 22:54:40 +04:00
2026-03-08 09:33:49 +04:00
2026-03-18 10:42:49 +04:00
2026-04-23 22:21:25 +04:00
2026-04-11 09:39:27 +04:00
2026-03-18 10:19:17 +04:00
2026-04-21 22:36:30 +04:00
2026-04-17 17:43:21 +04:00
2026-04-20 10:19:03 +04:00
2026-04-16 17:28:16 +04:00
2026-02-26 10:07:59 +04:00
2026-04-05 12:52:20 +04:00
2026-04-22 09:55:59 +03:00
2026-04-07 22:24:17 +04:00
2026-04-22 15:59:03 +04:00
2026-04-22 09:55:59 +03:00
2026-04-24 19:08:07 +04:00
2026-04-09 13:06:08 +04:00
2026-04-05 13:26:19 +04:00
2026-04-14 09:05:50 +04:00
2026-04-12 22:41:44 +04:00
2026-04-09 22:16:24 +04:00
2026-03-21 16:24:17 +04:00
2026-04-18 15:19:12 +04:00
2026-04-24 07:53:51 +04:00
2026-04-24 07:53:51 +04:00
2026-03-13 12:32:53 +04:00
2026-04-13 13:00:14 +04:00
2026-03-19 12:11:57 +04:00
2026-03-24 18:52:02 +04:00
2026-03-15 15:57:22 +04:00
2026-04-23 20:38:11 +04:00
2026-03-19 03:45:32 +04:00
2026-04-23 07:34:07 +04:00
2026-04-23 07:34:07 +04:00
2026-04-05 12:32:13 +04:00
2026-04-08 20:05:13 +04:00
2026-04-16 10:41:15 +04:00
2026-02-28 10:58:53 +04:00
2026-04-22 22:58:31 +04:00
2026-04-12 07:58:01 +04:00
2026-04-22 22:58:31 +04:00
2026-03-15 15:42:27 +04:00
2026-03-19 10:35:00 +04:00
2026-04-14 08:19:47 +04:00
2026-04-14 08:19:47 +04:00
2026-04-12 22:53:32 +04:00
2026-04-12 19:41:27 +04:00
2026-03-28 23:07:18 +04:00
2026-04-13 22:03:27 +04:00
2026-02-17 19:22:55 +04:00
2026-04-24 16:25:14 +04:00
2026-03-03 15:13:29 +04:00
2026-04-14 08:28:57 +04:00
2026-04-09 13:06:08 +04:00
2026-04-13 12:51:35 +04:00
2026-04-13 21:53:21 +04:00
2026-04-11 16:44:25 +04:00
2026-03-04 20:42:51 +04:00
2026-03-31 12:21:11 +04:00
2026-04-09 13:06:08 +04:00
2026-04-09 13:06:08 +04:00
2026-02-25 10:53:22 +04:00
2026-03-13 08:50:10 +04:00
2026-03-21 16:47:42 +04:00
2026-03-19 17:00:45 +04:00
2026-04-24 19:01:47 +04:00
2026-03-14 18:11:11 +04:00
2026-02-15 19:22:40 +04:00
2026-04-24 19:09:21 +04:00
2026-03-05 09:28:07 +04:00
2026-04-11 17:54:26 +04:00
2026-03-28 21:17:41 +04:00
2026-03-13 00:21:08 +04:00
2026-04-23 16:24:03 +03:00
2026-03-31 12:21:11 +04:00
2026-03-20 17:23:51 +04:00
2026-03-20 17:23:51 +04:00
2026-04-23 19:42:13 +04:00
2026-03-12 08:01:32 +04:00
2026-04-21 19:41:58 +04:00
2026-03-01 10:07:38 +04:00
2026-03-17 01:41:54 +04:00
2026-03-16 08:40:14 +04:00
2026-02-18 23:31:44 +04:00
2026-02-18 23:31:44 +04:00
2026-04-22 09:55:59 +03:00
2026-04-13 08:35:38 +04:00
2026-03-20 16:08:48 +04:00
2026-04-24 16:25:14 +04:00
2026-04-24 16:25:14 +04:00
2026-04-24 16:25:14 +04:00
2026-04-20 08:40:29 +04:00
2026-04-12 14:04:31 +04:00
2026-04-16 09:24:12 +04:00
2026-03-01 15:59:53 +04:00
2026-03-01 15:59:53 +04:00
2026-02-28 18:02:23 +04:00
2026-04-09 13:06:08 +04:00
2026-04-12 00:18:04 +04:00
2026-04-23 07:34:07 +04:00
2026-04-23 07:34:07 +04:00
2026-04-23 07:34:07 +04:00
2026-04-24 23:36:51 +04:00
2026-04-07 22:56:08 +04:00
2026-04-13 14:13:18 +04:00
2026-04-22 22:37:08 +04:00
2026-04-09 13:06:08 +04:00
2026-03-12 14:02:58 +04:00
2026-03-27 10:43:32 +04:00
2026-04-04 11:48:12 +04:00
2026-04-22 16:21:40 +04:00
2026-04-06 12:28:21 +04:00
2026-04-17 17:43:21 +04:00
2026-04-14 13:14:53 +04:00
2026-04-24 18:00:41 +03:00
2026-04-24 18:14:04 +04:00
2026-04-22 15:26:09 +04:00
2026-04-12 11:06:51 +04:00
2026-04-12 00:23:20 +04:00
2026-04-12 01:03:28 +04:00
2026-04-11 23:39:20 +04:00
2026-04-12 07:58:01 +04:00
2026-04-12 09:56:35 +04:00
2026-04-11 20:28:55 +04:00
2026-04-04 23:19:33 +04:00
2026-04-04 23:19:33 +04:00
2026-03-19 09:09:48 +04:00
2026-04-13 21:53:21 +04:00
2026-04-23 08:51:27 +04:00
2026-04-22 16:44:12 +04:00
2026-04-24 18:14:04 +04:00
2026-04-22 16:44:12 +04:00
2026-04-23 09:01:30 +04:00
2026-04-24 18:13:22 +04:00
2026-04-05 17:46:22 +04:00
2026-04-22 23:57:28 +04:00
2026-04-23 09:01:30 +04:00
2026-04-23 09:01:30 +04:00
2026-04-23 09:01:30 +04:00
2026-04-24 18:14:29 +04:00
2026-04-24 09:37:18 +04:00
2026-04-24 18:25:50 +04:00
2026-04-11 20:04:26 +04:00
2026-04-24 18:14:04 +04:00
2026-04-22 17:10:38 +04:00
2026-04-23 09:01:30 +04:00
2026-04-12 10:24:19 +04:00
2026-04-09 22:06:54 +04:00
2026-04-09 22:06:54 +04:00
2026-04-12 10:24:19 +04:00
2026-04-04 19:27:37 +04:00
2026-04-23 09:01:30 +04:00
2026-04-24 18:14:04 +04:00
2026-04-24 18:14:04 +04:00
2026-04-22 06:52:07 +04:00
2026-04-21 22:37:27 +04:00
2026-04-22 06:52:07 +04:00
2026-04-24 18:14:04 +04:00
2026-04-23 10:25:18 +04:00
2026-04-23 10:25:18 +04:00
2026-04-23 09:01:30 +04:00
2026-04-23 09:01:30 +04:00
2026-04-24 18:30:59 +04:00
2026-04-23 10:25:18 +04:00
2026-04-24 18:14:04 +04:00
2026-04-12 10:22:21 +04:00
2026-04-12 10:10:10 +04:00
2026-04-13 13:00:58 +04:00
2026-04-04 16:24:28 +04:00
2026-04-23 09:01:30 +04:00
2026-04-08 20:05:13 +04:00
2026-04-11 09:11:07 +04:00
2026-04-12 09:57:09 +04:00
2026-04-12 08:16:02 +04:00
2026-04-12 08:25:38 +04:00
2026-04-12 08:25:38 +04:00
2026-03-19 11:05:41 +04:00
2026-03-15 16:54:42 +04:00
2026-02-15 19:22:40 +04:00
2026-03-21 20:26:02 +04:00
2026-03-21 20:26:02 +04:00
2026-04-22 09:55:59 +03:00
2026-04-11 20:19:01 +04:00
2026-04-11 06:58:43 +04:00
2026-04-16 20:02:31 +04:00
2026-04-11 17:05:39 +04:00
2026-04-24 18:14:04 +04:00
2026-04-12 09:53:21 +04:00
2026-04-14 12:29:17 +04:00
2026-04-15 09:16:27 +04:00
2026-04-15 09:16:27 +04:00
2026-04-14 22:11:56 +04:00
2026-04-18 14:40:00 +04:00
2026-04-14 09:02:21 +04:00
2026-04-14 22:11:56 +04:00
2026-04-14 22:11:56 +04:00
2026-04-14 12:36:07 +04:00
2026-04-13 21:57:11 +04:00
2026-04-14 08:19:47 +04:00
2026-04-24 07:21:13 +04:00
2026-03-21 12:43:56 +04:00
2026-04-12 10:10:10 +04:00
2026-04-12 11:39:48 +04:00
2026-04-24 18:13:41 +04:00
2026-04-12 10:10:10 +04:00
2026-04-23 21:35:25 +04:00
2026-04-14 09:02:21 +04:00
2026-04-15 09:16:27 +04:00
2026-04-14 13:28:00 +04:00
2026-03-16 08:48:00 +04:00
2026-04-22 23:37:46 +04:00
2026-04-22 09:55:59 +03:00
2026-03-17 12:17:25 +04:00
2026-03-21 16:37:43 +04:00
2026-04-24 18:00:41 +03:00
2026-04-23 07:34:07 +04:00
2026-03-28 19:52:59 +04:00
2026-04-22 17:11:18 +04:00
2026-03-19 12:11:57 +04:00
2026-04-09 22:16:24 +04:00
2026-04-23 16:24:03 +03:00
2026-04-11 14:26:36 +04:00
2026-04-23 16:24:03 +03:00
2026-04-15 14:00:57 +04:00
2026-03-17 19:25:08 +04:00
2026-04-23 07:34:07 +04:00
2026-04-23 07:34:07 +04:00
2026-04-23 07:34:07 +04:00
2026-04-24 16:25:14 +04:00
2026-03-31 12:21:11 +04:00
2026-04-24 16:25:14 +04:00
2026-04-11 08:39:13 +04:00
2026-03-14 21:29:21 +04:00
2026-04-18 23:14:00 +04:00
2026-04-12 08:36:42 +04:00
2026-04-09 21:41:26 +04:00
2026-04-22 09:55:59 +03:00
2026-04-18 22:54:58 +04:00
2026-04-23 07:58:40 +04:00
2026-03-19 11:08:04 +04:00
2026-03-17 14:24:26 +04:00
2026-03-17 14:24:26 +04:00
2026-04-11 08:21:08 +04:00
2026-04-18 23:14:00 +04:00
2026-04-04 23:18:53 +04:00
2026-04-22 09:55:59 +03:00
2026-04-15 09:16:27 +04:00
2026-04-01 10:15:26 +04:00
2026-03-02 14:47:14 +04:00
2026-04-11 17:10:06 +04:00
2026-03-08 14:14:16 +04:00
2026-04-24 08:21:07 +04:00
2026-03-27 11:49:01 +04:00
2026-03-27 16:52:56 +04:00
2026-04-11 07:07:11 +04:00
2026-04-16 09:25:06 +04:00