feat(desktop): implement workspace foundation + desktop-client skeleton
Plan 0 (workspaces): add workspaces + workspace_memberships schema, extend JWT/Actor/claims with primary_workspace_id, seed default workspace per tenant, thread workspace_id through tenant monitoring quota. Plan A (desktop skeleton): new Electron app (apps/desktop-client) with main/ preload/renderer, shared Vue component package (packages/ui-shared), and server surface — desktop client registration + token rotation + heartbeat, SSE task event stream, desktop accounts/tasks/content handlers, publish job endpoint, and supporting repositories, services, sqlc queries, and migrations. Hard cutover per plan: remove browser-extension monitoring callback endpoints, stub legacy media API in admin-web, and delete monitoring_callback_handler.go.
This commit is contained in:
@@ -0,0 +1,268 @@
|
||||
-- name: ListDesktopAccountsByClient :many
|
||||
SELECT
|
||||
desktop_id,
|
||||
tenant_id,
|
||||
workspace_id,
|
||||
user_id,
|
||||
client_id,
|
||||
platform_id,
|
||||
platform_uid,
|
||||
account_fingerprint,
|
||||
display_name,
|
||||
health,
|
||||
verified_at,
|
||||
tags,
|
||||
sync_version,
|
||||
deleted_at,
|
||||
delete_requested_at,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM platform_accounts
|
||||
WHERE workspace_id = sqlc.arg(workspace_id)
|
||||
AND client_id = sqlc.arg(client_id)
|
||||
ORDER BY platform_id, display_name, created_at DESC;
|
||||
|
||||
-- name: GetDesktopAccountByDesktopID :one
|
||||
SELECT
|
||||
desktop_id,
|
||||
tenant_id,
|
||||
workspace_id,
|
||||
user_id,
|
||||
client_id,
|
||||
platform_id,
|
||||
platform_uid,
|
||||
account_fingerprint,
|
||||
display_name,
|
||||
health,
|
||||
verified_at,
|
||||
tags,
|
||||
sync_version,
|
||||
deleted_at,
|
||||
delete_requested_at,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM platform_accounts
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND workspace_id = sqlc.arg(workspace_id)
|
||||
LIMIT 1;
|
||||
|
||||
-- name: GetDesktopAccountByIdentity :one
|
||||
SELECT
|
||||
desktop_id,
|
||||
tenant_id,
|
||||
workspace_id,
|
||||
user_id,
|
||||
client_id,
|
||||
platform_id,
|
||||
platform_uid,
|
||||
account_fingerprint,
|
||||
display_name,
|
||||
health,
|
||||
verified_at,
|
||||
tags,
|
||||
sync_version,
|
||||
deleted_at,
|
||||
delete_requested_at,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM platform_accounts
|
||||
WHERE workspace_id = sqlc.arg(workspace_id)
|
||||
AND platform_id = sqlc.arg(platform_id)
|
||||
AND platform_uid = sqlc.arg(platform_uid)
|
||||
AND deleted_at IS NULL
|
||||
LIMIT 1;
|
||||
|
||||
-- name: UpsertDesktopAccount :one
|
||||
INSERT INTO platform_accounts (
|
||||
desktop_id,
|
||||
tenant_id,
|
||||
workspace_id,
|
||||
user_id,
|
||||
client_id,
|
||||
platform_id,
|
||||
platform_uid,
|
||||
nickname,
|
||||
status,
|
||||
metadata_json,
|
||||
last_check_at,
|
||||
account_fingerprint,
|
||||
display_name,
|
||||
health,
|
||||
verified_at,
|
||||
tags,
|
||||
sync_version
|
||||
)
|
||||
VALUES (
|
||||
sqlc.arg(desktop_id),
|
||||
sqlc.arg(tenant_id),
|
||||
sqlc.arg(workspace_id),
|
||||
sqlc.arg(user_id),
|
||||
sqlc.arg(client_id),
|
||||
sqlc.arg(platform_id),
|
||||
sqlc.arg(platform_uid),
|
||||
sqlc.arg(display_name)::text,
|
||||
sqlc.arg(legacy_status),
|
||||
sqlc.narg(metadata_json),
|
||||
sqlc.narg(verified_at),
|
||||
sqlc.narg(account_fingerprint),
|
||||
sqlc.arg(display_name)::text,
|
||||
sqlc.arg(health),
|
||||
sqlc.narg(verified_at),
|
||||
sqlc.narg(tags),
|
||||
1
|
||||
)
|
||||
ON CONFLICT (workspace_id, platform_id, platform_uid) WHERE deleted_at IS NULL
|
||||
DO UPDATE SET
|
||||
client_id = EXCLUDED.client_id,
|
||||
user_id = EXCLUDED.user_id,
|
||||
nickname = EXCLUDED.nickname,
|
||||
status = EXCLUDED.status,
|
||||
metadata_json = COALESCE(EXCLUDED.metadata_json, platform_accounts.metadata_json),
|
||||
last_check_at = COALESCE(EXCLUDED.last_check_at, platform_accounts.last_check_at),
|
||||
account_fingerprint = EXCLUDED.account_fingerprint,
|
||||
display_name = EXCLUDED.display_name,
|
||||
health = EXCLUDED.health,
|
||||
verified_at = COALESCE(EXCLUDED.verified_at, platform_accounts.verified_at),
|
||||
tags = EXCLUDED.tags,
|
||||
sync_version = platform_accounts.sync_version + 1,
|
||||
delete_requested_at = NULL,
|
||||
updated_at = now()
|
||||
WHERE platform_accounts.workspace_id = EXCLUDED.workspace_id
|
||||
AND (
|
||||
sqlc.narg(if_sync_version)::bigint IS NULL
|
||||
OR platform_accounts.sync_version = sqlc.narg(if_sync_version)::bigint
|
||||
)
|
||||
RETURNING
|
||||
desktop_id,
|
||||
tenant_id,
|
||||
workspace_id,
|
||||
user_id,
|
||||
client_id,
|
||||
platform_id,
|
||||
platform_uid,
|
||||
account_fingerprint,
|
||||
display_name,
|
||||
health,
|
||||
verified_at,
|
||||
tags,
|
||||
sync_version,
|
||||
deleted_at,
|
||||
delete_requested_at,
|
||||
created_at,
|
||||
updated_at;
|
||||
|
||||
-- name: PatchDesktopAccount :one
|
||||
UPDATE platform_accounts
|
||||
SET display_name = COALESCE(sqlc.narg(display_name)::text, display_name),
|
||||
nickname = COALESCE(sqlc.narg(display_name)::text, nickname),
|
||||
health = COALESCE(sqlc.narg(health), health),
|
||||
status = COALESCE(sqlc.narg(legacy_status), status),
|
||||
verified_at = COALESCE(sqlc.narg(verified_at), verified_at),
|
||||
last_check_at = COALESCE(sqlc.narg(verified_at), last_check_at),
|
||||
tags = COALESCE(sqlc.narg(tags), tags),
|
||||
sync_version = sync_version + 1,
|
||||
updated_at = now()
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND workspace_id = sqlc.arg(workspace_id)
|
||||
AND sync_version = sqlc.arg(if_sync_version)
|
||||
AND deleted_at IS NULL
|
||||
RETURNING
|
||||
desktop_id,
|
||||
tenant_id,
|
||||
workspace_id,
|
||||
user_id,
|
||||
client_id,
|
||||
platform_id,
|
||||
platform_uid,
|
||||
account_fingerprint,
|
||||
display_name,
|
||||
health,
|
||||
verified_at,
|
||||
tags,
|
||||
sync_version,
|
||||
deleted_at,
|
||||
delete_requested_at,
|
||||
created_at,
|
||||
updated_at;
|
||||
|
||||
-- name: TombstoneDesktopAccount :one
|
||||
UPDATE platform_accounts
|
||||
SET deleted_at = now(),
|
||||
sync_version = sync_version + 1,
|
||||
updated_at = now()
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND workspace_id = sqlc.arg(workspace_id)
|
||||
AND sync_version = sqlc.arg(if_sync_version)
|
||||
AND deleted_at IS NULL
|
||||
RETURNING
|
||||
desktop_id,
|
||||
tenant_id,
|
||||
workspace_id,
|
||||
user_id,
|
||||
client_id,
|
||||
platform_id,
|
||||
platform_uid,
|
||||
account_fingerprint,
|
||||
display_name,
|
||||
health,
|
||||
verified_at,
|
||||
tags,
|
||||
sync_version,
|
||||
deleted_at,
|
||||
delete_requested_at,
|
||||
created_at,
|
||||
updated_at;
|
||||
|
||||
-- name: MarkDesktopAccountDeleteRequested :one
|
||||
UPDATE platform_accounts
|
||||
SET delete_requested_at = now(),
|
||||
sync_version = sync_version + 1,
|
||||
updated_at = now()
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND workspace_id = sqlc.arg(workspace_id)
|
||||
AND deleted_at IS NULL
|
||||
RETURNING
|
||||
desktop_id,
|
||||
tenant_id,
|
||||
workspace_id,
|
||||
user_id,
|
||||
client_id,
|
||||
platform_id,
|
||||
platform_uid,
|
||||
account_fingerprint,
|
||||
display_name,
|
||||
health,
|
||||
verified_at,
|
||||
tags,
|
||||
sync_version,
|
||||
deleted_at,
|
||||
delete_requested_at,
|
||||
created_at,
|
||||
updated_at;
|
||||
|
||||
-- name: ClearDesktopAccountDeleteRequested :one
|
||||
UPDATE platform_accounts
|
||||
SET delete_requested_at = NULL,
|
||||
sync_version = sync_version + 1,
|
||||
updated_at = now()
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND workspace_id = sqlc.arg(workspace_id)
|
||||
AND deleted_at IS NULL
|
||||
RETURNING
|
||||
desktop_id,
|
||||
tenant_id,
|
||||
workspace_id,
|
||||
user_id,
|
||||
client_id,
|
||||
platform_id,
|
||||
platform_uid,
|
||||
account_fingerprint,
|
||||
display_name,
|
||||
health,
|
||||
verified_at,
|
||||
tags,
|
||||
sync_version,
|
||||
deleted_at,
|
||||
delete_requested_at,
|
||||
created_at,
|
||||
updated_at;
|
||||
Reference in New Issue
Block a user