Skip to content

Data Products (REQ-1634)

A data product is a named, owned bundle of tables published together for consumption. It is the unit the catalog exposes to consumers — not individual tables, but a curated surface a domain explicitly declares ready. Fields follow the ODPS (Open Data Product Standard) vocabulary where Provisa already has the source of truth. [tool-verified: provisa/core/models.py:318-342, provisa-ui/src/i18n/locales/en/dataProductsTab.json]

Domain ownership rule

Every data product is owned by exactly one domain (domain_id is a required field). A table may join a data product only when both share the same domain_id. The UI scopes the table picker to the product's domain; the backend rejects a product_id assignment whose domain does not match the product's at save time. [tool-verified: provisa/core/models.py:320, docs/arch/requirements.yaml:54573-54574]

A product that needs data from another domain must bring that data in as a domain view first, then include the view as a member.

Output ports

The tables and commands assigned to a data product are its output ports — the queryable surface consumers see. Assigning a table sets Table.product_id; clearing it removes the membership. A table belongs to at most one product. Commands in the same domain may also be assigned as members. [tool-verified: provisa/core/models.py:941, provisa-ui/src/i18n/locales/en/dataProductsTab.json:tablesLabel,commandsLabel]

Detail panel sections

Opening a data product in the admin UI shows these panels:

Panel What it shows
Output Ports Member tables and their columns; member commands; sample queries (GraphQL, SQL, Cypher, gRPC, JSON:API, REST)
Related Terms Glossary terms linked to the product's member tables
Related Tables Tables reachable from member tables through approved relationships but not yet part of the product
Relationships Approved relationships between this product's member tables
Lineage Column lineage graph showing member tables as the published endpoint plus every upstream table. Requires the view_governance capability
Input Ports One-hop inputs → transform → outputs derived from lineage. Requires view_governance
Data Quality Checker tables whose contracts scan this product's output ports; one row per check per run. Includes a rules modal and PII tag display

[tool-verified: provisa-ui/src/i18n/locales/en/dataProductsTab.json:detail]

Metadata export

Only tables assigned to a product publish to external catalogs by default. build_snapshot applies a data_products_only filter: unassigned tables are withheld, along with their relationship edges, lineage edges, and governance tags. Sources and domains always publish regardless. [tool-verified: provisa/api/metadata_export/builder.py:594,609,641]

A product with no exported members does not publish — an empty listing would claim a product exists with nothing behind it. [tool-verified: provisa/api/metadata_export/model.py:106-113]

Only catalogs with a native data-product concept publish it as a first-class entity; the rest publish the (already-filtered) member tables without a product grouping:

Catalog Published as
Snowflake Horizon SHARE + organization listing (native Data Product); publish=false keeps it DRAFT, publish=true takes it live. The listing's data dictionary covers every member and column; the first five members are featured and masked columns are hidden in the preview (REQ-1656)
BigQuery Analytics Hub Analytics Hub listing (native)
OpenMetadata DataProduct entity (native)
DataHub Native dataProduct URN entity with its own properties/ownership aspects
Collibra Asset of a Data Product community type, related to member tables
Apache Atlas Best-effort custom provisa_data_product typedef — Atlas has no native data-product type
Atlan Best-effort custom DataProduct typedef guess — Atlan has no documented stable type for this
OpenLineage Not a listing — member tables carry a provisa_data_product custom facet naming the product

[tool-verified: provisa/api/metadata_export/snowflake_horizon.py:389-418, provisa/api/metadata_export/bigquery_dataplex.py:112-136, provisa/api/metadata_export/openmetadata.py:326-344, provisa/api/metadata_export/datahub.py:133-136,443-483, provisa/api/metadata_export/collibra.py:129-133,371-388, provisa/api/metadata_export/atlas.py:134-147, provisa/api/metadata_export/atlan.py:60, provisa/api/metadata_export/openlineage.py:243,348]

Fields

Field Required Notes
id Yes Machine-readable stable identifier, e.g. customer_360
domain_id Yes Owning domain; membership rule enforced against this
name Yes Display name
owner_role No Role accountable for this product; distinct from the domain steward
team_role No Role whose holders form the day-to-day working team; resolves to individuals
purpose No What this product publishes and why
limitations No Known constraints, caveats, or exclusions
usage No How to consume this product
version No e.g. 1.2.0
status No e.g. proposed, active, deprecated, retired
sla No Service-level commitments; prose only — a product spans multiple member tables and a structured SLA cannot unambiguously name which member it describes
support No Free-text support guidance
support_contact No Email or URL; required by Snowflake Horizon Catalog organization listing manifests (REQ-1635)
publish No true to publish Horizon Catalog listings immediately; new listings default to DRAFT (REQ-1635)
custom_properties No Arbitrary key-value metadata not covered by the standard fields

[tool-verified: provisa/core/models.py:318-342, provisa/api/admin/types.py:104-118,538-551]