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-automation 199 pass, @objectstack/trigger-record-change 20 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

vercel Bot commented Jun 15, 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 Jun 15, 2026 2:33pm

Request Review

@github-actions github-actions Bot 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 main Jun 15, 2026
14 checks passed
@os-zhuang
os-zhuang deleted the fix/1872-multilookup-hydration branch June 15, 2026 14:35
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/m tests tooling

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