feat(messaging): synthesize inbox action_url from event source (ADR-0030 L5)#1456
Merged
Merged
Conversation
…030 L5)
The bell reads `sys_inbox_message` (the L5 materialization), which carries
only `action_url` — not the L2 event's `source_object`/`source_id`. Producers
that pass a `source` but no explicit `payload.url` (collaboration @mention,
record assignment) therefore materialized inbox rows with no navigable link,
so clicking the bell entry couldn't deep-link to the record.
Synthesize an app-relative `/{object}/{id}` link from `emit()`'s `source` when
no explicit `payload.url`/`payload.actionUrl` is given, in both the inline
fan-out and the durable-outbox enqueue paths. An explicit url still wins; with
neither url nor source the link stays undefined. This keeps the materialization
self-sufficient for navigation (the objectui bell consumes action_url).
Tests: 3 new cases (source→link, explicit-url precedence, neither→undefined);
all 95 service-messaging tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
xuyushun441-sys
added a commit
that referenced
this pull request
Jun 2, 2026
…min mechanism (ADR-0015 Addendum) (#1502) * chore: bump objectui to fdd083657e2d feat(studio): AI-draft review/diff mode in the object designer (v1) (#1456) objectui@fdd083657e2da9832059492d4c88e818a5990a8d * feat(service-datasource-admin): open-source the runtime datasource admin mechanism (ADR-0015 Addendum) Move the runtime UI-created datasource lifecycle (list/test/create/update/ remove) out of the private cloud repo into the open framework as @objectstack/service-datasource-admin, sitting next to its federation sibling @objectstack/service-external-datasource. This package is mechanism only: credential storage is delegated to a host-provided SecretBinder over any ICryptoProvider (framework default: InMemoryCryptoProvider), and drivers to a swappable factory. The tier line falls on which crypto provider / driver factory a host injects — a neutral technical seam — so a managed credential vault + multi-tenant overlay can be layered on by a private host without forking. Consistent with the connector / outbox / approval tiering principle: charge for credential custody + multi-tenant ops + scale, not for the ability to manage a datasource. - workspace:* deps, Apache-2.0, exports . and ./contracts - serve is NOT wired to mount this by default yet (OSS-edition identity TBD) - 29 tests pass; typecheck + build (incl. dts) clean Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
xuyushun441-sys
added a commit
that referenced
this pull request
Jun 2, 2026
* chore: bump objectui to fdd083657e2d feat(studio): AI-draft review/diff mode in the object designer (v1) (#1456) objectui@fdd083657e2da9832059492d4c88e818a5990a8d * fix(driver-sqlite-wasm): defer flush during transactions (#1494) Under `persist: 'on-write'` an authenticated insert could fail with `COMMIT; - cannot commit - no transaction is active`. Root cause: sql.js `Database.export()` closes and reopens the database (it has no in-place serialize). Closing a connection rolls back any open transaction, so the fire-and-forget `void flush()` triggered after a write inside a Knex transaction (e.g. the autonumber sequence `BEGIN…COMMIT`) aborted that transaction, leaving the trailing COMMIT to run with no active transaction. The failure is timing-dependent, which is why objects with extra in-transaction writes (autonumber + sharing-rule recompute, like crm_account) tripped it while a bare insert usually did not. Fix: make the connection transaction-aware. Track BEGIN/COMMIT/ROLLBACK/SAVEPOINT/RELEASE; `flush()` now defers while a transaction is open and runs once it fully closes. `close()` clears the state so the final flush still persists committed data. The dialect notifies the connection of every transaction-control statement before markDirty. Adds a regression test covering multi-statement transactions, on-write disk persistence, autonumber inserts, and nested savepoints. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: add changeset for #1494 fix Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(driver-sqlite-wasm): serialize flushes; single flush per txn close Follow-up to the #1494 fix. Two issues surfaced in CI / under load: - A COMMIT triggered two flushes (one from noteTransactionControl, one from the dialect's trailing markDirty('run')). Overlapping sql.js export() close/reopens raced and could persist 0 bytes. Route transaction-control statements through noteTransactionControl only, so the transaction lifecycle owns flushing and fires exactly once on close. - Replace the pendingFlush + recursive re-flush mechanism with a single strictly-serialized flush chain. export() mutates the live connection (close/reopen), so two exports must never overlap, and flush() must not resolve until the caller's own write has hit disk (deterministic for close()/tests). Key the post-commit flush off flushDeferred (not dirty) so on-disconnect mode still defers to close() instead of flushing on every COMMIT. Full driver suite green across repeated full-suite runs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
xuyushun441-sys
added a commit
that referenced
this pull request
Jun 2, 2026
#1503) * chore: bump objectui to fdd083657e2d feat(studio): AI-draft review/diff mode in the object designer (v1) (#1456) objectui@fdd083657e2da9832059492d4c88e818a5990a8d * fix(dev): unify dev admin seed in-process; remove port-drift HTTP seed `pnpm dev:showcase` often failed to provision a usable admin. The CLI seeded over HTTP against a hard-coded localhost:3000, but dev auto-shifts off a busy port — so the POST hit the wrong server (or nothing) and the showcase instance never got an admin. A second, divergent seed in plugin-dev inserted a raw sys_user row with no credential, producing an un-loginable ghost admin (admin@dev.local). Consolidate to a single in-process seed in the runtime: - plugin-auth: maybeSeedDevAdmin() runs on kernel:ready, creates the admin (admin@objectos.ai / admin123) through better-auth's real signUpEmail pipeline (hashed credential + hooks), so it is fully loginable; plugin-security's first-user middleware promotes it to platform admin. Empty-DB only (excludes the SystemUserId.SYSTEM account), idempotent, never overwrites an existing account. Hard-gated to NODE_ENV=development; opt out with OS_SEED_ADMIN=0. No port, no readiness race. - cli/dev: delete the HTTP seedAdminAccount entirely; --seed-admin now just passes OS_SEED_ADMIN[_EMAIL|_PASSWORD] to the serve child. Drop the dead `port` param from the watch loop. - cli/serve: publish the actually-bound port — process.send({type: 'objectstack:listening', port, url}) over IPC + a runtime.<env>.json state file under OS_HOME for external supervisors. - plugin-dev: remove the credential-less raw sys_user insert; seedAdminUser now maps to the unified OS_SEED_ADMIN toggle. Verified on the showcase: loginable admin + platform-admin promotion, correct seed under port auto-shift (3999 busy -> 4000), runtime.json written, --no-seed-admin opt-out, and idempotency on a persistent DB (no duplicate user / permission set). Tests: plugin-auth 88, plugin-dev 7, cli 144 — all green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: add changeset for dev seed-admin fix Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
xuyushun441-sys
pushed a commit
that referenced
this pull request
Jun 2, 2026
feat(studio): AI-draft review/diff mode in the object designer (v1) (#1456) objectui@fdd083657e2da9832059492d4c88e818a5990a8d
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The Console bell reads
sys_inbox_message(the ADR-0030 L5 in-app materialization), which carries onlyaction_url— not the L2sys_notificationevent'ssource_object/source_id. Producers that pass asourcebut no explicitpayload.url(collaboration@mention, record assignment) materialized inbox rows with no navigable link, so clicking the bell entry could not deep-link to the originating record.This synthesizes an app-relative
/{object}/{id}link fromemit()'ssourcewhen no explicitpayload.url/payload.actionUrlis supplied, in both the inline fan-out and the durable-outbox enqueue paths (actionUrlFor()helper). Precedence: explicit url → source-derived link →undefined.Keeps the L5 materialization self-sufficient for navigation, which the objectui bell cut-over consumes (companion objectui PR repoints the bell to
sys_inbox_message+sys_notification_receipt).Why
Part of the ADR-0030 objectui cut-over. The re-modeled
sys_notificationis now the L2 event (no recipient/read columns); the bell can no longer fall back tosource_object/source_idon the event, so the link must ride on the materialization.Tests
3 new
messaging-service.test.tscases — source→/obj/id, explicit-url precedence, neither→undefined. All 95@objectstack/service-messagingtests green.Verification
Verified live in the showcase Console (fresh sqlite, full pipeline): a materialized
sys_inbox_messagewith adeliveredreceipt lit the bell badge; the popover rendered the row; "mark all read" updated the existing receipt in place toread(no duplicate, unique index respected) and cleared the badge.🤖 Generated with Claude Code