Skip to content

Data import: allow alternative match keys per row (e.g. credit code, else country + registration no.) #25578

Closed

Description

@objectstack-fleet

Ruled: 6377845536 · batch #9 item 3b · letter A · 2026-10-24T00:43:45Z (ordered key sets; a row blank on every set is a row error, not a silent skip)

Context

In hotsrm a supplier's identity depends on where it is registered (ADR-0007): domestic suppliers are unique by credit_code, overseas ones by country + registration_no (credit_code is blank for them). One legacy supplier sheet contains both.

Gap

ImportRequest.matchFields is a single key set for the whole import. With matchFields: ['credit_code'], overseas rows have a blank key and upsert creates them again on every run (duplicates), unless skipBlankMatchKey is set, in which case they are not imported at all.

Proposal

Accept an ordered list of key sets, first non-blank one wins per row:

{ "writeMode": "upsert", "matchKeys": [["credit_code"], ["country", "registration_no"]] }

(or matchFields accepting string[][]). Ambiguity rules stay as today (AMBIGUOUS_MATCH if a key set hits more than one row).

Workaround in hotsrm (temporary)

Import the same sheet twice with skipBlankMatchKey: true: pass 1 matchFields: ['credit_code'], pass 2 matchFields: ['country', 'registration_no']. Each pass skips the other kind of row. Correct, but the operator has to run two imports and read two reports, and a domestic row with a blank credit code is only reported as BLANK_MATCH_KEY skipped, not as an error.

Linked: objectstack-ai/hotsrm#10


Re-filed as objectstack-fleet[bot] from #25476, same body and labels. #25476 was written off the fleet relay, under the maintainer's personal account, by a project-thread session through GitHub MCP; pm-dispatch allows content writes only through the relay. #25476's thread (triage, ruling, comments) stays there for reference; this card replaces it in the queue.
Session: session_018fnREjMeK9XQeHDwkJXKMW

Activity

  1. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01PC4NPXPgPmpDRG9DdDnyXT
    Account: sunhaolin (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-25577-import-applyon-matchkeys
    Worktree: objectstack-issue-25577
    Domain: domain:spec
    Seat: domain:spec#2 (seat post #18549)
    File surface: folded into the chain head #25577's PR (ruling 6377846440 on #25475: 「可与 #25476 同 PR」; #25476 is the card this re-files). This card's half: an ordered list of match key sets in packages/spec/src/api/export.zod.ts (first non-blank set wins per row; a row blank on every set is a row error, not a silent skip; AMBIGUOUS_MATCH unchanged) and the import runner in packages/rest/src/import-prepare.ts. The full surface, serial check and fold gates are on #25577's claim.
    Container & model: M, mode:cloud, model: default (TIER_DEFAULT), effort: high (the chain head's dispatch). Clause-②: yes ⇒ a CONTRACT_REVIEW_TIER contract review is owed before the queue.
    Clause-②: yes (widening)
    Metadata-protocol: added
    Responsibility: n/a — not a defect card
    Ruling-ref: 6377845536 (on #25476, batch #9 item 3b, letter A, maintainer 「#9 同意」)
    Thread-read: none
    Serial constraints cleared: see #25577's claim (no open PR on an import file; PR #25540 landed).


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Dispatched · round 1 · domain:spec seat 2 · 2026-10-24T12:13Z


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev report for this folded card is on #25577: #25577 (comment) (draft PR #25664; this card is its commit f21019e). Session: session_013Zj6EHJ5eped9wNcSM4jvh


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #25664 comment 6385545321 · domain:spec seat 2 · 2026-10-24T14:44Z · #25577 and #25578 land together (one fold, Fixes both). Waits for the CONTRACT_REVIEW_TIER review and green checks.

  5. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:spec seat 2 (seat post #18549) · sunhaolin · session session_01PC4NPXPgPmpDRG9DdDnyXT · 2026-10-24T17:19Z

    reading value
    PR #25664 (#25577 + #25578, folded) MERGED through the queue at 2026-10-24T17:17:52Z; merge commit b77bb37eb2. ACCEPT 6385545321; contract review PASS 6386765368 on head b89b3b242a (it judged the ['a', ['b']] 400 as owing no declaration: the protocol never accepted that shape)
    queue branch gh-readonly-queue/main/pr-25664-* gone (git ls-remote: 0 refs)
    origin/main carries b77bb37eb2; packages/spec/src/api/export.zod.ts holds isMatchKeySets (2 hits)

    State: both cards closed completed on the merge (one PR, a Fixes line each). pm:dispatched is removed from both in this stroke, and the dev's cloud session is archived. The two out-of-scope notes, ExportImportTemplateSchema.mappings (zero consumers) and the named mapping artifact's upsertKey, stay in the PR's Acceptance notes with no carrier.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchdomain:specenhancementNew feature or requestpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions