card_store.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package postgres
  2. import (
  3. "context"
  4. "fmt"
  5. "time"
  6. )
  7. type Card struct {
  8. ID string
  9. PublicID string
  10. CardType string
  11. Title string
  12. Subtitle *string
  13. CoverURL *string
  14. DisplaySlot string
  15. DisplayPriority int
  16. EntryChannelID *string
  17. EventPublicID *string
  18. EventDisplayName *string
  19. EventSummary *string
  20. HTMLURL *string
  21. }
  22. func (s *Store) ListCardsForEntry(ctx context.Context, tenantID string, entryChannelID *string, slot string, now time.Time, limit int) ([]Card, error) {
  23. if limit <= 0 || limit > 100 {
  24. limit = 20
  25. }
  26. if slot == "" {
  27. slot = "home_primary"
  28. }
  29. rows, err := s.pool.Query(ctx, `
  30. SELECT
  31. c.id,
  32. c.card_public_id,
  33. c.card_type,
  34. c.title,
  35. c.subtitle,
  36. c.cover_url,
  37. c.display_slot,
  38. c.display_priority,
  39. c.entry_channel_id,
  40. e.event_public_id,
  41. e.display_name,
  42. e.summary,
  43. c.html_url
  44. FROM cards c
  45. LEFT JOIN events e ON e.id = c.event_id
  46. WHERE c.tenant_id = $1
  47. AND ($2::uuid IS NULL OR c.entry_channel_id = $2 OR c.entry_channel_id IS NULL)
  48. AND c.display_slot = $3
  49. AND c.status = 'active'
  50. AND (c.starts_at IS NULL OR c.starts_at <= $4)
  51. AND (c.ends_at IS NULL OR c.ends_at >= $4)
  52. ORDER BY
  53. CASE WHEN $2::uuid IS NOT NULL AND c.entry_channel_id = $2 THEN 0 ELSE 1 END,
  54. c.display_priority DESC,
  55. c.created_at ASC
  56. LIMIT $5
  57. `, tenantID, entryChannelID, slot, now, limit)
  58. if err != nil {
  59. return nil, fmt.Errorf("list cards for entry: %w", err)
  60. }
  61. defer rows.Close()
  62. var cards []Card
  63. for rows.Next() {
  64. var card Card
  65. if err := rows.Scan(
  66. &card.ID,
  67. &card.PublicID,
  68. &card.CardType,
  69. &card.Title,
  70. &card.Subtitle,
  71. &card.CoverURL,
  72. &card.DisplaySlot,
  73. &card.DisplayPriority,
  74. &card.EntryChannelID,
  75. &card.EventPublicID,
  76. &card.EventDisplayName,
  77. &card.EventSummary,
  78. &card.HTMLURL,
  79. ); err != nil {
  80. return nil, fmt.Errorf("scan card: %w", err)
  81. }
  82. cards = append(cards, card)
  83. }
  84. if err := rows.Err(); err != nil {
  85. return nil, fmt.Errorf("iterate cards: %w", err)
  86. }
  87. return cards, nil
  88. }