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/matchFields defaults; 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

vercel Bot commented Jul 5, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 5, 2026 8:48am

Request Review

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

github-actions Bot 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 main Jul 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 free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/l tests tooling

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