fix(server): device-reconcile adopts orphan connections + web bump#714
Conversation
…bmodule
When a device-connector row's created_by didn't match the polling user
(e.g. created_by IS NULL on rows inserted by older reconcile versions,
or a `lobu apply` call whose token had no user identity), the auto-wire
fast-path JOIN filtered it out, the slow-path reuse-check did the same,
and the fall-through INSERT collided with the orphan's slug — the txn
aborted and the pin never got applied. Every subsequent poll repeated
the same dance, so the UI stayed permanently broken for that org.
Drop the `c.created_by = ${userId}` predicate from both the fast-path
JOIN and the slow-path reuse-check. The device-connector identity is
(org_id, connector_key, auth_profile_id IS NULL, deleted_at IS NULL) —
exactly one such row per org, no ambiguity to disambiguate by owner.
When adopting an orphan, also backfill `created_by` so per-user
queries (e.g. /api/me/devices) start attributing the connection
correctly.
Also bumps the web submodule to pick up the inline-page border cleanup
+ /$owner -> /events redirect (lobu-ai/owletto#105).
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughDevice-connector reconciliation now identifies no-auth connections by ChangesDevice Connection Reconciliation
Web Submodule Update
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 69118ff9c9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| LEFT JOIN connections c | ||
| ON c.organization_id = cd.organization_id | ||
| AND c.connector_key = cd.key | ||
| AND c.created_by = ${userId} | ||
| AND c.auth_profile_id IS NULL | ||
| AND c.deleted_at IS NULL |
There was a problem hiding this comment.
Preserve device owner when adopting no-auth connections
In a shared workspace where two users have devices advertising the same device connector, this join now matches any live no-auth connection for the org/connector, including one already pinned to another user's device. The fast path then calls reconcilePin on that row, and because the other device id is not in the current user's matchingDeviceIds, it can rewrite connections.device_worker_id to the polling user's device; subsequent polls from the original user can flip it back, stranding or misattributing runs/feeds. Scope adoption to true orphan/unpinned rows or keep the current user's ownership/device constraint.
Useful? React with 👍 / 👎.
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Summary
reconcileDeviceCapabilities(worker poll auto-wire) couldn't repair a device-connector row whosecreated_bydidn't match the polling user. Both the fast-path JOIN and the slow-path reuse-check filtered byc.created_by = \${userId}, so an orphan row (e.g.created_by IS NULLfrom older reconcile code, or rows inserted bylobu applywith a no-user token) was invisible. The fall-through INSERT then collided with the orphan's slug, aborted the txn, and the pin never landed. Result: the row sat unpinned forever and the UI hid it (sidebar device-grouping requiresdevice_worker_id).created_bypredicate from both lookups — match on(org, connector_key, auth_profile_id IS NULL, deleted_at IS NULL)instead. There's at most one such row per org, so no ambiguity.created_by IS NULL, backfill it under the lock so/api/me/devicesand friends start attributing it correctly./$owner→/eventsredirect.Hit this against buremba's
whatsapp.local(connection id 361,created_bywas NULL, never got a pin). Backfilled prod with the explicit pin + owner so the row is usable immediately; the code fix prevents new orphans from getting stranded the same way.Test plan
whatsapp.localconnection in a new org (no orphan in the DB) — unchanged behaviour.whatsapp.localrow whosecreated_byis NULL or a different user — the row is adopted,device_worker_idset,created_bybackfilled.make build-packages+bun run typecheckclean./$ownerredirect) load via the bumped submodule.Summary by CodeRabbit
Bug Fixes
Chores