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:
@@ -9,12 +9,30 @@ FROM users
|
||||
WHERE id = sqlc.arg(id) AND deleted_at IS NULL;
|
||||
|
||||
-- name: GetTenantMembership :one
|
||||
SELECT id, tenant_id, user_id, tenant_role, created_at
|
||||
FROM tenant_memberships
|
||||
WHERE user_id = sqlc.arg(user_id) AND deleted_at IS NULL
|
||||
SELECT tm.id,
|
||||
tm.tenant_id,
|
||||
tm.user_id,
|
||||
tm.tenant_role,
|
||||
tm.created_at,
|
||||
wm.workspace_id AS primary_workspace_id
|
||||
FROM tenant_memberships tm
|
||||
JOIN workspace_memberships wm
|
||||
ON wm.tenant_id = tm.tenant_id
|
||||
AND wm.user_id = tm.user_id
|
||||
AND wm.is_primary = TRUE
|
||||
WHERE tm.user_id = sqlc.arg(user_id) AND tm.deleted_at IS NULL
|
||||
LIMIT 1;
|
||||
|
||||
-- name: GetTenantMembershipByTenantAndUser :one
|
||||
SELECT id, tenant_id, user_id, tenant_role, created_at
|
||||
FROM tenant_memberships
|
||||
WHERE tenant_id = sqlc.arg(tenant_id) AND user_id = sqlc.arg(user_id) AND deleted_at IS NULL;
|
||||
SELECT tm.id,
|
||||
tm.tenant_id,
|
||||
tm.user_id,
|
||||
tm.tenant_role,
|
||||
tm.created_at,
|
||||
wm.workspace_id AS primary_workspace_id
|
||||
FROM tenant_memberships tm
|
||||
JOIN workspace_memberships wm
|
||||
ON wm.tenant_id = tm.tenant_id
|
||||
AND wm.user_id = tm.user_id
|
||||
AND wm.is_primary = TRUE
|
||||
WHERE tm.tenant_id = sqlc.arg(tenant_id) AND tm.user_id = sqlc.arg(user_id) AND tm.deleted_at IS NULL;
|
||||
|
||||
@@ -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;
|
||||
@@ -0,0 +1,70 @@
|
||||
-- name: RegisterDesktopClient :one
|
||||
INSERT INTO desktop_clients (
|
||||
id,
|
||||
tenant_id,
|
||||
workspace_id,
|
||||
user_id,
|
||||
token_hash,
|
||||
device_name,
|
||||
os,
|
||||
cpu_arch,
|
||||
client_version,
|
||||
channel
|
||||
)
|
||||
VALUES (
|
||||
sqlc.arg(id),
|
||||
sqlc.arg(tenant_id),
|
||||
sqlc.arg(workspace_id),
|
||||
sqlc.arg(user_id),
|
||||
sqlc.arg(token_hash),
|
||||
sqlc.narg(device_name),
|
||||
sqlc.narg(os),
|
||||
sqlc.narg(cpu_arch),
|
||||
sqlc.narg(client_version),
|
||||
sqlc.narg(channel)
|
||||
)
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetDesktopClientByTokenHash :one
|
||||
SELECT *
|
||||
FROM desktop_clients
|
||||
WHERE token_hash = sqlc.arg(token_hash)
|
||||
AND revoked_at IS NULL
|
||||
LIMIT 1;
|
||||
|
||||
-- name: RotateDesktopClientToken :one
|
||||
UPDATE desktop_clients
|
||||
SET token_hash = sqlc.arg(token_hash),
|
||||
last_rotated_at = now()
|
||||
WHERE id = sqlc.arg(id)
|
||||
AND workspace_id = sqlc.arg(workspace_id)
|
||||
AND revoked_at IS NULL
|
||||
RETURNING *;
|
||||
|
||||
-- name: HeartbeatDesktopClient :one
|
||||
UPDATE desktop_clients
|
||||
SET device_name = COALESCE(sqlc.narg(device_name), device_name),
|
||||
os = COALESCE(sqlc.narg(os), os),
|
||||
cpu_arch = COALESCE(sqlc.narg(cpu_arch), cpu_arch),
|
||||
client_version = COALESCE(sqlc.narg(client_version), client_version),
|
||||
channel = COALESCE(sqlc.narg(channel), channel),
|
||||
last_seen_at = now()
|
||||
WHERE id = sqlc.arg(id)
|
||||
AND workspace_id = sqlc.arg(workspace_id)
|
||||
AND revoked_at IS NULL
|
||||
RETURNING *;
|
||||
|
||||
-- name: RevokeDesktopClient :one
|
||||
UPDATE desktop_clients
|
||||
SET revoked_at = now()
|
||||
WHERE id = sqlc.arg(id)
|
||||
AND workspace_id = sqlc.arg(workspace_id)
|
||||
AND revoked_at IS NULL
|
||||
RETURNING *;
|
||||
|
||||
-- name: ListDesktopClientsByWorkspace :many
|
||||
SELECT *
|
||||
FROM desktop_clients
|
||||
WHERE workspace_id = sqlc.arg(workspace_id)
|
||||
AND revoked_at IS NULL
|
||||
ORDER BY last_seen_at DESC NULLS LAST, created_at DESC;
|
||||
@@ -0,0 +1,250 @@
|
||||
-- name: CreateDesktopPublishJob :one
|
||||
INSERT INTO desktop_publish_jobs (
|
||||
desktop_id,
|
||||
tenant_id,
|
||||
workspace_id,
|
||||
created_by_user_id,
|
||||
title,
|
||||
content_ref,
|
||||
scheduled_at
|
||||
)
|
||||
VALUES (
|
||||
sqlc.arg(desktop_id),
|
||||
sqlc.arg(tenant_id),
|
||||
sqlc.arg(workspace_id),
|
||||
sqlc.arg(created_by_user_id),
|
||||
sqlc.arg(title),
|
||||
sqlc.arg(content_ref),
|
||||
sqlc.narg(scheduled_at)
|
||||
)
|
||||
RETURNING *;
|
||||
|
||||
-- name: CreateDesktopTask :one
|
||||
INSERT INTO desktop_tasks (
|
||||
desktop_id,
|
||||
job_id,
|
||||
tenant_id,
|
||||
workspace_id,
|
||||
target_account_id,
|
||||
target_client_id,
|
||||
platform_id,
|
||||
kind,
|
||||
payload,
|
||||
status,
|
||||
dedup_key,
|
||||
parked_reason
|
||||
)
|
||||
VALUES (
|
||||
sqlc.arg(desktop_id),
|
||||
sqlc.arg(job_id),
|
||||
sqlc.arg(tenant_id),
|
||||
sqlc.arg(workspace_id),
|
||||
sqlc.arg(target_account_id),
|
||||
sqlc.arg(target_client_id),
|
||||
sqlc.arg(platform_id),
|
||||
sqlc.arg(kind),
|
||||
sqlc.arg(payload),
|
||||
sqlc.arg(status),
|
||||
sqlc.narg(dedup_key),
|
||||
sqlc.narg(parked_reason)
|
||||
)
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetDesktopTaskByDesktopID :one
|
||||
SELECT *
|
||||
FROM desktop_tasks
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND workspace_id = sqlc.arg(workspace_id)
|
||||
LIMIT 1;
|
||||
|
||||
-- name: LeaseNextQueuedDesktopTask :one
|
||||
WITH candidate AS (
|
||||
SELECT dt.desktop_id
|
||||
FROM desktop_tasks AS dt
|
||||
WHERE dt.target_client_id = sqlc.arg(client_id)
|
||||
AND dt.status = 'queued'
|
||||
AND (
|
||||
sqlc.narg(kind)::text IS NULL
|
||||
OR dt.kind = sqlc.narg(kind)::text
|
||||
)
|
||||
ORDER BY dt.created_at ASC, dt.desktop_id ASC
|
||||
LIMIT 1
|
||||
FOR UPDATE SKIP LOCKED
|
||||
)
|
||||
UPDATE desktop_tasks AS t
|
||||
SET active_attempt_id = sqlc.arg(attempt_id),
|
||||
lease_token_hash = sqlc.arg(lease_token_hash),
|
||||
lease_expires_at = now() + interval '10 minutes',
|
||||
status = 'in_progress',
|
||||
attempts = t.attempts + 1,
|
||||
parked_reason = NULL,
|
||||
updated_at = now()
|
||||
FROM candidate
|
||||
WHERE t.desktop_id = candidate.desktop_id
|
||||
RETURNING t.*;
|
||||
|
||||
-- name: LeaseQueuedDesktopTaskByDesktopID :one
|
||||
UPDATE desktop_tasks
|
||||
SET active_attempt_id = sqlc.arg(attempt_id),
|
||||
lease_token_hash = sqlc.arg(lease_token_hash),
|
||||
lease_expires_at = now() + interval '10 minutes',
|
||||
status = 'in_progress',
|
||||
attempts = attempts + 1,
|
||||
parked_reason = NULL,
|
||||
updated_at = now()
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND target_client_id = sqlc.arg(client_id)
|
||||
AND status = 'queued'
|
||||
RETURNING *;
|
||||
|
||||
-- name: LeaseParkedDesktopTask :one
|
||||
UPDATE desktop_tasks
|
||||
SET active_attempt_id = sqlc.arg(attempt_id),
|
||||
lease_token_hash = sqlc.arg(lease_token_hash),
|
||||
lease_expires_at = now() + interval '10 minutes',
|
||||
status = 'in_progress',
|
||||
attempts = attempts + 1,
|
||||
parked_reason = NULL,
|
||||
updated_at = now()
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND target_client_id = sqlc.arg(client_id)
|
||||
AND status = 'waiting_user'
|
||||
AND active_attempt_id IS NULL
|
||||
RETURNING *;
|
||||
|
||||
-- name: ExtendDesktopTaskLease :one
|
||||
UPDATE desktop_tasks
|
||||
SET lease_expires_at = now() + interval '10 minutes',
|
||||
updated_at = now()
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND lease_token_hash = sqlc.arg(lease_token_hash)
|
||||
AND status = 'in_progress'
|
||||
RETURNING *;
|
||||
|
||||
-- name: ParkDesktopTask :one
|
||||
UPDATE desktop_tasks
|
||||
SET status = 'waiting_user',
|
||||
active_attempt_id = NULL,
|
||||
lease_token_hash = NULL,
|
||||
lease_expires_at = NULL,
|
||||
parked_reason = sqlc.arg(parked_reason),
|
||||
updated_at = now()
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND lease_token_hash = sqlc.arg(lease_token_hash)
|
||||
AND status = 'in_progress'
|
||||
RETURNING *;
|
||||
|
||||
-- name: CompleteDesktopTask :one
|
||||
UPDATE desktop_tasks
|
||||
SET status = sqlc.arg(status),
|
||||
result = sqlc.narg(result),
|
||||
error = sqlc.narg(error),
|
||||
active_attempt_id = NULL,
|
||||
lease_token_hash = NULL,
|
||||
lease_expires_at = NULL,
|
||||
parked_reason = NULL,
|
||||
updated_at = now()
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND lease_token_hash = sqlc.arg(lease_token_hash)
|
||||
AND status = 'in_progress'
|
||||
RETURNING *;
|
||||
|
||||
-- name: CancelDesktopTaskByLease :one
|
||||
UPDATE desktop_tasks
|
||||
SET status = 'aborted',
|
||||
error = sqlc.narg(error),
|
||||
active_attempt_id = NULL,
|
||||
lease_token_hash = NULL,
|
||||
lease_expires_at = NULL,
|
||||
parked_reason = NULL,
|
||||
updated_at = now()
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND lease_token_hash = sqlc.arg(lease_token_hash)
|
||||
AND status = 'in_progress'
|
||||
RETURNING *;
|
||||
|
||||
-- name: CancelDesktopTaskByClient :one
|
||||
UPDATE desktop_tasks
|
||||
SET status = 'aborted',
|
||||
error = sqlc.narg(error),
|
||||
active_attempt_id = NULL,
|
||||
lease_token_hash = NULL,
|
||||
lease_expires_at = NULL,
|
||||
parked_reason = NULL,
|
||||
updated_at = now()
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND target_client_id = sqlc.arg(client_id)
|
||||
AND status IN ('queued', 'waiting_user')
|
||||
RETURNING *;
|
||||
|
||||
-- name: TenantCancelDesktopTask :one
|
||||
UPDATE desktop_tasks
|
||||
SET status = 'aborted',
|
||||
error = sqlc.narg(error),
|
||||
active_attempt_id = NULL,
|
||||
lease_token_hash = NULL,
|
||||
lease_expires_at = NULL,
|
||||
parked_reason = NULL,
|
||||
updated_at = now()
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND workspace_id = sqlc.arg(workspace_id)
|
||||
AND status IN ('queued', 'waiting_user')
|
||||
RETURNING *;
|
||||
|
||||
-- name: ReconcileDesktopTask :one
|
||||
UPDATE desktop_tasks
|
||||
SET status = CASE
|
||||
WHEN sqlc.arg(status)::text = 'retry' THEN 'queued'
|
||||
ELSE sqlc.arg(status)::text
|
||||
END,
|
||||
result = CASE
|
||||
WHEN sqlc.arg(status)::text = 'retry' THEN NULL
|
||||
ELSE sqlc.narg(result)
|
||||
END,
|
||||
error = sqlc.narg(error),
|
||||
active_attempt_id = NULL,
|
||||
lease_token_hash = NULL,
|
||||
lease_expires_at = NULL,
|
||||
parked_reason = NULL,
|
||||
attempts = attempts + CASE WHEN sqlc.arg(status)::text = 'retry' THEN 1 ELSE 0 END,
|
||||
updated_at = now()
|
||||
WHERE desktop_id = sqlc.arg(desktop_id)
|
||||
AND workspace_id = sqlc.arg(workspace_id)
|
||||
AND status = 'unknown'
|
||||
RETURNING *;
|
||||
|
||||
-- name: MarkDesktopTasksUnknownByClient :execrows
|
||||
UPDATE desktop_tasks
|
||||
SET status = 'unknown',
|
||||
error = sqlc.narg(error),
|
||||
active_attempt_id = NULL,
|
||||
lease_token_hash = NULL,
|
||||
lease_expires_at = NULL,
|
||||
parked_reason = NULL,
|
||||
updated_at = now()
|
||||
WHERE target_client_id = sqlc.arg(client_id)
|
||||
AND workspace_id = sqlc.arg(workspace_id)
|
||||
AND status IN ('waiting_user', 'in_progress');
|
||||
|
||||
-- name: CreateDesktopTaskAttempt :one
|
||||
INSERT INTO desktop_task_attempts (
|
||||
desktop_id,
|
||||
task_id,
|
||||
client_id,
|
||||
lease_token_hash
|
||||
)
|
||||
VALUES (
|
||||
sqlc.arg(desktop_id),
|
||||
sqlc.arg(task_id),
|
||||
sqlc.arg(client_id),
|
||||
sqlc.arg(lease_token_hash)
|
||||
)
|
||||
RETURNING *;
|
||||
|
||||
-- name: FinishDesktopTaskAttempt :exec
|
||||
UPDATE desktop_task_attempts
|
||||
SET ended_at = now(),
|
||||
final_status = sqlc.narg(final_status),
|
||||
error = sqlc.narg(error)
|
||||
WHERE task_id = sqlc.arg(task_id)
|
||||
AND desktop_id = sqlc.arg(attempt_id);
|
||||
Reference in New Issue
Block a user