Skip to content

feat(catalog-gateway): unified resolve/lineage + first real DCAT emitter (read-only) - #1158

Open
mdheller wants to merge 1 commit into
mainfrom
feat/catalog-gateway
Open

feat(catalog-gateway): unified resolve/lineage + first real DCAT emitter (read-only)#1158
mdheller wants to merge 1 commit into
mainfrom
feat/catalog-gateway

Conversation

@mdheller

Copy link
Copy Markdown
Member

The Catalog Gateway first increment (strategy item B) — the GMS-equivalent seam the data-catalog design brief calls for, built by composing what already exists rather than forking it.

What

New apps/catalog-gateway/ (FastAPI), read-only over the shared file-state layout, with the Crystal Atlas contract families as the API contract:

  • GET /v1/catalog/{kind}/{id} — resolve source|asset|model|workflow
  • GET /v1/catalog/{kind}/{id}/lineage — upstream source_refs, best-effort resolved
  • GET /v1/catalog/asset/{id}.dcat.jsonthe first real DCAT / schema.org emitter (application/ld+json), the seam CKAN/DataHub/CK.org harvest from; carries prophet:distributionClass (the moat, exported)

Security

Ids constrained to [A-Za-z0-9._:-], .. refused, resolved path enforced under the catalog root — path traversal fails closed (tested).

Tests

tests/ — 7 passing (resolve/404, DCAT shape + access-rights mapping, lineage, traversal guard). Two real bugs were caught and fixed during test (regex admitting ..; the generic /{kind}/{id} route shadowing .dcat.json via Starlette ordering).

Not

Not a fork of crystal-atlas-contract-intel; not the Go tritrpc gateway. Next: registration (write path), search, real CKAN/DataHub-MCP/CK.org emitters off the DCAT bridge, and mounting the masking PDP as a read-path filter.

🤖 Generated with Claude Code

…ter (read-only)

New apps/catalog-gateway — the GMS-equivalent seam over the Crystal Atlas catalog
families (docs/strategy/PROPHET_DATA_CATALOG_DESIGN.md), composing existing pieces
rather than reinventing them (file-state layout from crystal-atlas-contract-intel;
Crystal Atlas contract families as the API contract).

First increment (read-only):
  * GET /v1/catalog/{kind}/{id}          — resolve source|asset|model|workflow entry
  * GET /v1/catalog/{kind}/{id}/lineage  — upstream source_refs, best-effort resolved
  * GET /v1/catalog/asset/{id}.dcat.json — the first REAL DCAT/schema.org emitter
    (application/ld+json), carrying prophet:distributionClass — the moat exported.

app/store.py: read-only over $SOCIOPROFIT_STATE_HOME/prophet-platform/catalog/<kind>/<id>.json;
ids constrained to [A-Za-z0-9._:-], ".." refused, resolved-path-under-root enforced
(path traversal fails closed).
app/dcat.py: asset-catalog-entry.v0 → dcat:Dataset (accessRights from distribution_class,
prov:wasDerivedFrom from source_refs) + Prophet extension.

tests/ (7): healthz, resolve found/404, unknown-kind 404, DCAT emitter shape +
access-rights mapping, lineage, id-validation/traversal guard.

Not fork of crystal-atlas-contract-intel, not the Go tritrpc gateway. Next increments:
registration (write), search, real CKAN/DataHub-MCP/CK.org emitters off the DCAT bridge,
masking-PDP mount.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant