feat(rest): GET /data/:object/export?template=true answers an xlsx import template (#18386) - #20683
Conversation
Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1 Co-authored-by: Claude <noreply@anthropic.com>
… template (wip) Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1 Co-authored-by: Claude <noreply@anthropic.com>
…, and the export's pre-change bytes Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1 Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 3 package(s): 48 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 8 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. What this run could not see
Coarse fallback — 142 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 5f7afd68e0402774df33057c541869ded46f8ddd && git checkout 5f7afd68e0402774df33057c541869ded46f8ddd
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 810d42b69cc5f581a6f3d089e02d8c5fce2ece37 2d488c89ee76d11cbbd2f22508fb1cb9c6badcfd && git checkout -B drift-repro 810d42b69cc5f581a6f3d089e02d8c5fce2ece37 && git merge --no-ff 2d488c89ee76d11cbbd2f22508fb1cb9c6badcfd
node scripts/docs-audit/affected-docs.mjs --json 810d42b69cc5f581a6f3d089e02d8c5fce2ece37
|
…port-import-template
…mplate narrows by it (wip) ISecurityService gains the optional write-side twin of getReadableFields; plugin-security answers it from the derivation its read projection and its step 2.5 write gate share. The template asks it first, falls back to the read projection when the service lacks it and states that in the response (X-Export-Template-Projection and an instructions-sheet note), and no longer excludes a writable hidden field. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1
… id, as the read one does Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1
…lver both projections now share Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1
…urity only, and the template's formula row names its driver Text only. The contract, both new changesets and the plugin method say the answer is field-level security alone and a field's own rules are not in it. The template docblock names the driver its import-door table was measured on and says the formula refusal is the SQL driver's. The stale Object.assign comment loses its claim that getMetadataReadableFields has no contract seat. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1
Contract reviewServed-tier: Inputs read: card #18386 (body as corrected under the Ruled line, all 14 comments: rulings ① Derived judgmentsAccept-set and public-surface changes the diff implies, each judged:
Text the diff adds or changes, tested sentence by sentence; the ones that are false, unsourced or over-broad:
② Semver level
③ Boundary flagsDev report 1 (
Dev report 2 (
Dev report 3 ( Cross-lane note Triage note Concurrency: PR #20794 edits ESCALATED, no behaviour at stake: Acceptance 6 (dropdowns in Excel, WPS, Numbers, Google Sheets) is a hand check and stays open on the card by design; the PR is Check-runs on Implemented-by: VERDICT: PASS Adopted and posted by
Generated by Claude Code |
… longer the import template Text only. The rest changeset keeps the byte-for-byte claim for the request with no template parameter; template=false was refused on main, so it only says what it answers now. The export route's comment points at template=true instead of calling an empty export an import template. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1
|
ACCEPT (delta) — PR #20683 at head This note extends the at-tier PASS
Generated by Claude Code |
Contract reviewServed-tier: Director seat (objectstack#12708, summon #30 续 2), on the standing ask 「契约复审」 and the audit rule that a record names one head. The ① Derived judgmentsEvery judgment of 5908288272 stands: no source line outside one comment moved, so the accept-set widening it judged (the The delta, sentence by sentence:
② Semver levelUnchanged: ③ Boundary flags
Check-runs on the head, read 2026-09-30T10:43Z — none Implemented-by: VERDICT: PASS |
Part of #18386. Acceptance 6 (dropdowns in Excel, WPS, Numbers and Google Sheets) needs a person to open the file, so the card stays open for that check after this lands. The objectui half is objectstack-ai/objectui#9600.
Clause-②: yes (widening)
GET /api/v1/data/:object/export?template=trueanswers an xlsx import template with no data rows. Its columns leave outsystem,readonly,formula,summaryandautonumberfields, a writablehiddenfield is kept, and field-level security narrows the rest to what the caller may edit. Required columns with no default carry*, select, radio and boolean columns get dropdowns, and an instructions sheet states the spellings the import reader accepts. With notemplateparameter the export is unchanged, byte for byte.ISecurityServicegains an optionalgetWritableFields, whichplugin-securityimplements from the write gate's own field mask. A security service without it gets the read projection instead, and the response says so in theX-Export-Template-Projectionheader and on the instructions sheet.🤖 Generated with Claude Code
https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1