Skip to content

fix(automation): record-change flows see multi-lookup fields + array-index interpolation (#1872) - #1915

Merged
os-zhuang merged 1 commit into
mainfrom
fix/1872-multilookup-hydration
Jun 15, 2026
Merged

fix(automation): record-change flows see multi-lookup fields + array-index interpolation (#1872)#1915
os-zhuang merged 1 commit into
mainfrom
fix/1872-multilookup-hydration

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Closes#1872.

Problem (confirmed via full-kernel repro)

A multiple: true lookup is stored as an array column (not a junction table — objectql has no junction logic; the expand path at engine.ts already treats the value as Array.isArray). A data driver may not echo that column back on create, so it was absent from the after-create record the record-change flow sees:

  • record.target_channels != null evaluated false → the flow never ran;
  • {piece.target_channels.0} interpolation resolved empty.

Root cause (two distinct gaps, both confirmed by instrumented repro)

  1. The record-change trigger's buildContext read ctx.input.**doc**, but objectql lifecycle hooks carry the written row under ctx.input.**data** (insert/update). So the input fallback was always undefined — the flow only ever saw the driver's (incomplete) after-row.
  2. Interpolation's path regex required identifier segments, so a numeric .0 segment ({rec.channels.0}) never matched the fast path.

Fix

  • @objectstack/trigger-record-changebuildContext reads input.data and overlays the after-row on it ({ ...inputData, ...after }): the after-row wins for every field the driver returns (id, DB-computed), and fields it omits (multi-lookup arrays) come from the input. Affects only record-change flows.
  • @objectstack/service-automation{var.path.N} numeric segments now index into arrays (template.ts), so {record.channels.0} resolves.

Tests

  • Full-kernel repro: a driver that deliberately doesn't echo the array column → a record-after-create flow gated on record.target_channels != null fires AND its update_record stamps {record.target_channels.0} (= ch_1). Fails on each gap before the fix; passes after.
  • Array-index interpolation unit tests (single / embedded / out-of-range).
  • @objectstack/service-automation199 pass, @objectstack/trigger-record-change20 pass (incl. the Record-change trigger plugin loads but flows never fire on data writes (7.4.1) #1491 integration test — confirms the input.data change doesn't regress the record path).

🤖 Generated with Claude Code

…index interpolation (#1872)
A `multiple: true` lookup is an array column a driver may not echo back on
create, so it was absent from the after-create record a record-change flow saw:
`record.target_channels != null` was false and `{rec.target_channels.0}`
resolved empty. (Multi-lookup is an array column, not a junction table.)
Two parts:
- trigger-record-change buildContext: read the hook's `input.data` (objectql's
actual insert/update payload key — it had been reading a non-existent
`input.doc`, so the input fallback never worked) and overlay the after-row on
it, so fields the driver didn't return stay visible to the flow's start
condition and `{record.<field>}` interpolation.
- service-automation template: `{var.path.N}` numeric segments index into arrays
(`{record.channels.0}`).
Tests: full-kernel repro (driver that doesn't echo the array column → flow fires
on the multi-lookup condition AND stamps `{record.target_channels.0}`) +
array-index interpolation unit tests. service-automation 199, trigger 20 pass
(incl. the #1491 integration test, confirming the input.data change is safe).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercelBot commented Jun 15, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJun 15, 2026 2:33pm

Request Review

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling size/m labels Jun 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): packages/services, packages/triggers.

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

  • content/docs/guides/packages.mdx(via packages/services)
  • content/docs/guides/runtime-services/audit-service.mdx(via packages/services)
  • content/docs/guides/runtime-services/index.mdx(via packages/services)
  • content/docs/guides/runtime-services/settings-service.mdx(via packages/services)
  • content/docs/protocol/objectos/i18n-standard.mdx(via packages/services)

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.

@os-zhuang
os-zhuang merged commit b0df09c into mainJun 15, 2026
14 checks passed
@os-zhuang
os-zhuang deleted the fix/1872-multilookup-hydration branch June 15, 2026 14:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P2] record-change context does not hydrate multi-lookup (junction) fields

1 participant

@os-zhuang