entity

Parameter Key

The canonical identity and meaning of one parameter, independent of where it is used or how it is rendered. Owned by bim-ontology, consumed by product-marketplace. One record per handle, never one per product model.

Entity(Aggregate Root)Status: Implemented in api-v1Aggregate Root

Purpose

A parameter key is what this parameter is, once. Width is one key, not one key per product model, per class, or per vendor. Everything else about a parameter is a separate concept that references the key: ParameterSpec for value semantics, ParameterControl for presentation, ParameterGroup for authoring grouping, ParameterValue for canonical values and ParameterValueGroup for reusable sets of them, ClassParameter for the assignment to an object class, and RevitParameterProjection for the Revit-facing expression.

Keys are reused through dictionary lookup by name, handle, or domain_id — never minted per scrape target.

Ownership boundary with Product Marketplace

ParameterKey is one concept, owned here. BIM Ontology defines parameter keys and their relationships to object classes and Revit. Product Marketplace assigns a class to a product and uses the parameters that come with it; its own pages cross-reference this one instead of redefining the key. The junctions that genuinely belong to product-marketplace — ModelParameter, ModelParameterAllowedValue, VariantParameter — stay in that domain and reference this entity.

Lifecycle

draft → active → approved → archived, from PARAMETER_STATUSES.

TransitionRule
draft → activeSpec and control need not be complete, but if either reference is set it must resolve to the same record, and a resolved spec/control pair must be compatible
draft → approvedSame stewardship gate as active → approved. Activate is not required
active → approvedRequires a parameter spec and a parameter control. BIM usage is not required
active → archivedAllowed
approved → archivedAllowed; idempotent when already archived
archived → draftreinstate() only. Archived has no forward transition

draft → archived is not legal. Both active and approved count as usable (isUsableParameterStatus); only approved counts as vetted (isApprovedParameterStatus). Activate remains the scraper path into displayable-but-unvetted; a steward who already meets the approve gates may skip it.

Hard delete is deliberately not a lifecycle transition — markDeleted records ParameterKeyDeleted for audit and is allowed from any status, with the actual removal left to the use case.

Why active exists

This is a business contract, not an extra approval step. active means displayable-but-unvetted.

When a scraper reads a product page it either maps the scraped attribute onto an existing approved key, or it creates a new key in active. The active key is live immediately — a scraped product_spec reaches the e-commerce page without waiting for a steward — while still being visibly flagged as needing canonical mapping. A steward later promotes it to approved or folds it into an existing key. Without active, either scraped product data would be invisible until a human reviewed it, or unvetted keys would be indistinguishable from canonical ones.

ParameterKey is the only aggregate in the module with this state (ADR-0052). Nothing renders an ObjectClass or a RevitParameterProjection to a customer ahead of review, so neither needs the tier.

The ordering is load-bearing downstream: automatic Revit projection is triggered by ParameterKeyApproved — not by creation and not by activation. An active key is deliberately not yet in Revit.

Usages

variant_option, product_spec, bim_parameter, mfg_takeoff, qto_takeoff (PARAMETER_USAGES). A usage set, when present, must be non-empty and may only contain supported values; addUsages unions onto the existing set idempotently.

bim_parameter membership is the load-bearing one for Revit. It gates automatic projection ensure and archive, and it is required to markSystem. It is not an approve precondition — a product_spec-only key can be canonical. It is not the same thing as Revit document altitude, which is always spelled revit_*.

Invariants

  • name and handle are both required and non-empty.
  • A persisted key must carry a lifecycleStatus; rehydrating without one raises PARAMETER_KEY_LIFECYCLE_STATUS_REQUIRED.
  • Rehydrating a key that claims approved re-checks the approve requirements and fails with ParameterKeyLifecycleInvariantViolatedError if spec or control is missing. An approved key that does not satisfy its own gate cannot be loaded.
  • Approve requires a parameter spec and a parameter control — the missing ones are named in ParameterKeyApprovePreconditionError. usage:bim_parameter is not on that list.
  • Spec and control references are locked while approved or archived (ParameterKeyReferencesLockedError). Rename and regroup remain possible; changing what the value means does not.
  • A supplied spec or control must resolve to the record the key references, and the control must be compatible with the spec’s data type.
  • isSystem requires approved plus usage:bim_parameter, enforced both by markSystem and by metadata updates.
  • Usage sets may not be empty and may not contain unsupported values.

Domain Events

Exactly six, from ParameterKey.events.ts:

EventEmitted by
ParameterKeyCreatedcreate
ParameterKeyUpdatedupdateCanonicalMetadata, addUsages, markSystem — only when something actually changed
ParameterKeyActivatedactivate
ParameterKeyApprovedapprove
ParameterKeyArchivedarchive
ParameterKeyDeletedmarkDeleted (audit record; hard delete)

ParameterKeyApproved is what triggers the Revit projection ensure. ParameterKeyUpdated also reaches the projection side — for the ensure path and for archive-on-retirement — and ParameterKeyArchived archives the projection rather than deleting it, so the shared parameter GUID survives.

OpenAPI Operations

ADRs

The platform series lives in docs/adr/07_Architectural_Decision_Records.md. The per-file series is separate and the numbers collide — see docs/adr/README.md.

ADRDecision
Platform ADR-0048domain_id is the public identifier; never a rec… id in a payload
Platform ADR-0052active is displayable-but-unvetted and belongs to ParameterKey alone
Per-file ADR-0006Canonical parameter keys and values with per-level junctions
Per-file ADR-0009Parameter table base placement and cross-base sync