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 Priority int Lane string LaneWeight int Source string SchedulerGroupKey *string MonitorTaskID *int64 SupersedesTaskID *uuid.UUID ControlFlags []byte InterruptGeneration int DedupKey *string ActiveAttemptID *uuid.UUID LeaseExpiresAt *time.Time Attempts int Result []byte Error []byte StartedAt *time.Time InterruptedAt *time.Time InterruptReason *string EnqueuedAt time.Time 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, Priority: int(row.Priority), Lane: row.Lane, LaneWeight: int(row.LaneWeight), Source: row.Source, SchedulerGroupKey: nullableText(row.SchedulerGroupKey), MonitorTaskID: nullableInt64(row.MonitorTaskID), SupersedesTaskID: nullableUUID(row.SupersedesTaskID), ControlFlags: row.ControlFlags, InterruptGeneration: int(row.InterruptGeneration), DedupKey: nullableText(row.DedupKey), ActiveAttemptID: nullableUUID(row.ActiveAttemptID), LeaseExpiresAt: optionalTime(row.LeaseExpiresAt), Attempts: int(row.Attempts), Result: row.Result, Error: row.Error, StartedAt: optionalTime(row.StartedAt), InterruptedAt: optionalTime(row.InterruptedAt), InterruptReason: nullableText(row.InterruptReason), EnqueuedAt: timeFromTimestamp(row.EnqueuedAt), 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), } }