Conversation
* Allow duplicate v2 repo clone URLs * Add migration to drop v2 repo clone URL unique index * regen migrations * Add projects settings action for duplicate imports
* Stabilize v1 to v2 migration * Update migration modal dither color * Remove electric proxy changes from migration PR * Rate limit migration support reports * Address migration review feedback * Remove migration cloud rollback * Address migration review feedback * Log project local persistence failures * Preserve clone for project relink recovery
…uperset-sh#3632) * feat(desktop): auto-create + pin v2 main workspace on host project setup Each (projectId, hostId) gets a singleton "main" workspace pointing at the host's configured repoPath, auto-created when a project is created or set up on a new host. Mains are auto-pinned at creation; existing mains get backfilled by the startup sweep. - Schema: v2_workspaces.type pgEnum ('main' | 'worktree', default 'worktree') enforced at the DB layer — matches the v2ClientType / v2UsersHostRole naming precedent. Partial unique index on (project_id, host_id) WHERE type='main', plus a pinned_at timestamp. - API: v2Workspace.create uses onConflictDoNothing + re-fetch so concurrent main creates collapse idempotently instead of racing into a raw unique-violation error. Backfills pinned_at on existing main rows. - Helper: ensureMainWorkspace resolves current branch via git symbolic-ref, creates the cloud + local workspace rows. Log-and-continue on any error so transient cloud blips don't fail project.setup; the startup sweep retries on next boot. Skips on detached HEAD. - Call sites: project.create (createFromClone, createFromImportLocal) and project.setup (clone, import, including early-return paths). - Recovery: host-service startup sweep iterates local projects and ensures each has a main row. Idempotent via the unique index. * fix main workspace sidebar behavior * fix preview migration rerun * fix(host-service): recover missing main workspace during worktree flows * fix(desktop): protect main workspace delete flows * fix(desktop): tighten main workspace lifecycle * fix(db): regenerate v2 main workspace migration * fix(host-service): reuse host workspace lookup
…3784) * feat(db): consolidate host/client identity on machineId Drop UUID surrogates on v2_hosts/v2_clients/v2_users_hosts in favor of composite primary keys keyed on the existing machineId. Same value the host service already uses to identify itself (getHostId, formerly getHashedDeviceId), now canonical end-to-end across DB, cloud API, relay, and renderer. Drops the dead session_hosts table. Renames the device-info shared lib + cloud trpc device router to host (v1 device.heartbeat / device.registerDevice retained against the untouched device_presence table). Bumps host-service version to 0.3.0 so the desktop coordinator force-respawns older binaries that still call device.ensureV2Host. * fix: scope relay routing key by organizationId machineId alone collides on the relay tunnel map when the same physical machine is registered as a host in multiple orgs. Switch the relay routing key to "${organizationId}:${machineId}" everywhere the desktop, host service, and cloud trpc construct it. Code-splits buildHostRoutingKey / parseHostRoutingKey out of host-info into a browser-safe @superset/shared/host-routing entry so the renderer no longer transitively imports node:child_process via host-info. Adds a useHostTargetUrl hook that wraps the (active host vs relay) URL resolution with the active organization's id, replacing the inline ${env.RELAY_URL}/hosts/${hostId} pattern at every renderer call site. * fix(db,trpc): address pr review feedback - host.ensure: gate v2_users_hosts owner-grant on host.createdByUserId === ctx.userId. Prevents an org member who knows another member's machineId (it's in the synced collection) from calling host.ensure and being granted owner role on someone else's host. - Drop composite FKs on automations.target_host_id and automation_runs.host_id (migration 0038). These nullable refs originally used ON DELETE SET NULL with a single-column FK; the consolidation made them composite, which breaks SET NULL semantics (PG would try to NULL the NOT NULL organization_id too). Both columns are best-effort pointers — dispatcher already handles the host-not-found path — so dropping the FK is the cleaner fix than the PG15+ column-list workaround. v2_users_hosts (CASCADE) and v2_workspaces (NOT NULL, deletion-blocks) keep their composite FKs intentionally. * fix(db): scope migration null-out by (organization_id, machine_id) Pre-PR FK on automation_runs.host_id and automations.target_host_id was single-column uuid → v2_hosts.id; it didn't enforce that the row's organization_id matched the host's. If any cross-org row existed (past bug, manual SQL, etc.), the uuid→machineId translation step would write the wrong-org's machine_id, and the new composite FK on (organization_id, host_id) would reject it. Switch the null-out predicate from `host_id NOT IN (SELECT machine_id …)` to `NOT EXISTS (… WHERE machine_id = X AND organization_id = X)` so the migration self-defends instead of trusting the cross-org invariant. Identical behavior on data that satisfies the invariant (prod confirmed zero orphans), defensive against environments that don't.
PR-B 取り込み中、3efd92763 (Stabilize v1→v2 migration) と 9abd936 (machineId consolidation) の auto-merge で復活してしまった fork で削除済みの ExperimentalSettings 関連を再削除する。 - apps/desktop/src/renderer/routes/_authenticated/settings/experimental/ ディレクトリ削除 (route 未登録 + V2LocalOverrideState の setForceV1 が既に存在しないため build fail していた) - settings-search.ts から EXPERIMENTAL_SUPERSET_V2 / EXPERIMENTAL_V1_MIGRATION 関連 ID と SETTINGS_ITEMS エントリを削除 - V1MigrationSummaryModal の "/settings/experimental" リンクを削除 (fork は V1 へ戻るオプトアウト UI を持たない) 加えて 3efd927 + 9abd936 を同時取り込みすると v2Workspace.updateNameFromHost の戻り値型 (4列 Pick) が host-service adopt.ts の HostWorkspace 期待型と噛み合わなくなるため、 findFirst の columns 限定を外して全列を返すように直す (getFromHost と同形)。
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🧹 Preview Cleanup CompleteThe following preview resources have been cleaned up:
Thank you for your contribution! 🎉 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a7300ec1f9
ℹ️ 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".
| if (local && project && local.worktreePath === project.repoPath) { | ||
| throw new TRPCError({ | ||
| code: "BAD_REQUEST", | ||
| message: | ||
| "Main workspaces cannot be deleted. Remove them from the sidebar or remove the project from this host instead.", |
There was a problem hiding this comment.
Gate main-workspace delete by cloud type, not repoPath
migrateV1DataToV2 still adopts legacy workspace.type === "branch" entries from mainRepoPath, so a non-main workspace can legitimately have worktreePath === project.repoPath. This new precheck classifies those rows as main purely by path and throws before checking cloud v2Workspace.type, which makes migrated repo-root branch workspaces undeletable via workspaceCleanup.destroy.
Useful? React with 👍 / 👎.
| if (ws.worktreePath === localProject.repoPath) { | ||
| await ctx.api.v2Workspace.deleteMainForHost.mutate({ | ||
| id: ws.id, | ||
| projectId: input.projectId, | ||
| }); |
There was a problem hiding this comment.
Confirm workspace type before calling deleteMainForHost
project.remove now routes any repo-root local workspace through v2Workspace.deleteMainForHost, but legacy/migrated repo-root workspaces are not always type="main". In that case deleteMainForHost rejects with BAD_REQUEST, and the mutation exits before local worktree/repo cleanup, so project removal can fail for migrated data. This branch should verify the cloud workspace type first (or handle non-main rows separately).
Useful? React with 👍 / 👎.
Summary
upstream (superset-sh/superset) から fork (MocA-Love/superset) への 2026-04-27 バッチ取り込み 第2弾。22 commits を 3 PR に分割した中の PR-B: DB / migration / machineId / main workspace (6 commits + 1 fix commit)。
取り込み内容
239773e390036(再復元) と00379590812301cc83989511c1ea669findMigrationByOtherOrg撤廃)9463af0c20038でv2_workspace_typeenum / main type 追加)c2cfdbea7machineIdに統合 (drizzle migration0039)。device.*→host.*改名、v2_hosts.machineId複合 PK 化加えて fork 固有の解消 commit
a7300ec1f fix(merge): drop fork-incompatible v1 experimental settingsを含む。重要な fork 側修正
Migration
0036(drop_pending_automation_status) の復元fork は過去の取り込み (
5b38c8a57chore: post-qstash-ship cleanup) で migration0036_drop_pending_automation_status.sqlを意図的に落としていた。今回239773e39(superset-sh#3723) で0037を追加するに当たって journal chain (0035 → 0036 → 0037) が不整合になるため、5b38c8a57の tree から0036_drop_pending_automation_status.sqlと0036_snapshot.jsonを復元して chain を再連結した。RESEND_API_KEYを optional 化959081230(superset-sh#3775) でpackages/trpc/src/env.tsにRESEND_API_KEYが必須として追加されたが、fork は upstream の support@superset.sh に migration エラーを送る立場ではない。ランタイム起動時に env validation で死なないよう optional 化し、support.sendMigrationReport呼び出し時に未設定なら503 SERVICE_UNAVAILABLEを返す no-op に切り替え。ExperimentalSettingsUI を再削除fork は過去に
apps/desktop/.../settings/experimental/を削除済みだったが、959081230(superset-sh#3775) と9463af0c2(superset-sh#3779) の auto-merge で復活していた。V2LocalOverrideState.setForceV1が既に存在せず、route 登録もないため build が通らない状態。apps/desktop/.../settings/experimental/ディレクトリ削除settings-search.tsからEXPERIMENTAL_SUPERSET_V2/EXPERIMENTAL_V1_MIGRATIONID と SETTINGS_ITEMS エントリ削除V1MigrationSummaryModalの"/settings/experimental"リンク削除 (V1 へ戻る UI を fork は提供しない)v2Workspace.updateNameFromHostの戻り値型修正959081230+c2cfdbea7を同時取り込みするとfindFirstの columns 限定 (4列 Pick) によって host-serviceadopt.tsのHostWorkspace期待型と合わない。getFromHostと同じく columns 限定を外して全列を返すようにした。host-service-coordinator.tsMIN_HOST_SERVICE_VERSION0.1.0→0.3.0に bump。machineId 統合後の host-service バイナリ要件 (device.*→host.*リネーム + 複合 PK)。Migration 系の fork 固有保持
migrate.tsのworkspace.type === "branch"分岐 (worktreeId 無し時に親プロジェクトの mainRepoPath で adopt) は維持branch-search.tsの FORK NOTE (listWorktreeBranches uses (git, repoPath)) は維持しつつ upstream のnormalizeWorktreePathを統合Fork 固有機能ヘルスチェック
baseline と比較し全項目健在を確認:
ansi_up,@vscode/ripgrep,@xyflow/reactTERMINAL_OPTIONS,SUPERSET_WORKSPACE_NAME,moonshot-ai.kimi-code,MainWindowEffects,INCEPTION_AUTH_PROVIDER_ID,v1MigrationState,TiptapPromptEditorapps/desktop/electron-builder.tsのdmg.size = "4g"維持packages/db/drizzle/最大 idx は 0039 に更新 (PR-A 後の 0035 → 0036/0037/0038/0039)packages/local-db/drizzle/最大 idx 0072 維持Test plan
bun install整合性 OKbun run typecheck全 28 task greenbun run lintbiome greenbun run --filter @superset/desktop build成功確認次のリファレンス
6c2a7719a,4399b7398,7c168e779,c885eb212を別 PR で。version は upstream1.6.2まで追従し、次回リリースをv1.6.2-fork.1から開始する予定。