@@ -1168,6 +1168,72 @@ func (s *Store) TransferArtifact(ctx context.Context, taskID, targetClientID, re
|
||||
return from, nil
|
||||
}
|
||||
|
||||
// AdminArtifactQueueItem is a compact admin-only view of queued/generated
|
||||
// collectibles. It is intentionally independent from the task list filters so
|
||||
// an admin drop stays observable even when the UI is currently showing only
|
||||
// active hunt tasks.
|
||||
type AdminArtifactQueueItem struct {
|
||||
TaskID string `json:"task_id"`
|
||||
ArtifactOrigin string `json:"artifact_origin"`
|
||||
ArtifactStatus string `json:"artifact_status"`
|
||||
ArtifactError *string `json:"artifact_error,omitempty"`
|
||||
ArtifactURI *string `json:"artifact_uri,omitempty"`
|
||||
OwnerClientID string `json:"owner_client_id"`
|
||||
CreatedAtMS int64 `json:"created_at_ms"`
|
||||
}
|
||||
|
||||
func (s *Store) AdminArtifactQueueItems(ctx context.Context, ids []string) ([]AdminArtifactQueueItem, error) {
|
||||
clean := make([]string, 0, len(ids))
|
||||
seen := map[string]struct{}{}
|
||||
for _, id := range ids {
|
||||
id = strings.TrimSpace(id)
|
||||
if id == "" {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[id]; ok {
|
||||
continue
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
clean = append(clean, id)
|
||||
if len(clean) >= 20 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(clean) == 0 {
|
||||
return []AdminArtifactQueueItem{}, nil
|
||||
}
|
||||
marks := make([]string, len(clean))
|
||||
args := make([]any, len(clean))
|
||||
for i, id := range clean {
|
||||
marks[i] = "?"
|
||||
args[i] = id
|
||||
}
|
||||
rows, err := s.DB.QueryContext(ctx, `SELECT id,artifact_origin,artifact_status,artifact_error,artifact_uri,COALESCE(artifact_owner_client_id,winner_client_id,''),created_at
|
||||
FROM tasks WHERE id IN (`+strings.Join(marks, ",")+`) ORDER BY created_at`, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
out := make([]AdminArtifactQueueItem, 0, len(clean))
|
||||
for rows.Next() {
|
||||
var x AdminArtifactQueueItem
|
||||
var aerr, uri sql.NullString
|
||||
if err := rows.Scan(&x.TaskID, &x.ArtifactOrigin, &x.ArtifactStatus, &aerr, &uri, &x.OwnerClientID, &x.CreatedAtMS); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if aerr.Valid {
|
||||
v := aerr.String
|
||||
x.ArtifactError = &v
|
||||
}
|
||||
if uri.Valid {
|
||||
v := uri.String
|
||||
x.ArtifactURI = &v
|
||||
}
|
||||
out = append(out, x)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
// CreateAdminArtifactDrop queues a collectible for an existing client without
|
||||
// recording a game win. A random task is used as the art-direction template
|
||||
// when templateTaskID is empty; the new seed/id still randomize collection traits.
|
||||
|
||||
Reference in New Issue
Block a user