Files
silo-server/internal/usercollections/listing.go
T

75 lines
2.8 KiB
Go

package usercollections
import (
"context"
"fmt"
"time"
"github.com/jackc/pgx/v5/pgxpool"
)
// ServerVisibleCollection is the per-user view of a personal collection the
// owner has opted into their own library Collections tab. Personal collections
// are private to their owner; this list never crosses user boundaries.
type ServerVisibleCollection struct {
ID string `json:"id"`
CreatorProfileID string `json:"creator_profile_id"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
CollectionType string `json:"collection_type"`
ItemCount int `json:"item_count"`
PosterPath string `json:"-"`
PosterURL string `json:"poster_url,omitempty"`
PosterThumbhash string `json:"poster_thumbhash,omitempty"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
// serverVisibleListLimit caps how many opt-in collections a single library tab
// will surface so a user with hundreds of published collections can't blow up
// the response.
const serverVisibleListLimit = 500
// ListServerVisibleByLibrary returns the current user's personal collections
// that have opted into their library Collections tab and whose library scope
// matches the requested library. A collection with no library_ids set in its
// query definition is treated as library-agnostic and therefore visible in
// every library tab. Other users' collections are never returned.
func ListServerVisibleByLibrary(ctx context.Context, pool *pgxpool.Pool, userID int, libraryID int) ([]ServerVisibleCollection, error) {
rows, err := pool.Query(ctx,
`SELECT id, creator_profile_id, name, description, collection_type, item_count,
poster_url, poster_thumbhash, created_at, updated_at
FROM user_personal_collections
WHERE user_id = $1
AND include_in_server_collections = TRUE
AND (
NOT (query_definition ? 'library_ids')
OR jsonb_array_length(COALESCE(query_definition->'library_ids', '[]'::jsonb)) = 0
OR query_definition->'library_ids' @> to_jsonb($2::int)
)
ORDER BY name ASC
LIMIT $3`,
userID, libraryID, serverVisibleListLimit,
)
if err != nil {
return nil, fmt.Errorf("listing server-visible user collections: %w", err)
}
defer rows.Close()
var out []ServerVisibleCollection
for rows.Next() {
var c ServerVisibleCollection
var createdAt, updatedAt time.Time
if err := rows.Scan(
&c.ID, &c.CreatorProfileID, &c.Name, &c.Description, &c.CollectionType,
&c.ItemCount, &c.PosterPath, &c.PosterThumbhash, &createdAt, &updatedAt,
); err != nil {
return nil, fmt.Errorf("scanning server-visible user collection: %w", err)
}
c.CreatedAt = createdAt.UTC().Format(time.RFC3339)
c.UpdatedAt = updatedAt.UTC().Format(time.RFC3339)
out = append(out, c)
}
return out, rows.Err()
}