CREATE OR REPLACE VIEW optimized_all_activity AS
WITH feed_data AS (
  SELECT json_build_object(
    'title', p.title,
    'url', p.url,
    'description', p.content,
    'date', p.date,
    'type', 'article',
    'label', 'Post',
    'content', p.content
  ) AS feed
  FROM optimized_posts p

  UNION ALL

  SELECT json_build_object(
    'title', CONCAT(l.title, ' via ', l.author->>'name'),
    'url', l.link,
    'description', l.description,
    'date', l.date,
    'type', 'link',
    'label', 'Link',
    'author', l.author
  ) AS feed
  FROM optimized_links l

  UNION ALL

  SELECT CASE
    WHEN LOWER(b.status) = 'finished' THEN
      json_build_object(
        'title', CONCAT(b.title, ' by ', b.author,
          CASE WHEN b.rating IS NOT NULL THEN CONCAT(' (', b.rating, ')') ELSE '' END
        ),
        'url', b.url,
        'description', COALESCE(b.review, b.description),
        'date', b.date_finished,
        'type', 'books',
        'label', 'Book',
        'image', b.image,
        'rating', b.rating
      )
    ELSE NULL
  END AS feed
  FROM optimized_books b

  UNION ALL

  SELECT CASE
    WHEN m.last_watched IS NOT NULL THEN
      json_build_object(
        'title', CONCAT(m.title,
          CASE WHEN m.rating IS NOT NULL THEN CONCAT(' (', m.rating, ')') ELSE '' END
        ),
        'url', m.url,
        'description', COALESCE(m.review, m.description),
        'date', m.last_watched,
        'type', 'movies',
        'label', 'Movie',
        'image', m.image,
        'rating', m.rating
      )
    ELSE NULL
  END AS feed
  FROM optimized_movies m
)
SELECT feed
FROM feed_data
WHERE feed IS NOT NULL
ORDER BY (feed->>'date')::timestamp DESC
LIMIT 20;