You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add the CONSUMING counterpart to /portaljs-add-dcat (po-uu5, which EXPOSES
DCAT-AP). /portaljs-migrate could read DCAT-US /data.json + CKAN/Socrata/ODS/
ArcGIS, but not full DCAT / DCAT-AP RDF feeds — so PortalJS could publish
DCAT-AP yet not ingest a European/national DCAT-AP catalog. This closes the
gap: a portal is now a full two-way DCAT interop node.
Template (examples/portaljs-catalog):
- lib/metadata/dcat-harvest.ts — zero-dep inbound harvester, the inverse of
dcat-rdf.ts's serializer. parseRdf() reads JSON-LD, Turtle, and RDF/XML into
one triple model; harvestTriples() walks Catalog -> Dataset -> Distribution
and maps to the canonical {slug,namespace,name,description,keywords,
resources[]} shape /portaljs-migrate writes. Format auto-detected from the
payload + Content-Type. Profile inferred from dct:conformsTo via the SAME
dcat-profiles.ts registry po-uu5 exposes (expose/consume stay in sync).
Reads DCAT 2/3, DCAT-AP + national (SE/CH/DE), GeoDCAT-AP spatial fields
(dct:spatial/locn:geometry/dcat:bbox), and Croissant (schema.org JSON-LD)
best-effort. Resilient: skips datasets with no title/distribution to a
warnings[] rather than aborting a partial/nonstandard feed.
- lib/metadata/index.ts — export harvest/harvestTriples/parseRdf/detectFormat/
toCanonicalEntry + types.
- scripts/harvest-roundtrip.test.ts — round-trip proof: serialize the sample
catalog to 6 profiles x 3 serializations, harvest each back, assert field
fidelity + cross-serialization triple-count equivalence.
Skill:
- .claude/commands/portaljs-migrate.md — new --source dcat-rdf (feed URL or a
portal page that autodiscovers one via <link rel="alternate">); RDF->canonical
mapping table; pagination (hydra:next); resilience notes; two-way-interop
section linking /portaljs-add-dcat.
Verified: tsc clean; round-trip clean (6 profiles x 3 serializations). Real
sources harvested — data.europa.eu JSON-LD (multilingual description intact) and
govdata.de RDF/XML (100 DCAT-AP.de datasets in 22ms). End-to-end: merged 5 real
DE datasets into datasets.json, next build green, showcase HTML + /search render
the harvested titles/namespaces (datasets.json restored after).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: .claude/commands/portaljs-migrate.md
+99-11Lines changed: 99 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,5 @@
1
1
---
2
-
description: Migrate (harvest) datasets between open-data platforms. Reads CKAN, a DCAT-US /data.json catalog (DKAN, ArcGIS Hub, data.gov), Socrata, OpenDataSoft, or an ArcGIS FeatureServer, and writes them to a static PortalJS catalog (datasets.json, link-by-URL or download data files into Cloudflare R2 via Git LFS / Giftless) or pushes them into a CKAN instance over its API.
2
+
description: Migrate (harvest) datasets between open-data platforms. Reads CKAN, a DCAT-US /data.json catalog (DKAN, ArcGIS Hub, data.gov), a DCAT / DCAT-AP RDF feed (JSON-LD, Turtle, or RDF/XML — data.europa.eu, national DCAT-AP portals, GeoDCAT-AP), Socrata, OpenDataSoft, or an ArcGIS FeatureServer, and writes them to a static PortalJS catalog (datasets.json, link-by-URL or download data files into Cloudflare R2 via Git LFS / Giftless) or pushes them into a CKAN instance over its API.
3
3
allowed-tools: Read, Write, Edit, Bash, WebFetch
4
4
---
5
5
@@ -21,21 +21,31 @@ catalog, so the portal stands alone and needs no backend.
21
21
Every source is read into one **canonical** shape (the template's `Dataset`/`Resource`
22
22
type — a Frictionless-aligned `{ slug, namespace, name, description, resources[] }`), then
23
23
written to the target from that canonical form. Add a source once and it migrates to every
24
-
target. v1 ships two readers and one writer.
24
+
target.
25
25
26
-
**Sources (v1):**
26
+
**Sources:**
27
27
28
28
| Source |`--source`| How it's read | Covers |
29
29
| ------ | ---------- | ------------- | ------ |
30
30
|**CKAN**|`ckan`| REST API (`package_search` / `package_show`) | any CKAN instance |
31
-
|**DCAT-US `/data.json`**|`dcat`| one catalog document |**DKAN, ArcGIS Hub, data.gov**, other DCAT-US publishers |
31
+
|**DCAT-US `/data.json`**|`dcat`| one catalog document (plain JSON) |**DKAN, ArcGIS Hub, data.gov**, other DCAT-US publishers |
32
+
|**DCAT / DCAT-AP RDF feed**|`dcat-rdf`| RDF catalog in JSON-LD, Turtle, or RDF/XML |**data.europa.eu**, national **DCAT-AP** portals (SE/CH/DE), GeoDCAT-AP, any DCAT 2/3 RDF feed |
0 commit comments