Skip to content
This repository was archived by the owner on Oct 26, 2026. It is now read-only.

Commit cb80001

Browse files
fix(plugin-grid): the Import Wizard stops offering the two control opt-outs the import doors refuse (objectui#12985) (#12989)
Fixes #12985 Clause-②: no The Import Wizard no longer offers "Run automations & triggers" or "Import as historical data". Both import doors (`POST /api/v1/data/:object/import` and `/import/jobs`) honour `runAutomations: false` and `treatAsHistorical: true` for the system principal only and refuse every other caller `403 PERMISSION_DENIED` (objectstack-ai/objectstack#24348, PR objectstack-ai/objectstack#24379, measured there by `import-control-opt-out-gate.test.ts`). A browser request is never the system principal, so a user who unticked the first box or ticked the second had the whole import refused. ## What changed - `packages/plugin-grid/src/ImportWizard.tsx`: the two checkboxes, their `useState` pairs, their props on `ImportOptions`, their entries in the dependency lists and the reset, and the two fields `assembleImportRequest` set are removed. The wizard's import, dry-run and background-job requests (all three go through `assembleImportRequest`) carry neither key. Omitting both is the server's declared default (`readImportControlFlags`: `runAutomations` is on unless the body sends `false`; `treatAsHistorical` is on only for a literal `true`), so the default import is unchanged: automations run and the state machine is walked. No capability or entitlement is added. - `packages/i18n/src/locales/*.ts` (all ten packs) and the wizard's English fallback map `IMPORT_DEFAULT_TRANSLATIONS`: the three keys only those options read, `grid.import.optRunAutomations`, `grid.import.optTreatHistorical`, `grid.import.optTreatHistoricalHint`, are retired. A repo-wide `git grep` for the two leaf names is empty after the change (control: `optCreateOptions` still hits every pack). - Two comments (`en.ts` and `makerEmptyState-v1-scope-8329.test.ts`) listed `dataImport.optRunAutomations` as a live manual automation surface. That key is retired here, so the name is dropped from both lists. - `.changeset/12985-import-optouts.md`: `@object-ui/plugin-grid` and `@object-ui/i18n`, patch. **Contract note for the seat (Clause-② no, narrowing):** `ImportWizardProps` and `ImportResult` are unchanged. The locale objects exported under `@object-ui/i18n/locales/*` lose three members of `grid.import`. The internal `__testables.assembleImportRequest` options type loses `runAutomations` and `treatAsHistorical`. `ImportRequestOptions` in `@object-ui/types` still declares both fields, because the server still accepts them from the system principal. ## Pins New file `packages/plugin-grid/src/ImportWizard.controlOptOuts-12985.test.tsx`, over the real wizard: - (a) "draws neither the run-automations nor the treat-as-historical option": in the preview step neither `import-opt-run-automations` nor `import-opt-treat-historical` is drawn, and no text matches automations or historical. CONTROL: the `import-options` panel and `import-opt-create-options` are drawn. - (b) + (c) "a completed default import sends neither opt-out and still imports": the request handed to `importRecords` has neither property, and equals the default import's request exactly (`format`, `rows`, `writeMode: insert`, `createMissingOptions: false`, `skipBlankMatchKey: false`) as the CONTROL that nothing else moved; `onComplete` receives 2 of 2 rows imported. `importDryRun.test.ts` and `importSavedMapping.test.ts` drop the two option inputs and the assertions that the fields were sent. **Ablation (once):** with the fix committed, `ablation-replace.mjs` put a `data-testid="import-opt-run-automations"` checkbox labelled "Run automations & triggers" back into `ImportOptions` (anchor 1 to 0, blob `3cdd0e998baf` to `37f2a414044c`), and pin (a) went red: `Tests 1 failed | 1 passed (2)`, failing on `queryByTestId('import-opt-run-automations')`. Restore: blob after restore `3cdd0e998baf` equals the HEAD blob and `git diff HEAD` is empty. A first attempt was a no-op: its replacement contained its own anchor, so the tool refused it (anchor count 1 to 1) and the test never ran. It was re-run with a new anchor, and that second run is the one quoted here. ## Verification (at `ac0198b332`) All of it ran on the committed tree at `ac0198b332`. - Closure build `turbo run build --filter=@object-ui/plugin-grid^...` (13 tasks): exit 0. - `type-check` for `@object-ui/plugin-grid` and `@object-ui/i18n` (`tsc --noEmit && tsc -p tsconfig.test.json`): exit 0. `--listFiles` confirms the new and edited test files are in the test program. - vitest `--maxWorkers=1`: the new and edited files plus the parity test, 4 files and 20 tests, passed. Every test file that names `ImportWizard`, `runAutomations` or `treatAsHistorical`, in plugin-grid (21 files, 148 tests) and elsewhere, plus the i18n parity and retired-key suites (20 files, 301 tests), passed. - Declared to CI: the full `packages/plugin-grid/` and `packages/i18n/` directories. - The pre-tsc battery, all exit 0: `check:phantom-deps`, `check:self-import`, `check:unreferenced-sources`, `check:doc-example-readers`, `check:handler-key-reads`, `check:side-effects-array`, `check:element-data-source-declaration`, `check:spec-symbols`, `check:action-forward-parity`, `check:designer-field-key-parity`, `check:icon-record-names`, `check:i18n-keys`, `check:i18n-dead-keys`, `check:i18n-drift`, `check:i18n-designer-parity` and `check:control-bytes`. Also exit 0: `node scripts/check-hand-rolled-comment-mask.mjs`, `node scripts/check-changeset-fixed.mjs`, `node scripts/check-changeset-presence.mjs` and `check:new-line-citations` (0 new). - Narrowed lint, run as `eslint --no-inline-config` over the 15 changed `.ts` / `.tsx` files: - Population: `eslint.config.js` scopes `**/*.{ts,tsx}`. The JSON output counts 15 files linted, 0 errors and 9 warnings. - The 9 warnings are all in `ImportWizard.tsx`. The same 9 rules fire on the base blob of that file, so the change adds none. - Invariance: the config sets no `parserOptions.project`, so linting is not type-aware and this diff cannot move a verdict on an untouched file. ## Acceptance notes - **Another caller of the fields:** no other objectui caller sends `runAutomations` or `treatAsHistorical`. `git grep` hits only this file, its tests and the type `ImportRequestOptions` in `packages/types/src/data.ts`, which is outside this file surface and still correct as a wire type. `data-objectstack` forwards the request object and names neither field. - **Doc drift, not filed (carrier: none):** the JSDoc on `ImportRequestOptions.runAutomations` in `packages/types/src/data.ts` reads "off by default for bulk". The spec and server default is on (`ImportRequestSchema`, `runAutomations` declared default). No producer reads it. Session: `https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB` --- _Generated by [Claude Code](https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 736b9ce commit cb80001

16 files changed

Lines changed: 136 additions & 101 deletions

‎.changeset/12985-import-optouts.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'@object-ui/plugin-grid': patch
3+
'@object-ui/i18n': patch
4+
---
5+
6+
The Import Wizard no longer offers "Run automations & triggers" or "Import as historical data" (objectui#12985). Both import doors (`POST /api/v1/data/:object/import` and `/import/jobs`) honour `runAutomations: false` and `treatAsHistorical: true` for the system principal only and refuse every signed-in caller `403 PERMISSION_DENIED` (objectstack-ai/objectstack#24348). A user who unticked the first box or ticked the second had the whole import refused.
7+
8+
- **The two options are gone** from the wizard's options panel, with their state. The wizard's import, dry-run and background-job requests carry neither `runAutomations` nor `treatAsHistorical`. Leaving both keys out is the server's declared default, so the default import is unchanged: automations run and the state machine is walked.
9+
- **Language packs.** The three keys only those options read, `grid.import.optRunAutomations`, `grid.import.optTreatHistorical` and `grid.import.optTreatHistoricalHint`, are removed from all ten packs and from the wizard's English fallback map. The locale objects exported under `@object-ui/i18n/locales/*` lose those three members.
10+
11+
Nothing else on either package entry changes: `ImportWizardProps` and `ImportResult` are unchanged, and `ImportRequestOptions` in `@object-ui/types` still declares both fields, because the server still accepts them from the system principal.

‎packages/i18n/src/__tests__/makerEmptyState-v1-scope-8329.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
* "automation". The platform's manual automation surfaces are real and are
4646
* deliberately NOT covered: `home.build.subtitle` (its card opens Studio, which
4747
* genuinely authors flows), `engine.studio.landing.description`,
48-
* `dataImport.optRunAutomations`, `packagedAutomation.*`, the marketplace
48+
* `packagedAutomation.*`, the marketplace
4949
* `automation` category, and the approvals / flow-runner groups.
5050
*
5151
* REVERT the wording (and relax this suite) when ADR-0112 v2 re-adds flows and

‎packages/i18n/src/locales/ar.ts‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -667,9 +667,6 @@ const ar = {
667667
needMatchFields: "اختر حقلًا واحدًا على الأقل للمطابقة.",
668668
matchOnlyField: "(للمطابقة فقط)",
669669
optCreateOptions: "الاحتفاظ بقيم الخيارات غير المعروفة",
670-
optRunAutomations: "تشغيل الأتمتة والمشغّلات",
671-
optTreatHistorical: "الاستيراد كبيانات تاريخية",
672-
optTreatHistoricalHint: "(استيراد السجلات المكتملة كما هي — تخطي فحوصات آلة الحالات والاحتفاظ بالطوابع الزمنية والمؤلف الأصليين بدل ختمها الآن)",
673670
optSkipBlankKey: "تخطي الصفوف التي تكون قيمة المطابقة فيها فارغة",
674671
optBackground: "الاستيراد في الخلفية",
675672
optBackgroundHint: "(يعمل كمهمة قابلة للتراجع)",

‎packages/i18n/src/locales/de.ts‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -583,9 +583,6 @@ const de = {
583583
needMatchFields: "Wählen Sie mindestens ein Feld für den Abgleich aus.",
584584
matchOnlyField: "(nur Abgleich)",
585585
optCreateOptions: "Unbekannte Optionswerte beibehalten",
586-
optRunAutomations: "Automatisierungen und Trigger ausführen",
587-
optTreatHistorical: "Als historische Daten importieren",
588-
optTreatHistoricalHint: "(abgeschlossene Datensätze unverändert importieren — Zustandsautomat-Prüfungen überspringen und die ursprünglichen Zeitstempel und Autoren beibehalten, statt jetzt zu stempeln)",
589586
optSkipBlankKey: "Zeilen mit leerem Abgleichswert überspringen",
590587
optBackground: "Im Hintergrund importieren",
591588
optBackgroundHint: "(läuft als rückgängig machbarer Auftrag)",

‎packages/i18n/src/locales/en.ts‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -864,9 +864,6 @@ const en = {
864864
needMatchFields: 'Select at least one field to match on.',
865865
matchOnlyField: '(match only)',
866866
optCreateOptions: 'Keep unknown option values',
867-
optRunAutomations: 'Run automations & triggers',
868-
optTreatHistorical: 'Import as historical data',
869-
optTreatHistoricalHint: '(import completed records as-is — skip state-machine checks and keep their original timestamps & author instead of stamping now)',
870867
optSkipBlankKey: 'Skip rows with a blank match value',
871868
optBackground: 'Import in the background',
872869
optBackgroundHint: '(runs as an undoable job)',
@@ -2365,7 +2362,7 @@ const en = {
23652362
// NOT the same thing as the platform's manual automation surfaces, which
23662363
// are real and stay as they are: `home.build.subtitle` (that card opens
23672364
// Studio, which does author flows), `engine.studio.landing.description`,
2368-
// `dataImport.optRunAutomations`, `packagedAutomation.*` and the
2365+
// `packagedAutomation.*` and the
23692366
// marketplace `automation` category. The boundary is v1 AI AUTHORING, not
23702367
// the word "automation".
23712368
//

‎packages/i18n/src/locales/es.ts‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -605,9 +605,6 @@ const es = {
605605
needMatchFields: "Seleccione al menos un campo por el que coincidir.",
606606
matchOnlyField: "(solo coincidencia)",
607607
optCreateOptions: "Conservar los valores de opción desconocidos",
608-
optRunAutomations: "Ejecutar automatizaciones y disparadores",
609-
optTreatHistorical: "Importar como datos históricos",
610-
optTreatHistoricalHint: "(importa los registros completados tal cual: omite las comprobaciones de la máquina de estados y conserva sus marcas de tiempo y autor originales en lugar de sellarlos ahora)",
611608
optSkipBlankKey: "Omitir las filas con valor de coincidencia vacío",
612609
optBackground: "Importar en segundo plano",
613610
optBackgroundHint: "(se ejecuta como un trabajo reversible)",

‎packages/i18n/src/locales/fr.ts‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -601,9 +601,6 @@ const fr = {
601601
needMatchFields: "Sélectionnez au moins un champ de correspondance.",
602602
matchOnlyField: "(correspondance seule)",
603603
optCreateOptions: "Conserver les valeurs d'option inconnues",
604-
optRunAutomations: "Exécuter les automatisations et déclencheurs",
605-
optTreatHistorical: "Importer comme données historiques",
606-
optTreatHistoricalHint: "(importer les enregistrements terminés tels quels — ignorer les contrôles de la machine à états et conserver leurs horodatages et auteurs d'origine au lieu d'horodater maintenant)",
607604
optSkipBlankKey: "Ignorer les lignes dont la valeur de correspondance est vide",
608605
optBackground: "Importer en arrière-plan",
609606
optBackgroundHint: "(s'exécute comme une tâche annulable)",

‎packages/i18n/src/locales/ja.ts‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -583,9 +583,6 @@ const ja = {
583583
needMatchFields: "照合する項目を 1 つ以上選択してください。",
584584
matchOnlyField: "(照合のみ)",
585585
optCreateOptions: "未知の選択肢の値を保持する",
586-
optRunAutomations: "自動化とトリガーを実行する",
587-
optTreatHistorical: "過去データとしてインポートする",
588-
optTreatHistoricalHint: "(完了済みレコードをそのまま取り込みます — ステートマシンの検査を省略し、現在時刻を打刻せずに元のタイムスタンプと作成者を保持します)",
589586
optSkipBlankKey: "照合値が空の行をスキップする",
590587
optBackground: "バックグラウンドでインポートする",
591588
optBackgroundHint: "(取り消し可能なジョブとして実行されます)",

‎packages/i18n/src/locales/ko.ts‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -583,9 +583,6 @@ const ko = {
583583
needMatchFields: "일치 기준 필드를 하나 이상 선택하세요.",
584584
matchOnlyField: "(일치 전용)",
585585
optCreateOptions: "알 수 없는 선택 값 유지",
586-
optRunAutomations: "자동화 및 트리거 실행",
587-
optTreatHistorical: "과거 데이터로 가져오기",
588-
optTreatHistoricalHint: "(완료된 레코드를 그대로 가져옵니다 — 상태 머신 검사를 건너뛰고 현재 시각을 찍는 대신 원래 타임스탬프와 작성자를 유지합니다)",
589586
optSkipBlankKey: "일치 값이 비어 있는 행 건너뛰기",
590587
optBackground: "백그라운드에서 가져오기",
591588
optBackgroundHint: "(되돌릴 수 있는 작업으로 실행됩니다)",

‎packages/i18n/src/locales/pt.ts‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -600,9 +600,6 @@ const pt = {
600600
needMatchFields: "Selecione pelo menos um campo de correspondência.",
601601
matchOnlyField: "(somente correspondência)",
602602
optCreateOptions: "Manter valores de opção desconhecidos",
603-
optRunAutomations: "Executar automações e gatilhos",
604-
optTreatHistorical: "Importar como dados históricos",
605-
optTreatHistoricalHint: "(importa registros concluídos como estão — ignora as verificações da máquina de estados e mantém os carimbos de data/hora e o autor originais em vez de carimbar agora)",
606603
optSkipBlankKey: "Ignorar linhas com valor de correspondência em branco",
607604
optBackground: "Importar em segundo plano",
608605
optBackgroundHint: "(executa como um trabalho reversível)",

0 commit comments

Comments
 (0)