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:
@@ -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"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user