package repository import ( "context" "errors" "time" "github.com/google/uuid" "github.com/jackc/pgx/v5" ) // BannerRow is OpsCMS Banner catalog row. type BannerRow struct { ID uuid.UUID `json:"id"` Code string `json:"code"` Title string `json:"title"` Placement string `json:"placement"` ImageURL *string `json:"image_url,omitempty"` LinkPath *string `json:"link_path,omitempty"` SortOrder int `json:"sort_order"` Active bool `json:"active"` System bool `json:"system"` UpdatedAt time.Time `json:"updated_at"` } // ListBanners returns banner catalog. func (r *AdminRepo) ListBanners(ctx context.Context) ([]BannerRow, error) { rows, err := r.Pool.Query(ctx, ` SELECT id, code, title, placement, image_url, link_path, sort_order, active, system, updated_at FROM ops_banners ORDER BY active DESC, sort_order ASC, code ASC LIMIT 500`) if err != nil { return nil, err } defer rows.Close() var out []BannerRow for rows.Next() { var b BannerRow if err := rows.Scan( &b.ID, &b.Code, &b.Title, &b.Placement, &b.ImageURL, &b.LinkPath, &b.SortOrder, &b.Active, &b.System, &b.UpdatedAt, ); err != nil { return nil, err } out = append(out, b) } return out, rows.Err() } // GetBanner loads one banner by id. func (r *AdminRepo) GetBanner(ctx context.Context, id uuid.UUID) (*BannerRow, error) { var b BannerRow err := r.Pool.QueryRow(ctx, ` SELECT id, code, title, placement, image_url, link_path, sort_order, active, system, updated_at FROM ops_banners WHERE id=$1`, id, ).Scan( &b.ID, &b.Code, &b.Title, &b.Placement, &b.ImageURL, &b.LinkPath, &b.SortOrder, &b.Active, &b.System, &b.UpdatedAt, ) if errors.Is(err, pgx.ErrNoRows) { return nil, err } if err != nil { return nil, err } return &b, nil } // FeedSlotRow is OpsCMS FeedSlot catalog row. type FeedSlotRow struct { ID uuid.UUID `json:"id"` Code string `json:"code"` Title string `json:"title"` SlotKey string `json:"slot_key"` Placement string `json:"placement"` Active bool `json:"active"` System bool `json:"system"` UpdatedAt time.Time `json:"updated_at"` } // ListFeedSlots returns feed slot catalog. func (r *AdminRepo) ListFeedSlots(ctx context.Context) ([]FeedSlotRow, error) { rows, err := r.Pool.Query(ctx, ` SELECT id, code, title, slot_key, placement, active, system, updated_at FROM ops_feed_slots ORDER BY active DESC, code ASC LIMIT 500`) if err != nil { return nil, err } defer rows.Close() var out []FeedSlotRow for rows.Next() { var s FeedSlotRow if err := rows.Scan( &s.ID, &s.Code, &s.Title, &s.SlotKey, &s.Placement, &s.Active, &s.System, &s.UpdatedAt, ); err != nil { return nil, err } out = append(out, s) } return out, rows.Err() } // GetFeedSlot loads one feed slot by id. func (r *AdminRepo) GetFeedSlot(ctx context.Context, id uuid.UUID) (*FeedSlotRow, error) { var s FeedSlotRow err := r.Pool.QueryRow(ctx, ` SELECT id, code, title, slot_key, placement, active, system, updated_at FROM ops_feed_slots WHERE id=$1`, id, ).Scan(&s.ID, &s.Code, &s.Title, &s.SlotKey, &s.Placement, &s.Active, &s.System, &s.UpdatedAt) if errors.Is(err, pgx.ErrNoRows) { return nil, err } if err != nil { return nil, err } return &s, nil }