Files
geo/server/internal/tenant/repository/desktop_task_repo.go
T
root a617d39a4a feat(desktop): drop parked review flow, add publish management
SaaS 侧人工审核后才创建 publish job,desktop 不再做二次审核:移除
manual/waiting_user/parked/from_parked 状态机与 LeaseFromParked 查询,
desktop client 只执行发布并新增"发布管理"页(待发布队列 / 历史 / 再次
发送)。同时抽离 @geo/publisher-platforms 共享适配器包、新增 Redis-based
desktop_presence 与 publish_record_support,刷新 admin-web 发布弹窗与
媒体库;plan A / spec 文档同步口径。
2026-04-20 09:52:48 +08:00

351 lines
12 KiB
Go

package repository
import (
"context"
"time"
"github.com/google/uuid"
"github.com/geo-platform/tenant-api/internal/tenant/repository/generated"
)
type DesktopPublishJob struct {
DesktopID uuid.UUID
TenantID int64
WorkspaceID int64
CreatedByUserID int64
Title string
ContentRef []byte
ScheduledAt *time.Time
CreatedAt time.Time
UpdatedAt time.Time
}
type CreateDesktopPublishJobParams struct {
DesktopID uuid.UUID
TenantID int64
WorkspaceID int64
CreatedByUserID int64
Title string
ContentRef []byte
ScheduledAt *time.Time
}
type DesktopTask struct {
DesktopID uuid.UUID
JobID uuid.UUID
TenantID int64
WorkspaceID int64
TargetAccountID uuid.UUID
TargetClientID uuid.UUID
Platform string
Kind string
Payload []byte
Status string
DedupKey *string
ActiveAttemptID *uuid.UUID
LeaseExpiresAt *time.Time
Attempts int
Result []byte
Error []byte
CreatedAt time.Time
UpdatedAt time.Time
}
type CreateDesktopTaskParams struct {
DesktopID uuid.UUID
JobID uuid.UUID
TenantID int64
WorkspaceID int64
TargetAccountID uuid.UUID
TargetClientID uuid.UUID
Platform string
Kind string
Payload []byte
Status string
DedupKey *string
}
type DesktopTaskLeaseParams struct {
AttemptID uuid.UUID
LeaseTokenHash []byte
}
type DesktopTaskAttempt struct {
DesktopID uuid.UUID
TaskID uuid.UUID
ClientID uuid.UUID
StartedAt time.Time
EndedAt *time.Time
FinalStatus *string
Error []byte
CreatedAt time.Time
}
type CreateDesktopTaskAttemptParams struct {
DesktopID uuid.UUID
TaskID uuid.UUID
ClientID uuid.UUID
LeaseTokenHash []byte
}
type FinishDesktopTaskAttemptParams struct {
TaskID uuid.UUID
AttemptID uuid.UUID
FinalStatus *string
Error []byte
}
type DesktopTaskRepository interface {
CreatePublishJob(ctx context.Context, params CreateDesktopPublishJobParams) (*DesktopPublishJob, error)
CreateTask(ctx context.Context, params CreateDesktopTaskParams) (*DesktopTask, error)
GetByDesktopID(ctx context.Context, desktopID uuid.UUID, workspaceID int64) (*DesktopTask, error)
LeaseNextQueued(ctx context.Context, clientID uuid.UUID, kind *string, params DesktopTaskLeaseParams) (*DesktopTask, error)
LeaseQueuedByDesktopID(ctx context.Context, desktopID, clientID uuid.UUID, params DesktopTaskLeaseParams) (*DesktopTask, error)
ExtendLease(ctx context.Context, desktopID uuid.UUID, leaseTokenHash []byte) (*DesktopTask, error)
Complete(ctx context.Context, desktopID uuid.UUID, leaseTokenHash []byte, status string, resultJSON, errorJSON []byte) (*DesktopTask, error)
CancelByLease(ctx context.Context, desktopID uuid.UUID, leaseTokenHash []byte, errorJSON []byte) (*DesktopTask, error)
CancelByClient(ctx context.Context, desktopID, clientID uuid.UUID, errorJSON []byte) (*DesktopTask, error)
TenantCancel(ctx context.Context, desktopID uuid.UUID, workspaceID int64, errorJSON []byte) (*DesktopTask, error)
Reconcile(ctx context.Context, desktopID uuid.UUID, workspaceID int64, status string, resultJSON, errorJSON []byte) (*DesktopTask, error)
MarkUnknownByClient(ctx context.Context, clientID uuid.UUID, workspaceID int64, errorJSON []byte) (int64, error)
CreateAttempt(ctx context.Context, params CreateDesktopTaskAttemptParams) (*DesktopTaskAttempt, error)
FinishAttempt(ctx context.Context, params FinishDesktopTaskAttemptParams) error
}
type desktopTaskRepository struct {
q generated.Querier
}
func NewDesktopTaskRepository(db generated.DBTX) DesktopTaskRepository {
return &desktopTaskRepository{q: newQuerier(db)}
}
func (r *desktopTaskRepository) CreatePublishJob(ctx context.Context, params CreateDesktopPublishJobParams) (*DesktopPublishJob, error) {
row, err := r.q.CreateDesktopPublishJob(ctx, generated.CreateDesktopPublishJobParams{
DesktopID: pgUUID(params.DesktopID),
TenantID: params.TenantID,
WorkspaceID: params.WorkspaceID,
CreatedByUserID: params.CreatedByUserID,
Title: params.Title,
ContentRef: params.ContentRef,
ScheduledAt: pgTimestamp(params.ScheduledAt),
})
if err != nil {
return nil, err
}
return desktopPublishJobFromGenerated(row), nil
}
func (r *desktopTaskRepository) CreateTask(ctx context.Context, params CreateDesktopTaskParams) (*DesktopTask, error) {
row, err := r.q.CreateDesktopTask(ctx, generated.CreateDesktopTaskParams{
DesktopID: pgUUID(params.DesktopID),
JobID: pgUUID(params.JobID),
TenantID: params.TenantID,
WorkspaceID: params.WorkspaceID,
TargetAccountID: pgUUID(params.TargetAccountID),
TargetClientID: pgUUID(params.TargetClientID),
PlatformID: params.Platform,
Kind: params.Kind,
Payload: params.Payload,
Status: params.Status,
DedupKey: pgText(params.DedupKey),
})
if err != nil {
return nil, err
}
return desktopTaskFromGenerated(row), nil
}
func (r *desktopTaskRepository) GetByDesktopID(ctx context.Context, desktopID uuid.UUID, workspaceID int64) (*DesktopTask, error) {
row, err := r.q.GetDesktopTaskByDesktopID(ctx, generated.GetDesktopTaskByDesktopIDParams{
DesktopID: pgUUID(desktopID),
WorkspaceID: workspaceID,
})
if err != nil {
return nil, err
}
return desktopTaskFromGenerated(row), nil
}
func (r *desktopTaskRepository) LeaseNextQueued(ctx context.Context, clientID uuid.UUID, kind *string, params DesktopTaskLeaseParams) (*DesktopTask, error) {
row, err := r.q.LeaseNextQueuedDesktopTask(ctx, generated.LeaseNextQueuedDesktopTaskParams{
AttemptID: pgUUID(params.AttemptID),
LeaseTokenHash: params.LeaseTokenHash,
ClientID: pgUUID(clientID),
Kind: pgText(kind),
})
if err != nil {
return nil, err
}
return desktopTaskFromGenerated(row), nil
}
func (r *desktopTaskRepository) LeaseQueuedByDesktopID(ctx context.Context, desktopID, clientID uuid.UUID, params DesktopTaskLeaseParams) (*DesktopTask, error) {
row, err := r.q.LeaseQueuedDesktopTaskByDesktopID(ctx, generated.LeaseQueuedDesktopTaskByDesktopIDParams{
AttemptID: pgUUID(params.AttemptID),
LeaseTokenHash: params.LeaseTokenHash,
DesktopID: pgUUID(desktopID),
ClientID: pgUUID(clientID),
})
if err != nil {
return nil, err
}
return desktopTaskFromGenerated(row), nil
}
func (r *desktopTaskRepository) ExtendLease(ctx context.Context, desktopID uuid.UUID, leaseTokenHash []byte) (*DesktopTask, error) {
row, err := r.q.ExtendDesktopTaskLease(ctx, generated.ExtendDesktopTaskLeaseParams{
DesktopID: pgUUID(desktopID),
LeaseTokenHash: leaseTokenHash,
})
if err != nil {
return nil, err
}
return desktopTaskFromGenerated(row), nil
}
func (r *desktopTaskRepository) Complete(ctx context.Context, desktopID uuid.UUID, leaseTokenHash []byte, status string, resultJSON, errorJSON []byte) (*DesktopTask, error) {
row, err := r.q.CompleteDesktopTask(ctx, generated.CompleteDesktopTaskParams{
Status: status,
Result: resultJSON,
Error: errorJSON,
DesktopID: pgUUID(desktopID),
LeaseTokenHash: leaseTokenHash,
})
if err != nil {
return nil, err
}
return desktopTaskFromGenerated(row), nil
}
func (r *desktopTaskRepository) CancelByLease(ctx context.Context, desktopID uuid.UUID, leaseTokenHash []byte, errorJSON []byte) (*DesktopTask, error) {
row, err := r.q.CancelDesktopTaskByLease(ctx, generated.CancelDesktopTaskByLeaseParams{
Error: errorJSON,
DesktopID: pgUUID(desktopID),
LeaseTokenHash: leaseTokenHash,
})
if err != nil {
return nil, err
}
return desktopTaskFromGenerated(row), nil
}
func (r *desktopTaskRepository) CancelByClient(ctx context.Context, desktopID, clientID uuid.UUID, errorJSON []byte) (*DesktopTask, error) {
row, err := r.q.CancelDesktopTaskByClient(ctx, generated.CancelDesktopTaskByClientParams{
Error: errorJSON,
DesktopID: pgUUID(desktopID),
ClientID: pgUUID(clientID),
})
if err != nil {
return nil, err
}
return desktopTaskFromGenerated(row), nil
}
func (r *desktopTaskRepository) TenantCancel(ctx context.Context, desktopID uuid.UUID, workspaceID int64, errorJSON []byte) (*DesktopTask, error) {
row, err := r.q.TenantCancelDesktopTask(ctx, generated.TenantCancelDesktopTaskParams{
Error: errorJSON,
DesktopID: pgUUID(desktopID),
WorkspaceID: workspaceID,
})
if err != nil {
return nil, err
}
return desktopTaskFromGenerated(row), nil
}
func (r *desktopTaskRepository) Reconcile(ctx context.Context, desktopID uuid.UUID, workspaceID int64, status string, resultJSON, errorJSON []byte) (*DesktopTask, error) {
row, err := r.q.ReconcileDesktopTask(ctx, generated.ReconcileDesktopTaskParams{
Status: status,
Result: resultJSON,
Error: errorJSON,
DesktopID: pgUUID(desktopID),
WorkspaceID: workspaceID,
})
if err != nil {
return nil, err
}
return desktopTaskFromGenerated(row), nil
}
func (r *desktopTaskRepository) MarkUnknownByClient(ctx context.Context, clientID uuid.UUID, workspaceID int64, errorJSON []byte) (int64, error) {
return r.q.MarkDesktopTasksUnknownByClient(ctx, generated.MarkDesktopTasksUnknownByClientParams{
Error: errorJSON,
ClientID: pgUUID(clientID),
WorkspaceID: workspaceID,
})
}
func (r *desktopTaskRepository) CreateAttempt(ctx context.Context, params CreateDesktopTaskAttemptParams) (*DesktopTaskAttempt, error) {
row, err := r.q.CreateDesktopTaskAttempt(ctx, generated.CreateDesktopTaskAttemptParams{
DesktopID: pgUUID(params.DesktopID),
TaskID: pgUUID(params.TaskID),
ClientID: pgUUID(params.ClientID),
LeaseTokenHash: params.LeaseTokenHash,
})
if err != nil {
return nil, err
}
return desktopTaskAttemptFromGenerated(row), nil
}
func (r *desktopTaskRepository) FinishAttempt(ctx context.Context, params FinishDesktopTaskAttemptParams) error {
return r.q.FinishDesktopTaskAttempt(ctx, generated.FinishDesktopTaskAttemptParams{
FinalStatus: pgText(params.FinalStatus),
Error: params.Error,
TaskID: pgUUID(params.TaskID),
AttemptID: pgUUID(params.AttemptID),
})
}
func desktopPublishJobFromGenerated(row generated.DesktopPublishJob) *DesktopPublishJob {
return &DesktopPublishJob{
DesktopID: uuidFromPG(row.DesktopID),
TenantID: row.TenantID,
WorkspaceID: row.WorkspaceID,
CreatedByUserID: row.CreatedByUserID,
Title: row.Title,
ContentRef: row.ContentRef,
ScheduledAt: optionalTime(row.ScheduledAt),
CreatedAt: timeFromTimestamp(row.CreatedAt),
UpdatedAt: timeFromTimestamp(row.UpdatedAt),
}
}
func desktopTaskFromGenerated(row generated.DesktopTask) *DesktopTask {
return &DesktopTask{
DesktopID: uuidFromPG(row.DesktopID),
JobID: uuidFromPG(row.JobID),
TenantID: row.TenantID,
WorkspaceID: row.WorkspaceID,
TargetAccountID: uuidFromPG(row.TargetAccountID),
TargetClientID: uuidFromPG(row.TargetClientID),
Platform: row.PlatformID,
Kind: row.Kind,
Payload: row.Payload,
Status: row.Status,
DedupKey: nullableText(row.DedupKey),
ActiveAttemptID: nullableUUID(row.ActiveAttemptID),
LeaseExpiresAt: optionalTime(row.LeaseExpiresAt),
Attempts: int(row.Attempts),
Result: row.Result,
Error: row.Error,
CreatedAt: timeFromTimestamp(row.CreatedAt),
UpdatedAt: timeFromTimestamp(row.UpdatedAt),
}
}
func desktopTaskAttemptFromGenerated(row generated.DesktopTaskAttempt) *DesktopTaskAttempt {
return &DesktopTaskAttempt{
DesktopID: uuidFromPG(row.DesktopID),
TaskID: uuidFromPG(row.TaskID),
ClientID: uuidFromPG(row.ClientID),
StartedAt: timeFromTimestamp(row.StartedAt),
EndedAt: optionalTime(row.EndedAt),
FinalStatus: nullableText(row.FinalStatus),
Error: row.Error,
CreatedAt: timeFromTimestamp(row.CreatedAt),
}
}