feat(media-supply): add media resource supply marketplace
Desktop Client Build / Resolve Build Metadata (push) Successful in 43s
Frontend CI / Frontend (push) Successful in 3m49s
Backend CI / Backend (push) Failing after 7m10s
Desktop Client Build / Build Desktop Client (push) Successful in 23m4s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 28s
Desktop Client Build / Resolve Build Metadata (push) Successful in 43s
Frontend CI / Frontend (push) Successful in 3m49s
Backend CI / Backend (push) Failing after 7m10s
Desktop Client Build / Build Desktop Client (push) Successful in 23m4s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 28s
Introduce an end-to-end media-supply feature: tenant-side resource sync service/worker backed by a Meijiequan supplier client, ops-side management APIs, and admin/ops web views for resources, orders, favorites and submission. Adds a shared digitocr helper, MediaSupply config blocks for tenant and ops, shared types, and migrations for supplier media resources, price overrides, customer visibility and order refunds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -89,6 +89,7 @@ type CreatePublishJobResponse struct {
|
||||
TaskIDs []string `json:"task_ids"`
|
||||
CreatedTaskIDs []string `json:"created_task_ids"`
|
||||
ExistingTaskIDs []string `json:"existing_task_ids"`
|
||||
RequeuedTaskIDs []string `json:"requeued_task_ids,omitempty"`
|
||||
}
|
||||
|
||||
type publishTarget struct {
|
||||
@@ -668,6 +669,9 @@ func (s *PublishJobService) RetryByDesktopTask(
|
||||
if task.Status == "queued" || task.Status == "in_progress" {
|
||||
return nil, response.ErrConflict(40994, "desktop_task_retry_conflict", "desktop task is still pending or running")
|
||||
}
|
||||
if shouldRequeuePublishTaskInsteadOfCreatingNew(task) {
|
||||
return s.requeueUnknownPublishTask(ctx, task)
|
||||
}
|
||||
|
||||
payload := unmarshalJSONObject(task.Payload)
|
||||
articleID, err := s.resolveRetryArticleID(ctx, client.TenantID, payload)
|
||||
@@ -730,6 +734,9 @@ func (s *PublishJobService) RetryTenantDesktopTask(
|
||||
if task.Status == "queued" || task.Status == "in_progress" {
|
||||
return nil, response.ErrConflict(40994, "desktop_task_retry_conflict", "desktop task is still pending or running")
|
||||
}
|
||||
if shouldRequeuePublishTaskInsteadOfCreatingNew(task) {
|
||||
return s.requeueUnknownPublishTask(ctx, task)
|
||||
}
|
||||
|
||||
payload := unmarshalJSONObject(task.Payload)
|
||||
articleID, err := s.resolveRetryArticleID(ctx, actor.TenantID, payload)
|
||||
@@ -758,6 +765,59 @@ func (s *PublishJobService) RetryTenantDesktopTask(
|
||||
})
|
||||
}
|
||||
|
||||
func shouldRequeuePublishTaskInsteadOfCreatingNew(task *repository.DesktopTask) bool {
|
||||
return task != nil && task.Kind == "publish" && task.Status == "unknown"
|
||||
}
|
||||
|
||||
func (s *PublishJobService) requeueUnknownPublishTask(
|
||||
ctx context.Context,
|
||||
task *repository.DesktopTask,
|
||||
) (*CreatePublishJobResponse, error) {
|
||||
if task == nil {
|
||||
return nil, response.ErrNotFound(40482, "desktop_task_not_found", "desktop task not found")
|
||||
}
|
||||
tx, err := s.pool.Begin(ctx)
|
||||
if err != nil {
|
||||
return nil, response.ErrInternal(50105, "desktop_task_reconcile_begin_failed", "failed to start desktop task reconcile")
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
taskRepo := repository.NewDesktopTaskRepository(tx)
|
||||
requeued, err := taskRepo.Reconcile(ctx, task.DesktopID, task.WorkspaceID, "retry", nil, nil)
|
||||
if err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, response.ErrConflict(40985, "desktop_task_reconcile_conflict", "desktop task is not waiting for reconcile")
|
||||
}
|
||||
return nil, response.ErrInternal(50094, "desktop_task_reconcile_failed", "failed to reconcile desktop task")
|
||||
}
|
||||
|
||||
if err := tx.Commit(ctx); err != nil {
|
||||
return nil, response.ErrInternal(50106, "desktop_task_reconcile_commit_failed", "failed to commit desktop task reconcile")
|
||||
}
|
||||
|
||||
publishDesktopTaskLifecycleEvent(ctx, s.messaging, s.logger, requeued, "task_available")
|
||||
return createPublishJobResponseForRequeuedTask(requeued), nil
|
||||
}
|
||||
|
||||
func createPublishJobResponseForRequeuedTask(task *repository.DesktopTask) *CreatePublishJobResponse {
|
||||
if task == nil {
|
||||
return &CreatePublishJobResponse{
|
||||
TaskIDs: []string{},
|
||||
CreatedTaskIDs: []string{},
|
||||
ExistingTaskIDs: []string{},
|
||||
RequeuedTaskIDs: []string{},
|
||||
}
|
||||
}
|
||||
taskID := task.DesktopID.String()
|
||||
return &CreatePublishJobResponse{
|
||||
JobID: "",
|
||||
TaskIDs: []string{taskID},
|
||||
CreatedTaskIDs: []string{},
|
||||
ExistingTaskIDs: []string{},
|
||||
RequeuedTaskIDs: []string{taskID},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *PublishJobService) authorizePublishTaskForClientUser(
|
||||
ctx context.Context,
|
||||
client *repository.DesktopClient,
|
||||
|
||||
Reference in New Issue
Block a user