✨ feat(device): add structured working_dirs column to devices#15356
Closed
arvinxx wants to merge 1 commit into
Closed
✨ feat(device): add structured working_dirs column to devices#15356arvinxx wants to merge 1 commit into
working_dirs column to devices#15356arvinxx wants to merge 1 commit into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
4 tasks
Introduce a `working_dirs` `jsonb` column on the `devices` table plus the
`WorkingDirEntry` type (`{ path, repoType?: 'git' | 'github' }`). Structured
entries let a remote client surface a device's working directories with their
detected repo type — a bare path string would lose that, and the client can't
re-probe a remote filesystem.
Additive migration only: `recent_cwds` is kept (now `@deprecated`) and no data
is converted, so this carries no destructive SQL. Consumers switch over in a
follow-up PR.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
8ee8dd8 to
0752b4e
Compare
working_dirs column to devices
arvinxx
added a commit
that referenced
this pull request
Jun 3, 2026
Add a nullable `workspace_id text` column to user-owned business tables (agents, sessions, topics, messages, files, tasks, RAG/eval, RBAC, devices, connectors, etc.) so records can later be scoped to a workspace. Workspace tables themselves already landed on canary via 0105_add_usage_agent_share_workspace. Also folds in the additive device schema from #15356: the structured `working_dirs` jsonb column + `WorkingDirEntry` type (recent_cwds kept, now @deprecated). Scope is deliberately column-only — the lowest-risk slice: - migration 0106 is pure `ADD COLUMN IF NOT EXISTS` (metadata-only, ~ms locks per table, online-safe, no app code change since columns are all NULL). - FKs, btree indexes, and the per-user→workspace-scoped unique-constraint conversions are intentionally deferred to follow-up PRs so each can use the production-safe execution path Drizzle can't express (NOT VALID + VALIDATE, CREATE INDEX CONCURRENTLY, atomic unique swap). Scoping notes: - devices / user_connectors / user_connector_tools: scoped (user-owned resources). - push_tokens: left user/device-level — an Expo token is one per app install and receives a person's notifications across all their workspaces. - agent_shares: no workspace_id — scoped transitively via agent_id → agents. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4 tasks
arvinxx
added a commit
that referenced
this pull request
Jun 4, 2026
* 🗃️ feat(database): add workspace_id columns to existing tables Add a nullable `workspace_id text` column to user-owned business tables (agents, sessions, topics, messages, files, tasks, RAG/eval, RBAC, devices, connectors, etc.) so records can later be scoped to a workspace. Workspace tables themselves already landed on canary via 0105_add_usage_agent_share_workspace. Also folds in the additive device schema from #15356: the structured `working_dirs` jsonb column + `WorkingDirEntry` type (recent_cwds kept, now @deprecated). Scope is deliberately column-only — the lowest-risk slice: - migration 0106 is pure `ADD COLUMN IF NOT EXISTS` (metadata-only, ~ms locks per table, online-safe, no app code change since columns are all NULL). - FKs, btree indexes, and the per-user→workspace-scoped unique-constraint conversions are intentionally deferred to follow-up PRs so each can use the production-safe execution path Drizzle can't express (NOT VALID + VALIDATE, CREATE INDEX CONCURRENTLY, atomic unique swap). Scoping notes: - devices / user_connectors / user_connector_tools: scoped (user-owned resources). - push_tokens: left user/device-level — an Expo token is one per app install and receives a person's notifications across all their workspaces. - agent_shares: no workspace_id — scoped transitively via agent_id → agents. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 🐛 fix(database): satisfy inferred row types after adding workspace_id Adding workspace_id made it a required key in the Drizzle-inferred row types ($inferSelect), breaking call sites that build those shapes by hand: - rbac.getUserRoles: include workspace_id in the explicit select projection - session action: add workspaceId to the constructed chat-group literal - test mocks (apiKey / generation / generationBatch / generationTopic): add workspaceId: null Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ✅ test(database): use toMatchObject for topic.create row assertions The two `expect(createdTopic).toEqual({ ...full literal })` snapshots broke on every new column (here: workspace_id). Switch them to toMatchObject so the returned row may carry extra columns without churning the expected literal. The dbTopic↔createdTopic strict comparisons are left as toEqual. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
💻 Change Type
🔗 Related Issue
🔀 Description of Change
DB layer for structured device working directories. Adds a
working_dirsjsonbcolumn to thedevicestable and theWorkingDirEntrytype ({ path, repoType?: 'git' | 'github' }).A remote client viewing a device can't re-probe that device's filesystem, so the detected repo type must be captured at the source — a bare path string loses it.
Additive migration (
0105_device_add_working_dirs):ALTER TABLE "devices" ADD COLUMN IF NOT EXISTS "working_dirs" jsonb DEFAULT '[]'::jsonb. The column is nullable (defaults to[]). The legacyrecent_cwdscolumn is kept (now@deprecated) and no data is converted — no destructive SQL. A later cleanup can droprecent_cwdsonce nothing reads it.This is the lower layer of a stacked pair — it merges first. The consumers (model / tRPC / UI) follow in #15353.
🧪 How to Test
Existing device model tests pass unchanged against the additive migration (backward compatible):
📝 Additional Information
working_dirsis nullable with a[]default. The tRPClistDevicesreader coalescesnull → [](in ✨ feat(device): switch device cwd handling to structured workingDirs #15353) so the API contract stays an always-array.0105follows0104oncanary; if another0105lands first, the file +_journal.jsontag will need a rebase bump (per the db-migrations skill).