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:
2026-04-19 14:18:20 +08:00
parent 98f9e95875
commit b16e9f0bd1
141 changed files with 21533 additions and 357 deletions
@@ -12,18 +12,28 @@ import (
)
const getTenantMembership = `-- name: GetTenantMembership :one
SELECT id, tenant_id, user_id, tenant_role, created_at
FROM tenant_memberships
WHERE user_id = $1 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 = $1 AND tm.deleted_at IS NULL
LIMIT 1
`
type GetTenantMembershipRow struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
UserID int64 `json:"user_id"`
TenantRole string `json:"tenant_role"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
UserID int64 `json:"user_id"`
TenantRole string `json:"tenant_role"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
PrimaryWorkspaceID int64 `json:"primary_workspace_id"`
}
func (q *Queries) GetTenantMembership(ctx context.Context, userID int64) (GetTenantMembershipRow, error) {
@@ -35,14 +45,24 @@ func (q *Queries) GetTenantMembership(ctx context.Context, userID int64) (GetTen
&i.UserID,
&i.TenantRole,
&i.CreatedAt,
&i.PrimaryWorkspaceID,
)
return i, err
}
const getTenantMembershipByTenantAndUser = `-- name: GetTenantMembershipByTenantAndUser :one
SELECT id, tenant_id, user_id, tenant_role, created_at
FROM tenant_memberships
WHERE tenant_id = $1 AND user_id = $2 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 = $1 AND tm.user_id = $2 AND tm.deleted_at IS NULL
`
type GetTenantMembershipByTenantAndUserParams struct {
@@ -51,11 +71,12 @@ type GetTenantMembershipByTenantAndUserParams struct {
}
type GetTenantMembershipByTenantAndUserRow struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
UserID int64 `json:"user_id"`
TenantRole string `json:"tenant_role"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
UserID int64 `json:"user_id"`
TenantRole string `json:"tenant_role"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
PrimaryWorkspaceID int64 `json:"primary_workspace_id"`
}
func (q *Queries) GetTenantMembershipByTenantAndUser(ctx context.Context, arg GetTenantMembershipByTenantAndUserParams) (GetTenantMembershipByTenantAndUserRow, error) {
@@ -67,6 +88,7 @@ func (q *Queries) GetTenantMembershipByTenantAndUser(ctx context.Context, arg Ge
&i.UserID,
&i.TenantRole,
&i.CreatedAt,
&i.PrimaryWorkspaceID,
)
return i, err
}
@@ -0,0 +1,748 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: desktop_account.sql
package generated
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const clearDesktopAccountDeleteRequested = `-- name: ClearDesktopAccountDeleteRequested :one
UPDATE platform_accounts
SET delete_requested_at = NULL,
sync_version = sync_version + 1,
updated_at = now()
WHERE desktop_id = $1
AND workspace_id = $2
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
`
type ClearDesktopAccountDeleteRequestedParams struct {
DesktopID pgtype.UUID `json:"desktop_id"`
WorkspaceID int64 `json:"workspace_id"`
}
type ClearDesktopAccountDeleteRequestedRow struct {
DesktopID pgtype.UUID `json:"desktop_id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
UserID int64 `json:"user_id"`
ClientID pgtype.UUID `json:"client_id"`
PlatformID string `json:"platform_id"`
PlatformUid string `json:"platform_uid"`
AccountFingerprint pgtype.Text `json:"account_fingerprint"`
DisplayName string `json:"display_name"`
Health string `json:"health"`
VerifiedAt pgtype.Timestamptz `json:"verified_at"`
Tags []byte `json:"tags"`
SyncVersion int64 `json:"sync_version"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
DeleteRequestedAt pgtype.Timestamptz `json:"delete_requested_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) ClearDesktopAccountDeleteRequested(ctx context.Context, arg ClearDesktopAccountDeleteRequestedParams) (ClearDesktopAccountDeleteRequestedRow, error) {
row := q.db.QueryRow(ctx, clearDesktopAccountDeleteRequested, arg.DesktopID, arg.WorkspaceID)
var i ClearDesktopAccountDeleteRequestedRow
err := row.Scan(
&i.DesktopID,
&i.TenantID,
&i.WorkspaceID,
&i.UserID,
&i.ClientID,
&i.PlatformID,
&i.PlatformUid,
&i.AccountFingerprint,
&i.DisplayName,
&i.Health,
&i.VerifiedAt,
&i.Tags,
&i.SyncVersion,
&i.DeletedAt,
&i.DeleteRequestedAt,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getDesktopAccountByDesktopID = `-- 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 = $1
AND workspace_id = $2
LIMIT 1
`
type GetDesktopAccountByDesktopIDParams struct {
DesktopID pgtype.UUID `json:"desktop_id"`
WorkspaceID int64 `json:"workspace_id"`
}
type GetDesktopAccountByDesktopIDRow struct {
DesktopID pgtype.UUID `json:"desktop_id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
UserID int64 `json:"user_id"`
ClientID pgtype.UUID `json:"client_id"`
PlatformID string `json:"platform_id"`
PlatformUid string `json:"platform_uid"`
AccountFingerprint pgtype.Text `json:"account_fingerprint"`
DisplayName string `json:"display_name"`
Health string `json:"health"`
VerifiedAt pgtype.Timestamptz `json:"verified_at"`
Tags []byte `json:"tags"`
SyncVersion int64 `json:"sync_version"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
DeleteRequestedAt pgtype.Timestamptz `json:"delete_requested_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) GetDesktopAccountByDesktopID(ctx context.Context, arg GetDesktopAccountByDesktopIDParams) (GetDesktopAccountByDesktopIDRow, error) {
row := q.db.QueryRow(ctx, getDesktopAccountByDesktopID, arg.DesktopID, arg.WorkspaceID)
var i GetDesktopAccountByDesktopIDRow
err := row.Scan(
&i.DesktopID,
&i.TenantID,
&i.WorkspaceID,
&i.UserID,
&i.ClientID,
&i.PlatformID,
&i.PlatformUid,
&i.AccountFingerprint,
&i.DisplayName,
&i.Health,
&i.VerifiedAt,
&i.Tags,
&i.SyncVersion,
&i.DeletedAt,
&i.DeleteRequestedAt,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getDesktopAccountByIdentity = `-- 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 = $1
AND platform_id = $2
AND platform_uid = $3
AND deleted_at IS NULL
LIMIT 1
`
type GetDesktopAccountByIdentityParams struct {
WorkspaceID int64 `json:"workspace_id"`
PlatformID string `json:"platform_id"`
PlatformUid string `json:"platform_uid"`
}
type GetDesktopAccountByIdentityRow struct {
DesktopID pgtype.UUID `json:"desktop_id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
UserID int64 `json:"user_id"`
ClientID pgtype.UUID `json:"client_id"`
PlatformID string `json:"platform_id"`
PlatformUid string `json:"platform_uid"`
AccountFingerprint pgtype.Text `json:"account_fingerprint"`
DisplayName string `json:"display_name"`
Health string `json:"health"`
VerifiedAt pgtype.Timestamptz `json:"verified_at"`
Tags []byte `json:"tags"`
SyncVersion int64 `json:"sync_version"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
DeleteRequestedAt pgtype.Timestamptz `json:"delete_requested_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) GetDesktopAccountByIdentity(ctx context.Context, arg GetDesktopAccountByIdentityParams) (GetDesktopAccountByIdentityRow, error) {
row := q.db.QueryRow(ctx, getDesktopAccountByIdentity, arg.WorkspaceID, arg.PlatformID, arg.PlatformUid)
var i GetDesktopAccountByIdentityRow
err := row.Scan(
&i.DesktopID,
&i.TenantID,
&i.WorkspaceID,
&i.UserID,
&i.ClientID,
&i.PlatformID,
&i.PlatformUid,
&i.AccountFingerprint,
&i.DisplayName,
&i.Health,
&i.VerifiedAt,
&i.Tags,
&i.SyncVersion,
&i.DeletedAt,
&i.DeleteRequestedAt,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const listDesktopAccountsByClient = `-- 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 = $1
AND client_id = $2
ORDER BY platform_id, display_name, created_at DESC
`
type ListDesktopAccountsByClientParams struct {
WorkspaceID int64 `json:"workspace_id"`
ClientID pgtype.UUID `json:"client_id"`
}
type ListDesktopAccountsByClientRow struct {
DesktopID pgtype.UUID `json:"desktop_id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
UserID int64 `json:"user_id"`
ClientID pgtype.UUID `json:"client_id"`
PlatformID string `json:"platform_id"`
PlatformUid string `json:"platform_uid"`
AccountFingerprint pgtype.Text `json:"account_fingerprint"`
DisplayName string `json:"display_name"`
Health string `json:"health"`
VerifiedAt pgtype.Timestamptz `json:"verified_at"`
Tags []byte `json:"tags"`
SyncVersion int64 `json:"sync_version"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
DeleteRequestedAt pgtype.Timestamptz `json:"delete_requested_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) ListDesktopAccountsByClient(ctx context.Context, arg ListDesktopAccountsByClientParams) ([]ListDesktopAccountsByClientRow, error) {
rows, err := q.db.Query(ctx, listDesktopAccountsByClient, arg.WorkspaceID, arg.ClientID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListDesktopAccountsByClientRow
for rows.Next() {
var i ListDesktopAccountsByClientRow
if err := rows.Scan(
&i.DesktopID,
&i.TenantID,
&i.WorkspaceID,
&i.UserID,
&i.ClientID,
&i.PlatformID,
&i.PlatformUid,
&i.AccountFingerprint,
&i.DisplayName,
&i.Health,
&i.VerifiedAt,
&i.Tags,
&i.SyncVersion,
&i.DeletedAt,
&i.DeleteRequestedAt,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const markDesktopAccountDeleteRequested = `-- name: MarkDesktopAccountDeleteRequested :one
UPDATE platform_accounts
SET delete_requested_at = now(),
sync_version = sync_version + 1,
updated_at = now()
WHERE desktop_id = $1
AND workspace_id = $2
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
`
type MarkDesktopAccountDeleteRequestedParams struct {
DesktopID pgtype.UUID `json:"desktop_id"`
WorkspaceID int64 `json:"workspace_id"`
}
type MarkDesktopAccountDeleteRequestedRow struct {
DesktopID pgtype.UUID `json:"desktop_id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
UserID int64 `json:"user_id"`
ClientID pgtype.UUID `json:"client_id"`
PlatformID string `json:"platform_id"`
PlatformUid string `json:"platform_uid"`
AccountFingerprint pgtype.Text `json:"account_fingerprint"`
DisplayName string `json:"display_name"`
Health string `json:"health"`
VerifiedAt pgtype.Timestamptz `json:"verified_at"`
Tags []byte `json:"tags"`
SyncVersion int64 `json:"sync_version"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
DeleteRequestedAt pgtype.Timestamptz `json:"delete_requested_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) MarkDesktopAccountDeleteRequested(ctx context.Context, arg MarkDesktopAccountDeleteRequestedParams) (MarkDesktopAccountDeleteRequestedRow, error) {
row := q.db.QueryRow(ctx, markDesktopAccountDeleteRequested, arg.DesktopID, arg.WorkspaceID)
var i MarkDesktopAccountDeleteRequestedRow
err := row.Scan(
&i.DesktopID,
&i.TenantID,
&i.WorkspaceID,
&i.UserID,
&i.ClientID,
&i.PlatformID,
&i.PlatformUid,
&i.AccountFingerprint,
&i.DisplayName,
&i.Health,
&i.VerifiedAt,
&i.Tags,
&i.SyncVersion,
&i.DeletedAt,
&i.DeleteRequestedAt,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const patchDesktopAccount = `-- name: PatchDesktopAccount :one
UPDATE platform_accounts
SET display_name = COALESCE($1::text, display_name),
nickname = COALESCE($1::text, nickname),
health = COALESCE($2, health),
status = COALESCE($3, status),
verified_at = COALESCE($4, verified_at),
last_check_at = COALESCE($4, last_check_at),
tags = COALESCE($5, tags),
sync_version = sync_version + 1,
updated_at = now()
WHERE desktop_id = $6
AND workspace_id = $7
AND sync_version = $8
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
`
type PatchDesktopAccountParams struct {
DisplayName pgtype.Text `json:"display_name"`
Health pgtype.Text `json:"health"`
LegacyStatus pgtype.Text `json:"legacy_status"`
VerifiedAt pgtype.Timestamptz `json:"verified_at"`
Tags []byte `json:"tags"`
DesktopID pgtype.UUID `json:"desktop_id"`
WorkspaceID int64 `json:"workspace_id"`
IfSyncVersion int64 `json:"if_sync_version"`
}
type PatchDesktopAccountRow struct {
DesktopID pgtype.UUID `json:"desktop_id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
UserID int64 `json:"user_id"`
ClientID pgtype.UUID `json:"client_id"`
PlatformID string `json:"platform_id"`
PlatformUid string `json:"platform_uid"`
AccountFingerprint pgtype.Text `json:"account_fingerprint"`
DisplayName string `json:"display_name"`
Health string `json:"health"`
VerifiedAt pgtype.Timestamptz `json:"verified_at"`
Tags []byte `json:"tags"`
SyncVersion int64 `json:"sync_version"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
DeleteRequestedAt pgtype.Timestamptz `json:"delete_requested_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) PatchDesktopAccount(ctx context.Context, arg PatchDesktopAccountParams) (PatchDesktopAccountRow, error) {
row := q.db.QueryRow(ctx, patchDesktopAccount,
arg.DisplayName,
arg.Health,
arg.LegacyStatus,
arg.VerifiedAt,
arg.Tags,
arg.DesktopID,
arg.WorkspaceID,
arg.IfSyncVersion,
)
var i PatchDesktopAccountRow
err := row.Scan(
&i.DesktopID,
&i.TenantID,
&i.WorkspaceID,
&i.UserID,
&i.ClientID,
&i.PlatformID,
&i.PlatformUid,
&i.AccountFingerprint,
&i.DisplayName,
&i.Health,
&i.VerifiedAt,
&i.Tags,
&i.SyncVersion,
&i.DeletedAt,
&i.DeleteRequestedAt,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const tombstoneDesktopAccount = `-- name: TombstoneDesktopAccount :one
UPDATE platform_accounts
SET deleted_at = now(),
sync_version = sync_version + 1,
updated_at = now()
WHERE desktop_id = $1
AND workspace_id = $2
AND sync_version = $3
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
`
type TombstoneDesktopAccountParams struct {
DesktopID pgtype.UUID `json:"desktop_id"`
WorkspaceID int64 `json:"workspace_id"`
IfSyncVersion int64 `json:"if_sync_version"`
}
type TombstoneDesktopAccountRow struct {
DesktopID pgtype.UUID `json:"desktop_id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
UserID int64 `json:"user_id"`
ClientID pgtype.UUID `json:"client_id"`
PlatformID string `json:"platform_id"`
PlatformUid string `json:"platform_uid"`
AccountFingerprint pgtype.Text `json:"account_fingerprint"`
DisplayName string `json:"display_name"`
Health string `json:"health"`
VerifiedAt pgtype.Timestamptz `json:"verified_at"`
Tags []byte `json:"tags"`
SyncVersion int64 `json:"sync_version"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
DeleteRequestedAt pgtype.Timestamptz `json:"delete_requested_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) TombstoneDesktopAccount(ctx context.Context, arg TombstoneDesktopAccountParams) (TombstoneDesktopAccountRow, error) {
row := q.db.QueryRow(ctx, tombstoneDesktopAccount, arg.DesktopID, arg.WorkspaceID, arg.IfSyncVersion)
var i TombstoneDesktopAccountRow
err := row.Scan(
&i.DesktopID,
&i.TenantID,
&i.WorkspaceID,
&i.UserID,
&i.ClientID,
&i.PlatformID,
&i.PlatformUid,
&i.AccountFingerprint,
&i.DisplayName,
&i.Health,
&i.VerifiedAt,
&i.Tags,
&i.SyncVersion,
&i.DeletedAt,
&i.DeleteRequestedAt,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const upsertDesktopAccount = `-- 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 (
$1,
$2,
$3,
$4,
$5,
$6,
$7,
$8::text,
$9,
$10,
$11,
$12,
$8::text,
$13,
$11,
$14,
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 (
$15::bigint IS NULL
OR platform_accounts.sync_version = $15::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
`
type UpsertDesktopAccountParams struct {
DesktopID pgtype.UUID `json:"desktop_id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
UserID int64 `json:"user_id"`
ClientID pgtype.UUID `json:"client_id"`
PlatformID string `json:"platform_id"`
PlatformUid string `json:"platform_uid"`
DisplayName string `json:"display_name"`
LegacyStatus string `json:"legacy_status"`
MetadataJson []byte `json:"metadata_json"`
VerifiedAt pgtype.Timestamptz `json:"verified_at"`
AccountFingerprint pgtype.Text `json:"account_fingerprint"`
Health string `json:"health"`
Tags []byte `json:"tags"`
IfSyncVersion pgtype.Int8 `json:"if_sync_version"`
}
type UpsertDesktopAccountRow struct {
DesktopID pgtype.UUID `json:"desktop_id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
UserID int64 `json:"user_id"`
ClientID pgtype.UUID `json:"client_id"`
PlatformID string `json:"platform_id"`
PlatformUid string `json:"platform_uid"`
AccountFingerprint pgtype.Text `json:"account_fingerprint"`
DisplayName string `json:"display_name"`
Health string `json:"health"`
VerifiedAt pgtype.Timestamptz `json:"verified_at"`
Tags []byte `json:"tags"`
SyncVersion int64 `json:"sync_version"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
DeleteRequestedAt pgtype.Timestamptz `json:"delete_requested_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) UpsertDesktopAccount(ctx context.Context, arg UpsertDesktopAccountParams) (UpsertDesktopAccountRow, error) {
row := q.db.QueryRow(ctx, upsertDesktopAccount,
arg.DesktopID,
arg.TenantID,
arg.WorkspaceID,
arg.UserID,
arg.ClientID,
arg.PlatformID,
arg.PlatformUid,
arg.DisplayName,
arg.LegacyStatus,
arg.MetadataJson,
arg.VerifiedAt,
arg.AccountFingerprint,
arg.Health,
arg.Tags,
arg.IfSyncVersion,
)
var i UpsertDesktopAccountRow
err := row.Scan(
&i.DesktopID,
&i.TenantID,
&i.WorkspaceID,
&i.UserID,
&i.ClientID,
&i.PlatformID,
&i.PlatformUid,
&i.AccountFingerprint,
&i.DisplayName,
&i.Health,
&i.VerifiedAt,
&i.Tags,
&i.SyncVersion,
&i.DeletedAt,
&i.DeleteRequestedAt,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
@@ -0,0 +1,287 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: desktop_client.sql
package generated
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const getDesktopClientByTokenHash = `-- name: GetDesktopClientByTokenHash :one
SELECT id, tenant_id, workspace_id, user_id, token_hash, device_name, os, cpu_arch, client_version, channel, created_at, last_seen_at, last_rotated_at, revoked_at
FROM desktop_clients
WHERE token_hash = $1
AND revoked_at IS NULL
LIMIT 1
`
func (q *Queries) GetDesktopClientByTokenHash(ctx context.Context, tokenHash []byte) (DesktopClient, error) {
row := q.db.QueryRow(ctx, getDesktopClientByTokenHash, tokenHash)
var i DesktopClient
err := row.Scan(
&i.ID,
&i.TenantID,
&i.WorkspaceID,
&i.UserID,
&i.TokenHash,
&i.DeviceName,
&i.Os,
&i.CpuArch,
&i.ClientVersion,
&i.Channel,
&i.CreatedAt,
&i.LastSeenAt,
&i.LastRotatedAt,
&i.RevokedAt,
)
return i, err
}
const heartbeatDesktopClient = `-- name: HeartbeatDesktopClient :one
UPDATE desktop_clients
SET device_name = COALESCE($1, device_name),
os = COALESCE($2, os),
cpu_arch = COALESCE($3, cpu_arch),
client_version = COALESCE($4, client_version),
channel = COALESCE($5, channel),
last_seen_at = now()
WHERE id = $6
AND workspace_id = $7
AND revoked_at IS NULL
RETURNING id, tenant_id, workspace_id, user_id, token_hash, device_name, os, cpu_arch, client_version, channel, created_at, last_seen_at, last_rotated_at, revoked_at
`
type HeartbeatDesktopClientParams struct {
DeviceName pgtype.Text `json:"device_name"`
Os pgtype.Text `json:"os"`
CpuArch pgtype.Text `json:"cpu_arch"`
ClientVersion pgtype.Text `json:"client_version"`
Channel pgtype.Text `json:"channel"`
ID pgtype.UUID `json:"id"`
WorkspaceID int64 `json:"workspace_id"`
}
func (q *Queries) HeartbeatDesktopClient(ctx context.Context, arg HeartbeatDesktopClientParams) (DesktopClient, error) {
row := q.db.QueryRow(ctx, heartbeatDesktopClient,
arg.DeviceName,
arg.Os,
arg.CpuArch,
arg.ClientVersion,
arg.Channel,
arg.ID,
arg.WorkspaceID,
)
var i DesktopClient
err := row.Scan(
&i.ID,
&i.TenantID,
&i.WorkspaceID,
&i.UserID,
&i.TokenHash,
&i.DeviceName,
&i.Os,
&i.CpuArch,
&i.ClientVersion,
&i.Channel,
&i.CreatedAt,
&i.LastSeenAt,
&i.LastRotatedAt,
&i.RevokedAt,
)
return i, err
}
const listDesktopClientsByWorkspace = `-- name: ListDesktopClientsByWorkspace :many
SELECT id, tenant_id, workspace_id, user_id, token_hash, device_name, os, cpu_arch, client_version, channel, created_at, last_seen_at, last_rotated_at, revoked_at
FROM desktop_clients
WHERE workspace_id = $1
AND revoked_at IS NULL
ORDER BY last_seen_at DESC NULLS LAST, created_at DESC
`
func (q *Queries) ListDesktopClientsByWorkspace(ctx context.Context, workspaceID int64) ([]DesktopClient, error) {
rows, err := q.db.Query(ctx, listDesktopClientsByWorkspace, workspaceID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []DesktopClient
for rows.Next() {
var i DesktopClient
if err := rows.Scan(
&i.ID,
&i.TenantID,
&i.WorkspaceID,
&i.UserID,
&i.TokenHash,
&i.DeviceName,
&i.Os,
&i.CpuArch,
&i.ClientVersion,
&i.Channel,
&i.CreatedAt,
&i.LastSeenAt,
&i.LastRotatedAt,
&i.RevokedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const registerDesktopClient = `-- 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 (
$1,
$2,
$3,
$4,
$5,
$6,
$7,
$8,
$9,
$10
)
RETURNING id, tenant_id, workspace_id, user_id, token_hash, device_name, os, cpu_arch, client_version, channel, created_at, last_seen_at, last_rotated_at, revoked_at
`
type RegisterDesktopClientParams struct {
ID pgtype.UUID `json:"id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
UserID int64 `json:"user_id"`
TokenHash []byte `json:"token_hash"`
DeviceName pgtype.Text `json:"device_name"`
Os pgtype.Text `json:"os"`
CpuArch pgtype.Text `json:"cpu_arch"`
ClientVersion pgtype.Text `json:"client_version"`
Channel pgtype.Text `json:"channel"`
}
func (q *Queries) RegisterDesktopClient(ctx context.Context, arg RegisterDesktopClientParams) (DesktopClient, error) {
row := q.db.QueryRow(ctx, registerDesktopClient,
arg.ID,
arg.TenantID,
arg.WorkspaceID,
arg.UserID,
arg.TokenHash,
arg.DeviceName,
arg.Os,
arg.CpuArch,
arg.ClientVersion,
arg.Channel,
)
var i DesktopClient
err := row.Scan(
&i.ID,
&i.TenantID,
&i.WorkspaceID,
&i.UserID,
&i.TokenHash,
&i.DeviceName,
&i.Os,
&i.CpuArch,
&i.ClientVersion,
&i.Channel,
&i.CreatedAt,
&i.LastSeenAt,
&i.LastRotatedAt,
&i.RevokedAt,
)
return i, err
}
const revokeDesktopClient = `-- name: RevokeDesktopClient :one
UPDATE desktop_clients
SET revoked_at = now()
WHERE id = $1
AND workspace_id = $2
AND revoked_at IS NULL
RETURNING id, tenant_id, workspace_id, user_id, token_hash, device_name, os, cpu_arch, client_version, channel, created_at, last_seen_at, last_rotated_at, revoked_at
`
type RevokeDesktopClientParams struct {
ID pgtype.UUID `json:"id"`
WorkspaceID int64 `json:"workspace_id"`
}
func (q *Queries) RevokeDesktopClient(ctx context.Context, arg RevokeDesktopClientParams) (DesktopClient, error) {
row := q.db.QueryRow(ctx, revokeDesktopClient, arg.ID, arg.WorkspaceID)
var i DesktopClient
err := row.Scan(
&i.ID,
&i.TenantID,
&i.WorkspaceID,
&i.UserID,
&i.TokenHash,
&i.DeviceName,
&i.Os,
&i.CpuArch,
&i.ClientVersion,
&i.Channel,
&i.CreatedAt,
&i.LastSeenAt,
&i.LastRotatedAt,
&i.RevokedAt,
)
return i, err
}
const rotateDesktopClientToken = `-- name: RotateDesktopClientToken :one
UPDATE desktop_clients
SET token_hash = $1,
last_rotated_at = now()
WHERE id = $2
AND workspace_id = $3
AND revoked_at IS NULL
RETURNING id, tenant_id, workspace_id, user_id, token_hash, device_name, os, cpu_arch, client_version, channel, created_at, last_seen_at, last_rotated_at, revoked_at
`
type RotateDesktopClientTokenParams struct {
TokenHash []byte `json:"token_hash"`
ID pgtype.UUID `json:"id"`
WorkspaceID int64 `json:"workspace_id"`
}
func (q *Queries) RotateDesktopClientToken(ctx context.Context, arg RotateDesktopClientTokenParams) (DesktopClient, error) {
row := q.db.QueryRow(ctx, rotateDesktopClientToken, arg.TokenHash, arg.ID, arg.WorkspaceID)
var i DesktopClient
err := row.Scan(
&i.ID,
&i.TenantID,
&i.WorkspaceID,
&i.UserID,
&i.TokenHash,
&i.DeviceName,
&i.Os,
&i.CpuArch,
&i.ClientVersion,
&i.Channel,
&i.CreatedAt,
&i.LastSeenAt,
&i.LastRotatedAt,
&i.RevokedAt,
)
return i, err
}
@@ -0,0 +1,850 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: desktop_task.sql
package generated
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const cancelDesktopTaskByClient = `-- name: CancelDesktopTaskByClient :one
UPDATE desktop_tasks
SET status = 'aborted',
error = $1,
active_attempt_id = NULL,
lease_token_hash = NULL,
lease_expires_at = NULL,
parked_reason = NULL,
updated_at = now()
WHERE desktop_id = $2
AND target_client_id = $3
AND status IN ('queued', 'waiting_user')
RETURNING id, desktop_id, job_id, tenant_id, workspace_id, target_account_id, target_client_id, platform_id, kind, payload, status, dedup_key, active_attempt_id, lease_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
`
type CancelDesktopTaskByClientParams struct {
Error []byte `json:"error"`
DesktopID pgtype.UUID `json:"desktop_id"`
ClientID pgtype.UUID `json:"client_id"`
}
func (q *Queries) CancelDesktopTaskByClient(ctx context.Context, arg CancelDesktopTaskByClientParams) (DesktopTask, error) {
row := q.db.QueryRow(ctx, cancelDesktopTaskByClient, arg.Error, arg.DesktopID, arg.ClientID)
var i DesktopTask
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.JobID,
&i.TenantID,
&i.WorkspaceID,
&i.TargetAccountID,
&i.TargetClientID,
&i.PlatformID,
&i.Kind,
&i.Payload,
&i.Status,
&i.DedupKey,
&i.ActiveAttemptID,
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const cancelDesktopTaskByLease = `-- name: CancelDesktopTaskByLease :one
UPDATE desktop_tasks
SET status = 'aborted',
error = $1,
active_attempt_id = NULL,
lease_token_hash = NULL,
lease_expires_at = NULL,
parked_reason = NULL,
updated_at = now()
WHERE desktop_id = $2
AND lease_token_hash = $3
AND status = 'in_progress'
RETURNING id, desktop_id, job_id, tenant_id, workspace_id, target_account_id, target_client_id, platform_id, kind, payload, status, dedup_key, active_attempt_id, lease_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
`
type CancelDesktopTaskByLeaseParams struct {
Error []byte `json:"error"`
DesktopID pgtype.UUID `json:"desktop_id"`
LeaseTokenHash []byte `json:"lease_token_hash"`
}
func (q *Queries) CancelDesktopTaskByLease(ctx context.Context, arg CancelDesktopTaskByLeaseParams) (DesktopTask, error) {
row := q.db.QueryRow(ctx, cancelDesktopTaskByLease, arg.Error, arg.DesktopID, arg.LeaseTokenHash)
var i DesktopTask
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.JobID,
&i.TenantID,
&i.WorkspaceID,
&i.TargetAccountID,
&i.TargetClientID,
&i.PlatformID,
&i.Kind,
&i.Payload,
&i.Status,
&i.DedupKey,
&i.ActiveAttemptID,
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const completeDesktopTask = `-- name: CompleteDesktopTask :one
UPDATE desktop_tasks
SET status = $1,
result = $2,
error = $3,
active_attempt_id = NULL,
lease_token_hash = NULL,
lease_expires_at = NULL,
parked_reason = NULL,
updated_at = now()
WHERE desktop_id = $4
AND lease_token_hash = $5
AND status = 'in_progress'
RETURNING id, desktop_id, job_id, tenant_id, workspace_id, target_account_id, target_client_id, platform_id, kind, payload, status, dedup_key, active_attempt_id, lease_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
`
type CompleteDesktopTaskParams struct {
Status string `json:"status"`
Result []byte `json:"result"`
Error []byte `json:"error"`
DesktopID pgtype.UUID `json:"desktop_id"`
LeaseTokenHash []byte `json:"lease_token_hash"`
}
func (q *Queries) CompleteDesktopTask(ctx context.Context, arg CompleteDesktopTaskParams) (DesktopTask, error) {
row := q.db.QueryRow(ctx, completeDesktopTask,
arg.Status,
arg.Result,
arg.Error,
arg.DesktopID,
arg.LeaseTokenHash,
)
var i DesktopTask
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.JobID,
&i.TenantID,
&i.WorkspaceID,
&i.TargetAccountID,
&i.TargetClientID,
&i.PlatformID,
&i.Kind,
&i.Payload,
&i.Status,
&i.DedupKey,
&i.ActiveAttemptID,
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const createDesktopPublishJob = `-- name: CreateDesktopPublishJob :one
INSERT INTO desktop_publish_jobs (
desktop_id,
tenant_id,
workspace_id,
created_by_user_id,
title,
content_ref,
scheduled_at
)
VALUES (
$1,
$2,
$3,
$4,
$5,
$6,
$7
)
RETURNING id, desktop_id, tenant_id, workspace_id, created_by_user_id, title, content_ref, scheduled_at, created_at, updated_at
`
type CreateDesktopPublishJobParams struct {
DesktopID pgtype.UUID `json:"desktop_id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
CreatedByUserID int64 `json:"created_by_user_id"`
Title string `json:"title"`
ContentRef []byte `json:"content_ref"`
ScheduledAt pgtype.Timestamptz `json:"scheduled_at"`
}
func (q *Queries) CreateDesktopPublishJob(ctx context.Context, arg CreateDesktopPublishJobParams) (DesktopPublishJob, error) {
row := q.db.QueryRow(ctx, createDesktopPublishJob,
arg.DesktopID,
arg.TenantID,
arg.WorkspaceID,
arg.CreatedByUserID,
arg.Title,
arg.ContentRef,
arg.ScheduledAt,
)
var i DesktopPublishJob
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.TenantID,
&i.WorkspaceID,
&i.CreatedByUserID,
&i.Title,
&i.ContentRef,
&i.ScheduledAt,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const createDesktopTask = `-- 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 (
$1,
$2,
$3,
$4,
$5,
$6,
$7,
$8,
$9,
$10,
$11,
$12
)
RETURNING id, desktop_id, job_id, tenant_id, workspace_id, target_account_id, target_client_id, platform_id, kind, payload, status, dedup_key, active_attempt_id, lease_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
`
type CreateDesktopTaskParams struct {
DesktopID pgtype.UUID `json:"desktop_id"`
JobID pgtype.UUID `json:"job_id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
TargetAccountID pgtype.UUID `json:"target_account_id"`
TargetClientID pgtype.UUID `json:"target_client_id"`
PlatformID string `json:"platform_id"`
Kind string `json:"kind"`
Payload []byte `json:"payload"`
Status string `json:"status"`
DedupKey pgtype.Text `json:"dedup_key"`
ParkedReason pgtype.Text `json:"parked_reason"`
}
func (q *Queries) CreateDesktopTask(ctx context.Context, arg CreateDesktopTaskParams) (DesktopTask, error) {
row := q.db.QueryRow(ctx, createDesktopTask,
arg.DesktopID,
arg.JobID,
arg.TenantID,
arg.WorkspaceID,
arg.TargetAccountID,
arg.TargetClientID,
arg.PlatformID,
arg.Kind,
arg.Payload,
arg.Status,
arg.DedupKey,
arg.ParkedReason,
)
var i DesktopTask
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.JobID,
&i.TenantID,
&i.WorkspaceID,
&i.TargetAccountID,
&i.TargetClientID,
&i.PlatformID,
&i.Kind,
&i.Payload,
&i.Status,
&i.DedupKey,
&i.ActiveAttemptID,
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const createDesktopTaskAttempt = `-- name: CreateDesktopTaskAttempt :one
INSERT INTO desktop_task_attempts (
desktop_id,
task_id,
client_id,
lease_token_hash
)
VALUES (
$1,
$2,
$3,
$4
)
RETURNING id, desktop_id, task_id, client_id, lease_token_hash, started_at, ended_at, final_status, error, created_at
`
type CreateDesktopTaskAttemptParams struct {
DesktopID pgtype.UUID `json:"desktop_id"`
TaskID pgtype.UUID `json:"task_id"`
ClientID pgtype.UUID `json:"client_id"`
LeaseTokenHash []byte `json:"lease_token_hash"`
}
func (q *Queries) CreateDesktopTaskAttempt(ctx context.Context, arg CreateDesktopTaskAttemptParams) (DesktopTaskAttempt, error) {
row := q.db.QueryRow(ctx, createDesktopTaskAttempt,
arg.DesktopID,
arg.TaskID,
arg.ClientID,
arg.LeaseTokenHash,
)
var i DesktopTaskAttempt
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.TaskID,
&i.ClientID,
&i.LeaseTokenHash,
&i.StartedAt,
&i.EndedAt,
&i.FinalStatus,
&i.Error,
&i.CreatedAt,
)
return i, err
}
const extendDesktopTaskLease = `-- name: ExtendDesktopTaskLease :one
UPDATE desktop_tasks
SET lease_expires_at = now() + interval '10 minutes',
updated_at = now()
WHERE desktop_id = $1
AND lease_token_hash = $2
AND status = 'in_progress'
RETURNING id, desktop_id, job_id, tenant_id, workspace_id, target_account_id, target_client_id, platform_id, kind, payload, status, dedup_key, active_attempt_id, lease_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
`
type ExtendDesktopTaskLeaseParams struct {
DesktopID pgtype.UUID `json:"desktop_id"`
LeaseTokenHash []byte `json:"lease_token_hash"`
}
func (q *Queries) ExtendDesktopTaskLease(ctx context.Context, arg ExtendDesktopTaskLeaseParams) (DesktopTask, error) {
row := q.db.QueryRow(ctx, extendDesktopTaskLease, arg.DesktopID, arg.LeaseTokenHash)
var i DesktopTask
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.JobID,
&i.TenantID,
&i.WorkspaceID,
&i.TargetAccountID,
&i.TargetClientID,
&i.PlatformID,
&i.Kind,
&i.Payload,
&i.Status,
&i.DedupKey,
&i.ActiveAttemptID,
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const finishDesktopTaskAttempt = `-- name: FinishDesktopTaskAttempt :exec
UPDATE desktop_task_attempts
SET ended_at = now(),
final_status = $1,
error = $2
WHERE task_id = $3
AND desktop_id = $4
`
type FinishDesktopTaskAttemptParams struct {
FinalStatus pgtype.Text `json:"final_status"`
Error []byte `json:"error"`
TaskID pgtype.UUID `json:"task_id"`
AttemptID pgtype.UUID `json:"attempt_id"`
}
func (q *Queries) FinishDesktopTaskAttempt(ctx context.Context, arg FinishDesktopTaskAttemptParams) error {
_, err := q.db.Exec(ctx, finishDesktopTaskAttempt,
arg.FinalStatus,
arg.Error,
arg.TaskID,
arg.AttemptID,
)
return err
}
const getDesktopTaskByDesktopID = `-- name: GetDesktopTaskByDesktopID :one
SELECT id, desktop_id, job_id, tenant_id, workspace_id, target_account_id, target_client_id, platform_id, kind, payload, status, dedup_key, active_attempt_id, lease_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
FROM desktop_tasks
WHERE desktop_id = $1
AND workspace_id = $2
LIMIT 1
`
type GetDesktopTaskByDesktopIDParams struct {
DesktopID pgtype.UUID `json:"desktop_id"`
WorkspaceID int64 `json:"workspace_id"`
}
func (q *Queries) GetDesktopTaskByDesktopID(ctx context.Context, arg GetDesktopTaskByDesktopIDParams) (DesktopTask, error) {
row := q.db.QueryRow(ctx, getDesktopTaskByDesktopID, arg.DesktopID, arg.WorkspaceID)
var i DesktopTask
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.JobID,
&i.TenantID,
&i.WorkspaceID,
&i.TargetAccountID,
&i.TargetClientID,
&i.PlatformID,
&i.Kind,
&i.Payload,
&i.Status,
&i.DedupKey,
&i.ActiveAttemptID,
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const leaseNextQueuedDesktopTask = `-- name: LeaseNextQueuedDesktopTask :one
WITH candidate AS (
SELECT dt.desktop_id
FROM desktop_tasks AS dt
WHERE dt.target_client_id = $3
AND dt.status = 'queued'
AND (
$4::text IS NULL
OR dt.kind = $4::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 = $1,
lease_token_hash = $2,
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.id, t.desktop_id, t.job_id, t.tenant_id, t.workspace_id, t.target_account_id, t.target_client_id, t.platform_id, t.kind, t.payload, t.status, t.dedup_key, t.active_attempt_id, t.lease_token_hash, t.lease_expires_at, t.attempts, t.parked_reason, t.result, t.error, t.created_at, t.updated_at
`
type LeaseNextQueuedDesktopTaskParams struct {
AttemptID pgtype.UUID `json:"attempt_id"`
LeaseTokenHash []byte `json:"lease_token_hash"`
ClientID pgtype.UUID `json:"client_id"`
Kind pgtype.Text `json:"kind"`
}
func (q *Queries) LeaseNextQueuedDesktopTask(ctx context.Context, arg LeaseNextQueuedDesktopTaskParams) (DesktopTask, error) {
row := q.db.QueryRow(ctx, leaseNextQueuedDesktopTask,
arg.AttemptID,
arg.LeaseTokenHash,
arg.ClientID,
arg.Kind,
)
var i DesktopTask
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.JobID,
&i.TenantID,
&i.WorkspaceID,
&i.TargetAccountID,
&i.TargetClientID,
&i.PlatformID,
&i.Kind,
&i.Payload,
&i.Status,
&i.DedupKey,
&i.ActiveAttemptID,
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const leaseParkedDesktopTask = `-- name: LeaseParkedDesktopTask :one
UPDATE desktop_tasks
SET active_attempt_id = $1,
lease_token_hash = $2,
lease_expires_at = now() + interval '10 minutes',
status = 'in_progress',
attempts = attempts + 1,
parked_reason = NULL,
updated_at = now()
WHERE desktop_id = $3
AND target_client_id = $4
AND status = 'waiting_user'
AND active_attempt_id IS NULL
RETURNING id, desktop_id, job_id, tenant_id, workspace_id, target_account_id, target_client_id, platform_id, kind, payload, status, dedup_key, active_attempt_id, lease_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
`
type LeaseParkedDesktopTaskParams struct {
AttemptID pgtype.UUID `json:"attempt_id"`
LeaseTokenHash []byte `json:"lease_token_hash"`
DesktopID pgtype.UUID `json:"desktop_id"`
ClientID pgtype.UUID `json:"client_id"`
}
func (q *Queries) LeaseParkedDesktopTask(ctx context.Context, arg LeaseParkedDesktopTaskParams) (DesktopTask, error) {
row := q.db.QueryRow(ctx, leaseParkedDesktopTask,
arg.AttemptID,
arg.LeaseTokenHash,
arg.DesktopID,
arg.ClientID,
)
var i DesktopTask
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.JobID,
&i.TenantID,
&i.WorkspaceID,
&i.TargetAccountID,
&i.TargetClientID,
&i.PlatformID,
&i.Kind,
&i.Payload,
&i.Status,
&i.DedupKey,
&i.ActiveAttemptID,
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const leaseQueuedDesktopTaskByDesktopID = `-- name: LeaseQueuedDesktopTaskByDesktopID :one
UPDATE desktop_tasks
SET active_attempt_id = $1,
lease_token_hash = $2,
lease_expires_at = now() + interval '10 minutes',
status = 'in_progress',
attempts = attempts + 1,
parked_reason = NULL,
updated_at = now()
WHERE desktop_id = $3
AND target_client_id = $4
AND status = 'queued'
RETURNING id, desktop_id, job_id, tenant_id, workspace_id, target_account_id, target_client_id, platform_id, kind, payload, status, dedup_key, active_attempt_id, lease_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
`
type LeaseQueuedDesktopTaskByDesktopIDParams struct {
AttemptID pgtype.UUID `json:"attempt_id"`
LeaseTokenHash []byte `json:"lease_token_hash"`
DesktopID pgtype.UUID `json:"desktop_id"`
ClientID pgtype.UUID `json:"client_id"`
}
func (q *Queries) LeaseQueuedDesktopTaskByDesktopID(ctx context.Context, arg LeaseQueuedDesktopTaskByDesktopIDParams) (DesktopTask, error) {
row := q.db.QueryRow(ctx, leaseQueuedDesktopTaskByDesktopID,
arg.AttemptID,
arg.LeaseTokenHash,
arg.DesktopID,
arg.ClientID,
)
var i DesktopTask
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.JobID,
&i.TenantID,
&i.WorkspaceID,
&i.TargetAccountID,
&i.TargetClientID,
&i.PlatformID,
&i.Kind,
&i.Payload,
&i.Status,
&i.DedupKey,
&i.ActiveAttemptID,
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const markDesktopTasksUnknownByClient = `-- name: MarkDesktopTasksUnknownByClient :execrows
UPDATE desktop_tasks
SET status = 'unknown',
error = $1,
active_attempt_id = NULL,
lease_token_hash = NULL,
lease_expires_at = NULL,
parked_reason = NULL,
updated_at = now()
WHERE target_client_id = $2
AND workspace_id = $3
AND status IN ('waiting_user', 'in_progress')
`
type MarkDesktopTasksUnknownByClientParams struct {
Error []byte `json:"error"`
ClientID pgtype.UUID `json:"client_id"`
WorkspaceID int64 `json:"workspace_id"`
}
func (q *Queries) MarkDesktopTasksUnknownByClient(ctx context.Context, arg MarkDesktopTasksUnknownByClientParams) (int64, error) {
result, err := q.db.Exec(ctx, markDesktopTasksUnknownByClient, arg.Error, arg.ClientID, arg.WorkspaceID)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const parkDesktopTask = `-- name: ParkDesktopTask :one
UPDATE desktop_tasks
SET status = 'waiting_user',
active_attempt_id = NULL,
lease_token_hash = NULL,
lease_expires_at = NULL,
parked_reason = $1,
updated_at = now()
WHERE desktop_id = $2
AND lease_token_hash = $3
AND status = 'in_progress'
RETURNING id, desktop_id, job_id, tenant_id, workspace_id, target_account_id, target_client_id, platform_id, kind, payload, status, dedup_key, active_attempt_id, lease_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
`
type ParkDesktopTaskParams struct {
ParkedReason pgtype.Text `json:"parked_reason"`
DesktopID pgtype.UUID `json:"desktop_id"`
LeaseTokenHash []byte `json:"lease_token_hash"`
}
func (q *Queries) ParkDesktopTask(ctx context.Context, arg ParkDesktopTaskParams) (DesktopTask, error) {
row := q.db.QueryRow(ctx, parkDesktopTask, arg.ParkedReason, arg.DesktopID, arg.LeaseTokenHash)
var i DesktopTask
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.JobID,
&i.TenantID,
&i.WorkspaceID,
&i.TargetAccountID,
&i.TargetClientID,
&i.PlatformID,
&i.Kind,
&i.Payload,
&i.Status,
&i.DedupKey,
&i.ActiveAttemptID,
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const reconcileDesktopTask = `-- name: ReconcileDesktopTask :one
UPDATE desktop_tasks
SET status = CASE
WHEN $1::text = 'retry' THEN 'queued'
ELSE $1::text
END,
result = CASE
WHEN $1::text = 'retry' THEN NULL
ELSE $2
END,
error = $3,
active_attempt_id = NULL,
lease_token_hash = NULL,
lease_expires_at = NULL,
parked_reason = NULL,
attempts = attempts + CASE WHEN $1::text = 'retry' THEN 1 ELSE 0 END,
updated_at = now()
WHERE desktop_id = $4
AND workspace_id = $5
AND status = 'unknown'
RETURNING id, desktop_id, job_id, tenant_id, workspace_id, target_account_id, target_client_id, platform_id, kind, payload, status, dedup_key, active_attempt_id, lease_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
`
type ReconcileDesktopTaskParams struct {
Status string `json:"status"`
Result []byte `json:"result"`
Error []byte `json:"error"`
DesktopID pgtype.UUID `json:"desktop_id"`
WorkspaceID int64 `json:"workspace_id"`
}
func (q *Queries) ReconcileDesktopTask(ctx context.Context, arg ReconcileDesktopTaskParams) (DesktopTask, error) {
row := q.db.QueryRow(ctx, reconcileDesktopTask,
arg.Status,
arg.Result,
arg.Error,
arg.DesktopID,
arg.WorkspaceID,
)
var i DesktopTask
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.JobID,
&i.TenantID,
&i.WorkspaceID,
&i.TargetAccountID,
&i.TargetClientID,
&i.PlatformID,
&i.Kind,
&i.Payload,
&i.Status,
&i.DedupKey,
&i.ActiveAttemptID,
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const tenantCancelDesktopTask = `-- name: TenantCancelDesktopTask :one
UPDATE desktop_tasks
SET status = 'aborted',
error = $1,
active_attempt_id = NULL,
lease_token_hash = NULL,
lease_expires_at = NULL,
parked_reason = NULL,
updated_at = now()
WHERE desktop_id = $2
AND workspace_id = $3
AND status IN ('queued', 'waiting_user')
RETURNING id, desktop_id, job_id, tenant_id, workspace_id, target_account_id, target_client_id, platform_id, kind, payload, status, dedup_key, active_attempt_id, lease_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
`
type TenantCancelDesktopTaskParams struct {
Error []byte `json:"error"`
DesktopID pgtype.UUID `json:"desktop_id"`
WorkspaceID int64 `json:"workspace_id"`
}
func (q *Queries) TenantCancelDesktopTask(ctx context.Context, arg TenantCancelDesktopTaskParams) (DesktopTask, error) {
row := q.db.QueryRow(ctx, tenantCancelDesktopTask, arg.Error, arg.DesktopID, arg.WorkspaceID)
var i DesktopTask
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.JobID,
&i.TenantID,
&i.WorkspaceID,
&i.TargetAccountID,
&i.TargetClientID,
&i.PlatformID,
&i.Kind,
&i.Payload,
&i.Status,
&i.DedupKey,
&i.ActiveAttemptID,
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
@@ -119,6 +119,81 @@ type Competitor struct {
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
}
type DesktopClient struct {
ID pgtype.UUID `json:"id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
UserID int64 `json:"user_id"`
TokenHash []byte `json:"token_hash"`
DeviceName pgtype.Text `json:"device_name"`
Os pgtype.Text `json:"os"`
CpuArch pgtype.Text `json:"cpu_arch"`
ClientVersion pgtype.Text `json:"client_version"`
Channel pgtype.Text `json:"channel"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
LastSeenAt pgtype.Timestamptz `json:"last_seen_at"`
LastRotatedAt pgtype.Timestamptz `json:"last_rotated_at"`
RevokedAt pgtype.Timestamptz `json:"revoked_at"`
}
type DesktopPublishJob struct {
ID int64 `json:"id"`
DesktopID pgtype.UUID `json:"desktop_id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
CreatedByUserID int64 `json:"created_by_user_id"`
Title string `json:"title"`
ContentRef []byte `json:"content_ref"`
ScheduledAt pgtype.Timestamptz `json:"scheduled_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
type DesktopTask struct {
ID int64 `json:"id"`
DesktopID pgtype.UUID `json:"desktop_id"`
JobID pgtype.UUID `json:"job_id"`
TenantID int64 `json:"tenant_id"`
WorkspaceID int64 `json:"workspace_id"`
TargetAccountID pgtype.UUID `json:"target_account_id"`
TargetClientID pgtype.UUID `json:"target_client_id"`
PlatformID string `json:"platform_id"`
Kind string `json:"kind"`
Payload []byte `json:"payload"`
Status string `json:"status"`
DedupKey pgtype.Text `json:"dedup_key"`
ActiveAttemptID pgtype.UUID `json:"active_attempt_id"`
LeaseTokenHash []byte `json:"lease_token_hash"`
LeaseExpiresAt pgtype.Timestamptz `json:"lease_expires_at"`
Attempts int32 `json:"attempts"`
ParkedReason pgtype.Text `json:"parked_reason"`
Result []byte `json:"result"`
Error []byte `json:"error"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
type DesktopTaskAttempt struct {
ID int64 `json:"id"`
DesktopID pgtype.UUID `json:"desktop_id"`
TaskID pgtype.UUID `json:"task_id"`
ClientID pgtype.UUID `json:"client_id"`
LeaseTokenHash []byte `json:"lease_token_hash"`
StartedAt pgtype.Timestamptz `json:"started_at"`
EndedAt pgtype.Timestamptz `json:"ended_at"`
FinalStatus pgtype.Text `json:"final_status"`
Error []byte `json:"error"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
}
type DesktopTaskTrace struct {
TaskID pgtype.UUID `json:"task_id"`
AttemptID pgtype.UUID `json:"attempt_id"`
Size pgtype.Int8 `json:"size"`
UploadedAt pgtype.Timestamptz `json:"uploaded_at"`
ObjectKey pgtype.Text `json:"object_key"`
}
type GenerationTask struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
@@ -376,19 +451,29 @@ type Plan struct {
}
type PlatformAccount struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
UserID int64 `json:"user_id"`
PlatformID string `json:"platform_id"`
PlatformUid string `json:"platform_uid"`
Nickname string `json:"nickname"`
AvatarUrl pgtype.Text `json:"avatar_url"`
Status string `json:"status"`
MetadataJson []byte `json:"metadata_json"`
LastCheckAt pgtype.Timestamptz `json:"last_check_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
UserID int64 `json:"user_id"`
PlatformID string `json:"platform_id"`
PlatformUid string `json:"platform_uid"`
Nickname string `json:"nickname"`
AvatarUrl pgtype.Text `json:"avatar_url"`
Status string `json:"status"`
MetadataJson []byte `json:"metadata_json"`
LastCheckAt pgtype.Timestamptz `json:"last_check_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
WorkspaceID int64 `json:"workspace_id"`
DesktopID pgtype.UUID `json:"desktop_id"`
ClientID pgtype.UUID `json:"client_id"`
AccountFingerprint pgtype.Text `json:"account_fingerprint"`
DisplayName string `json:"display_name"`
Health string `json:"health"`
VerifiedAt pgtype.Timestamptz `json:"verified_at"`
Tags []byte `json:"tags"`
SyncVersion int64 `json:"sync_version"`
DeleteRequestedAt pgtype.Timestamptz `json:"delete_requested_at"`
}
type PlatformUserRole struct {
@@ -602,6 +687,7 @@ type TenantMonitoringQuota struct {
PlanTier string `json:"plan_tier"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
WorkspaceID int64 `json:"workspace_id"`
}
type TenantPlanSubscription struct {
@@ -641,3 +727,23 @@ type User struct {
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
}
type Workspace struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
Name string `json:"name"`
Slug string `json:"slug"`
IsDefault bool `json:"is_default"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
type WorkspaceMembership struct {
ID int64 `json:"id"`
WorkspaceID int64 `json:"workspace_id"`
UserID int64 `json:"user_id"`
TenantID int64 `json:"tenant_id"`
Role string `json:"role"`
IsPrimary bool `json:"is_primary"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
}
@@ -10,6 +10,10 @@ import (
type Querier interface {
ApproveKolSubscription(ctx context.Context, arg ApproveKolSubscriptionParams) error
CancelDesktopTaskByClient(ctx context.Context, arg CancelDesktopTaskByClientParams) (DesktopTask, error)
CancelDesktopTaskByLease(ctx context.Context, arg CancelDesktopTaskByLeaseParams) (DesktopTask, error)
ClearDesktopAccountDeleteRequested(ctx context.Context, arg ClearDesktopAccountDeleteRequestedParams) (ClearDesktopAccountDeleteRequestedRow, error)
CompleteDesktopTask(ctx context.Context, arg CompleteDesktopTaskParams) (DesktopTask, error)
ConfirmReservation(ctx context.Context, arg ConfirmReservationParams) error
CountActiveImagesInFolder(ctx context.Context, arg CountActiveImagesInFolderParams) (int32, error)
CountArticles(ctx context.Context, arg CountArticlesParams) (int64, error)
@@ -27,6 +31,9 @@ type Querier interface {
CreateAuditLog(ctx context.Context, arg CreateAuditLogParams) error
CreateBrand(ctx context.Context, arg CreateBrandParams) (CreateBrandRow, error)
CreateCompetitor(ctx context.Context, arg CreateCompetitorParams) (CreateCompetitorRow, error)
CreateDesktopPublishJob(ctx context.Context, arg CreateDesktopPublishJobParams) (DesktopPublishJob, error)
CreateDesktopTask(ctx context.Context, arg CreateDesktopTaskParams) (DesktopTask, error)
CreateDesktopTaskAttempt(ctx context.Context, arg CreateDesktopTaskAttemptParams) (DesktopTaskAttempt, error)
CreateGenerationTask(ctx context.Context, arg CreateGenerationTaskParams) (int64, error)
CreateImageFolder(ctx context.Context, arg CreateImageFolderParams) (int64, error)
CreateKeyword(ctx context.Context, arg CreateKeywordParams) (CreateKeywordRow, error)
@@ -47,12 +54,18 @@ type Querier interface {
DeleteImageReferencesByArticle(ctx context.Context, arg DeleteImageReferencesByArticleParams) error
DeleteImageReferencesByArticleScope(ctx context.Context, arg DeleteImageReferencesByArticleScopeParams) error
EnsureImageStorageUsageRow(ctx context.Context, tenantID int64) error
ExtendDesktopTaskLease(ctx context.Context, arg ExtendDesktopTaskLeaseParams) (DesktopTask, error)
FinishDesktopTaskAttempt(ctx context.Context, arg FinishDesktopTaskAttemptParams) error
GetActiveKolSubscription(ctx context.Context, arg GetActiveKolSubscriptionParams) (KolSubscription, error)
GetActivePlanForTenant(ctx context.Context, tenantID int64) (GetActivePlanForTenantRow, error)
GetArticleByID(ctx context.Context, arg GetArticleByIDParams) (GetArticleByIDRow, error)
GetArticleVersions(ctx context.Context, articleID int64) ([]GetArticleVersionsRow, error)
GetBrandByID(ctx context.Context, arg GetBrandByIDParams) (GetBrandByIDRow, error)
GetCurrentBalance(ctx context.Context, arg GetCurrentBalanceParams) (int32, error)
GetDesktopAccountByDesktopID(ctx context.Context, arg GetDesktopAccountByDesktopIDParams) (GetDesktopAccountByDesktopIDRow, error)
GetDesktopAccountByIdentity(ctx context.Context, arg GetDesktopAccountByIdentityParams) (GetDesktopAccountByIdentityRow, error)
GetDesktopClientByTokenHash(ctx context.Context, tokenHash []byte) (DesktopClient, error)
GetDesktopTaskByDesktopID(ctx context.Context, arg GetDesktopTaskByDesktopIDParams) (DesktopTask, error)
GetImageAsset(ctx context.Context, arg GetImageAssetParams) (GetImageAssetRow, error)
GetImageFolder(ctx context.Context, arg GetImageFolderParams) (GetImageFolderRow, error)
GetImageStorageUsage(ctx context.Context, tenantID int64) (GetImageStorageUsageRow, error)
@@ -78,6 +91,7 @@ type Querier interface {
GetTenantMembershipByTenantAndUser(ctx context.Context, arg GetTenantMembershipByTenantAndUserParams) (GetTenantMembershipByTenantAndUserRow, error)
GetUserByEmail(ctx context.Context, email string) (GetUserByEmailRow, error)
GetUserByID(ctx context.Context, id int64) (GetUserByIDRow, error)
HeartbeatDesktopClient(ctx context.Context, arg HeartbeatDesktopClientParams) (DesktopClient, error)
InsertImageAsset(ctx context.Context, arg InsertImageAssetParams) (int64, error)
InsertQuotaLedger(ctx context.Context, arg InsertQuotaLedgerParams) (int64, error)
// Cross-tenant aggregation: KOL owns packages across subscriber tenants.
@@ -86,6 +100,9 @@ type Querier interface {
KolDashboardTrend(ctx context.Context, arg KolDashboardTrendParams) ([]KolDashboardTrendRow, error)
// Cross-tenant aggregation for KOL dashboard.
KolUsageCountByPackage(ctx context.Context, packageIds []int64) ([]KolUsageCountByPackageRow, error)
LeaseNextQueuedDesktopTask(ctx context.Context, arg LeaseNextQueuedDesktopTaskParams) (DesktopTask, error)
LeaseParkedDesktopTask(ctx context.Context, arg LeaseParkedDesktopTaskParams) (DesktopTask, error)
LeaseQueuedDesktopTaskByDesktopID(ctx context.Context, arg LeaseQueuedDesktopTaskByDesktopIDParams) (DesktopTask, error)
ListActiveImagesByFolder(ctx context.Context, arg ListActiveImagesByFolderParams) ([]ListActiveImagesByFolderRow, error)
ListActiveKolPromptsByPackage(ctx context.Context, arg ListActiveKolPromptsByPackageParams) ([]ListActiveKolPromptsByPackageRow, error)
// Cross-tenant read: used by platform admin for subscription fan-out.
@@ -95,6 +112,8 @@ type Querier interface {
ListArticles(ctx context.Context, arg ListArticlesParams) ([]ListArticlesRow, error)
ListBrands(ctx context.Context, tenantID int64) ([]ListBrandsRow, error)
ListCompetitors(ctx context.Context, arg ListCompetitorsParams) ([]ListCompetitorsRow, error)
ListDesktopAccountsByClient(ctx context.Context, arg ListDesktopAccountsByClientParams) ([]ListDesktopAccountsByClientRow, error)
ListDesktopClientsByWorkspace(ctx context.Context, workspaceID int64) ([]DesktopClient, error)
ListImageAssets(ctx context.Context, arg ListImageAssetsParams) ([]ListImageAssetsRow, error)
ListImageFolders(ctx context.Context, tenantID int64) ([]ListImageFoldersRow, error)
ListImageReferenceArticles(ctx context.Context, arg ListImageReferenceArticlesParams) ([]ListImageReferenceArticlesRow, error)
@@ -122,6 +141,8 @@ type Querier interface {
ListScheduleTasks(ctx context.Context, arg ListScheduleTasksParams) ([]ListScheduleTasksRow, error)
ListSubscriptionPromptsByTenant(ctx context.Context, tenantID int64) ([]ListSubscriptionPromptsByTenantRow, error)
ListTemplates(ctx context.Context, tenantID int64) ([]ListTemplatesRow, error)
MarkDesktopAccountDeleteRequested(ctx context.Context, arg MarkDesktopAccountDeleteRequestedParams) (MarkDesktopAccountDeleteRequestedRow, error)
MarkDesktopTasksUnknownByClient(ctx context.Context, arg MarkDesktopTasksUnknownByClientParams) (int64, error)
MarkImagesInFolderPendingDelete(ctx context.Context, arg MarkImagesInFolderPendingDeleteParams) error
MarkKolAssistCompleted(ctx context.Context, arg MarkKolAssistCompletedParams) error
MarkKolAssistFailed(ctx context.Context, arg MarkKolAssistFailedParams) error
@@ -131,11 +152,17 @@ type Querier interface {
MarkKolUsageFailed(ctx context.Context, arg MarkKolUsageFailedParams) error
MarkKolUsageFailedByTask(ctx context.Context, arg MarkKolUsageFailedByTaskParams) error
NextKolPromptRevisionNo(ctx context.Context, arg NextKolPromptRevisionNoParams) (int32, error)
ParkDesktopTask(ctx context.Context, arg ParkDesktopTaskParams) (DesktopTask, error)
PatchDesktopAccount(ctx context.Context, arg PatchDesktopAccountParams) (PatchDesktopAccountRow, error)
ReconcileDesktopTask(ctx context.Context, arg ReconcileDesktopTaskParams) (DesktopTask, error)
RefundReservation(ctx context.Context, arg RefundReservationParams) error
RegisterDesktopClient(ctx context.Context, arg RegisterDesktopClientParams) (DesktopClient, error)
ReleaseImageStorageQuota(ctx context.Context, arg ReleaseImageStorageQuotaParams) error
RevokeDesktopClient(ctx context.Context, arg RevokeDesktopClientParams) (DesktopClient, error)
RevokeKolSubscription(ctx context.Context, arg RevokeKolSubscriptionParams) error
RevokeSubscriptionPromptsByPrompt(ctx context.Context, arg RevokeSubscriptionPromptsByPromptParams) error
RevokeSubscriptionPromptsBySubscription(ctx context.Context, arg RevokeSubscriptionPromptsBySubscriptionParams) error
RotateDesktopClientToken(ctx context.Context, arg RotateDesktopClientTokenParams) (DesktopClient, error)
SoftDeleteArticle(ctx context.Context, arg SoftDeleteArticleParams) error
SoftDeleteBrand(ctx context.Context, arg SoftDeleteBrandParams) error
SoftDeleteCompetitor(ctx context.Context, arg SoftDeleteCompetitorParams) error
@@ -149,6 +176,8 @@ type Querier interface {
SoftDeleteQuestion(ctx context.Context, arg SoftDeleteQuestionParams) error
SoftDeleteQuestionsByBrand(ctx context.Context, arg SoftDeleteQuestionsByBrandParams) error
SoftDeleteScheduleTask(ctx context.Context, arg SoftDeleteScheduleTaskParams) error
TenantCancelDesktopTask(ctx context.Context, arg TenantCancelDesktopTaskParams) (DesktopTask, error)
TombstoneDesktopAccount(ctx context.Context, arg TombstoneDesktopAccountParams) (TombstoneDesktopAccountRow, error)
UpdateArticleCurrentVersion(ctx context.Context, arg UpdateArticleCurrentVersionParams) error
UpdateArticleGenerateStatus(ctx context.Context, arg UpdateArticleGenerateStatusParams) error
UpdateBrand(ctx context.Context, arg UpdateBrandParams) error
@@ -175,6 +204,7 @@ type Querier interface {
UpdateScheduleTask(ctx context.Context, arg UpdateScheduleTaskParams) error
UpdateScheduleTaskStatus(ctx context.Context, arg UpdateScheduleTaskStatusParams) error
UpdateTaskRecordStatus(ctx context.Context, arg UpdateTaskRecordStatusParams) error
UpsertDesktopAccount(ctx context.Context, arg UpsertDesktopAccountParams) (UpsertDesktopAccountRow, error)
UpsertImageReference(ctx context.Context, arg UpsertImageReferenceParams) error
}