Skip to content

Named import mappings: wire defineMapping into the import path (#2611) - #2629

Merged
os-zhuang merged 3 commits into
mainfrom
claude/metadata-showcase-redesign-ougiov
Jul 5, 2026
Merged

Named import mappings: wire defineMapping into the import path (#2611)#2629
os-zhuang merged 3 commits into
mainfrom
claude/metadata-showcase-redesign-ougiov

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

What

Closes#2611.

defineMapping / stack mappings: artifacts were registered but never consumed — the classic enterprise capability (recurring feeds, packaged migration kits, programmatic imports) existed only as inert metadata. Two commits:

  1. feat(rest,spec) — the consumer.
    • POST /data/:object/import (sync + async job path, shared prepareImportRequest) accepts mappingName, resolving the registered artifact via getMetaItem('mapping') and applying its fieldMapping pipeline as a strict projection before the existing coercion/reference resolution.
    • Transforms per Prime Directive chore: version packages #10 (implement or reject loudly): none/constant/map/split/join implemented; lookup passes through to the import path's built-in name→id resolution (no second dialect); javascript → 400 UNSUPPORTED_TRANSFORM (no server-side sandbox — a silently skipped transform would corrupt data).
    • The artifact's mode/upsertKey apply as writeMode/matchFieldsdefaults; explicit request values win. mappingName is mutually exclusive with the inline rename (400 CONFLICTING_MAPPING) — one mapping source of truth per request; the inline {column: field} rename keeps its one-off wizard semantics (unmapped passthrough), the artifact is the governed ETL form (strict projection).
    • Loud, specific errors: MAPPING_NOT_FOUND (404), MAPPING_TARGET_MISMATCH, MAPPING_FORMAT_MISMATCH/MAPPING_FORMAT_UNSUPPORTED, CONFLICTING_MAPPING, UNSUPPORTED_TRANSFORM.
    • Producer-side gate (PD#12): defineStack cross-reference validation rejects mappings targeting undefined objects and any javascript transform at build time.
  2. feat(showcase) — the demo + waiver flip.showcase_inquiry_feed maps a marketing tool's CSV (Full Name/Channel/…) onto showcase_inquiry with a map transform for channel codes and artifact-declared idempotent upsert on email. STACK_COLLECTION_COVERAGE.mappings flips waived → demonstrated; gap-fill tests assert wiring and target liveness (every mapped target/upsertKey must be a real field). Data tour documents the workflow.

Why

Enterprise deployments live on recurring, headless imports (nightly ERP feeds, bank statements, partner files) and packaged migration kits — both need the mapping to be a governed, versioned, package-shippable artifact, not wizard state. This lands the missing consumer, and the capability now passes the ADR-0088 admission test it previously failed.

Verification

  • Unit: 7 transform-semantics tests (import-mapping.test.ts). Integration: 6 end-to-end route tests against the real engine/protocol/registry — the happy path proves artifact map → select-label coercion composition, lookup name→id, strict projection, artifact upsert defaults, plus every error code. Build lint: 3 new defineStack tests. Suites: rest 211, spec 6695, showcase verify 55 — green.
  • Live server E2E (fresh objectstack dev): imported a marketing CSV with mappingName=showcase_inquiry_feedcreated: 2; re-imported the same file → updated: 2 (idempotent upsert from artifact defaults); unknown mapping → 404; stored rows show Channel: "Webform"→source: "website" and "Partner Referral"→"referral".

🤖 Generated with Claude Code

https://claude.ai/code/session_01G6pPpRszk9cD3SxcKNFMWs


Generated by Claude Code

claude added 2 commits July 5, 2026 08:16
… into the import path
Closes the consumer gap behind #2611: a registered `mapping` artifact
(defineMapping / stack mappings:) is now resolvable by name at import.
- rest: `mappingName` on POST /data/:object/import (sync + async job path
via the shared prepareImportRequest). Resolution via getMetaItem
('mapping'); 404 MAPPING_NOT_FOUND, 400 MAPPING_TARGET_MISMATCH /
MAPPING_FORMAT_MISMATCH / CONFLICTING_MAPPING (mutually exclusive with
the inline rename — one mapping source of truth per request). The
artifact's mode/upsertKey apply as writeMode/matchFields DEFAULTS
(explicit request values win).
- transforms (import-mapping.ts, unit-tested): none/constant/map/split/
join implemented; lookup passes the raw value through to the import
path's existing reference resolution (no second dialect); javascript is
REJECTED with 400 UNSUPPORTED_TRANSFORM — no server-side sandbox, and a
silently skipped transform would corrupt data (Prime Directive #10).
Artifact output is a strict projection (only mapped targets reach the
write path); the inline mapping keeps its passthrough rename semantics —
inline = one-off wizard rename, artifact = reusable governed ETL.
- spec: defineStack cross-reference validation now rejects a mapping
whose targetObject is undefined and any javascript transform at BUILD
time (Prime Directive #12: fail at the producer).
Tests: 7 transform unit tests + 6 end-to-end route tests (real engine/
protocol/registry; happy path proves artifact map→label→code coercion
composition, lookup name→id, strict projection, artifact upsert
defaults, and every error code) + 3 build-lint tests.
rest 211 · spec 6695 — green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G6pPpRszk9cD3SxcKNFMWs
- src/data/mappings/index.ts — showcase_inquiry_feed: the marketing-CSV →
inquiry mapping (rename + map transform for channel codes), with
artifact-declared idempotent upsert on email. Wired via stack mappings:.
- STACK_COLLECTION_COVERAGE.mappings: waived → demonstrated (the consumer
landed in the previous commit).
- gap-fill tests assert the wiring AND target liveness: every mapped
target and upsertKey must be a real field of the target object — a
typo'd target would silently import into nowhere.
- Data tour documents the named-mapping workflow; changeset added.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G6pPpRszk9cD3SxcKNFMWs
@vercel

vercelBot commented Jul 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJul 5, 2026 8:48am

Request Review

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling size/l labels Jul 5, 2026
@github-actions

github-actionsBot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/metadata-core, @objectstack/rest, @objectstack/spec.

94 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx(via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx(via @objectstack/spec)
  • content/docs/ai/skills.mdx(via @objectstack/spec)
  • content/docs/api/client-sdk.mdx(via @objectstack/spec)
  • content/docs/api/environment-routing.mdx(via @objectstack/spec)
  • content/docs/api/error-catalog.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx(via @objectstack/spec)
  • content/docs/api/index.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/automation/approvals.mdx(via packages/spec)
  • content/docs/automation/flows.mdx(via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx(via packages/spec)
  • content/docs/automation/hooks.mdx(via @objectstack/spec)
  • content/docs/automation/index.mdx(via @objectstack/spec)
  • content/docs/automation/webhooks.mdx(via @objectstack/spec)
  • content/docs/automation/workflows.mdx(via @objectstack/spec)
  • content/docs/concepts/architecture.mdx(via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx(via packages/spec)
  • content/docs/concepts/index.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx(via @objectstack/metadata-core, packages/spec)
  • content/docs/concepts/north-star.mdx(via packages/spec)
  • content/docs/data-modeling/analytics.mdx(via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx(via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx(via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx(via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx(via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx(via @objectstack/spec)
  • content/docs/data-modeling/index.mdx(via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx(via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx(via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx(via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx(via @objectstack/spec)
  • content/docs/deployment/cloud-artifact-api.mdx(via packages/spec)
  • content/docs/deployment/troubleshooting.mdx(via @objectstack/spec)
  • content/docs/getting-started/cli.mdx(via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx(via @objectstack/spec)
  • content/docs/getting-started/examples.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx(via @objectstack/spec)
  • content/docs/getting-started/validating-metadata.mdx(via @objectstack/spec)
  • content/docs/kernel/cluster.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx(via packages/spec)
  • content/docs/kernel/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx(via packages/spec)
  • content/docs/kernel/services-checklist.mdx(via @objectstack/spec)
  • content/docs/permissions/authorization.mdx(via packages/rest, packages/spec)
  • content/docs/permissions/permission-sets.mdx(via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx(via @objectstack/spec)
  • content/docs/permissions/profiles.mdx(via @objectstack/spec)
  • content/docs/permissions/roles.mdx(via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx(via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx(via @objectstack/spec)
  • content/docs/plugins/development.mdx(via @objectstack/spec)
  • content/docs/plugins/index.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/plugins/packages.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx(via @objectstack/spec)
  • content/docs/protocol/diagram.mdx(via packages/spec)
  • content/docs/protocol/knowledge.mdx(via @objectstack/spec)
  • content/docs/protocol/objectos/config-resolution.mdx(via @objectstack/spec)
  • content/docs/protocol/objectos/i18n-standard.mdx(via @objectstack/spec)
  • content/docs/protocol/objectos/lifecycle.mdx(via @objectstack/spec)
  • content/docs/protocol/objectos/plugin-spec.mdx(via @objectstack/spec)
  • content/docs/protocol/objectos/runtime-capabilities.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx(via packages/spec)
  • content/docs/protocol/objectql/query-syntax.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx(via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx(via packages/spec)
  • content/docs/protocol/objectui/record-alert.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx(via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/releases/index.mdx(via @objectstack/spec)
  • content/docs/releases/v9.mdx(via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx(via @objectstack/spec)
  • content/docs/ui/dashboards.mdx(via @objectstack/spec)
  • content/docs/ui/forms.mdx(via @objectstack/spec)
  • content/docs/ui/index.mdx(via @objectstack/spec)
  • content/docs/ui/setup-app.mdx(via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

…passed)
With the import consumer landed, mapping now passes all three admission
criteria (independent lifecycle · governable · real consumer), so it
graduates from a bare stack collection to a registry kind (26 → 27):
- MetadataTypeSchema + DEFAULT_METADATA_TYPE_REGISTRY entry (domain data,
allowRuntimeCreate: true so the import wizard can SAVE a hand-built
mapping as a named artifact; packaged mappings stay locked like every
artifact-backed item; *.mapping.ts file pattern).
- metadata-type-schemas: MappingSchema wired → Studio's zero-code
metadata admin auto-renders list/edit forms for mappings, and
/api/v1/meta/types/mapping serves the JSON Schema (no Studio code).
- metadata-create-seeds: 'New Import Mapping' template so runtime-create
starts from a valid artifact.
- metadata-core lockstep enum; showcase KIND_COVERAGE gains the mapping
kind entry (and drops the now-redundant stack-collection row);
reference docs regenerated.
spec 6696 · metadata-core 80 · objectql 773 · rest 211 · showcase verify
— green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G6pPpRszk9cD3SxcKNFMWs
@os-zhuang
os-zhuang marked this pull request as ready for review July 5, 2026 08:59
@os-zhuang
os-zhuang merged commit fce8ff4 into mainJul 5, 2026
17 checks passed
@os-zhuang
os-zhuang deleted the claude/metadata-showcase-redesign-ougiov branch July 5, 2026 08:59
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/lteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

defineMapping artifacts are registered but never consumed — wire named mappings into REST import or de-scope from the stack

2 participants

@os-zhuang@claude