# Catalog

Catalog là danh sách phim và tập mà tổ chức của bạn được phép stream ngay lúc này. Catalog được thiết kế để là danh sách phim duy nhất app của bạn cần: nó mang thứ tự hiển thị, quy tắc tập miễn phí, facet thể loại và cờ sẵn sàng cho từng tập, nên bạn không phải tự duy trì những thứ này.

## Catalog chứa gì

`GET /api/delivery/v1/catalog` trả về một phim khi tất cả các điều kiện sau đều đúng tại thời điểm request:

- Tổ chức của bạn có giấy phép streaming cho phim, và giấy phép đó đang hoạt động.
- Hôm nay nằm trong khung thời gian của giấy phép. Khung thời gian tính theo ngày trọn vẹn theo UTC, bao gồm cả ngày đầu và ngày cuối.
- Phim đã được publish.

Với những phim đó, catalog trả về mọi tập đã publish. Phim còn đang sản xuất, và bản dựng thô (review cut) được chia sẻ để bạn góp ý, không bao giờ xuất hiện trong catalog và không phát được qua API.

Catalog chỉ chứa metadata. Nó không bao giờ chứa URL video; bạn xin playback cho từng tập bằng [`POST /playback`](https://docs.wandura.ai/vi/developers/concepts/playback).

## Cấu trúc response

Response có hai mảng phẳng, `films` và `episodes`. Nối chúng theo `episodes[].film_id` = `films[].id`. Danh sách trường đầy đủ nằm trong [tài liệu tham chiếu catalog](https://docs.wandura.ai/vi/developers/reference/catalog).

Toàn bộ catalog trả về trong một response. Không có pagination.

## Thứ tự

`films` được sắp theo `display_order`, nhỏ nhất trước. Hãy hiển thị phim đúng theo thứ tự nhận được. Wandura chỉnh thứ tự này, nên đừng giữ bảng thứ tự riêng.

`episodes` được nhóm theo film ID, rồi sắp theo `episode_no`. Các nhóm không theo thứ tự hiển thị, nên hãy lấy thứ tự phim từ `films`.

## Tập miễn phí và tập trả phí

Tập có `episode_no` nhỏ hơn hoặc bằng `free_until_episode` của phim là miễn phí; các tập còn lại là trả phí. Giá trị này khác nhau giữa các phim và có thể thay đổi, nên hãy đọc từ catalog thay vì hard-code. `0` nghĩa là không có tập miễn phí; `null` nghĩa là phim chưa được đặt số này, nên hãy coi mọi tập là trả phí.

## Tập dự kiến
`planned_episodes` là số tập phim sẽ có. Khi một số tập chưa được publish, catalog vẫn có một dòng cho mỗi số tập còn thiếu để bạn hiển thị ô "sắp ra mắt". Các dòng placeholder này có:

| Trường | Giá trị |
|---|---|
| `id` | `null` |
| `status` | `"planned"` |
| `stream_ready` | `false` |
| `title`, `synopsis`, `duration_ms`, `poster_uri` | `null` |

Không bao giờ gửi dòng placeholder tới `POST /playback`: nó không có episode ID. Nếu phim có nhiều tập đã publish hơn `planned_episodes`, tất cả vẫn được trả về. Khi `planned_episodes` là `null`, phim không có dòng placeholder nào.

## Trạng thái sẵn sàng: `stream_ready`

`stream_ready: true` nghĩa là đã có bản mã hoá của tập và `POST /playback` có thể cấp vé cho tập đó. Hãy làm mờ hoặc ẩn các tập có giá trị `false`, thay vì để người xem chạm vào rồi gặp lỗi.

Cờ này là ảnh chụp tại lúc bạn tải catalog. `POST /playback` kiểm tra lại giấy phép và tập mỗi lần, và câu trả lời của nó mới là câu trả lời có giá trị. Nhận `not_ready` cho một tập từng có `stream_ready: true` là bình thường, ví dụ sau khi một phim bị rút.

## Facet thể loại

Mỗi phim mang ba facet tuỳ chọn cho màn hình duyệt và bộ lọc. `null` nghĩa là phim chưa được phân loại; hãy hiển thị phim mà không có facet đó thay vì đoán.

| Trường | Giá trị có thể có |
|---|---|
| `audience` | `women`, `men`, `lgbtq`, hoặc `null` |
| `form` | `live_action`, `anime`, hoặc `null` |
| `setting` | `modern`, `city`, `fantasy`, `campus`, `palace`, hoặc `null` |

Phim còn có `genres`, một mảng nhãn thể loại dạng văn bản tự do, và `language`.

## Văn bản và ảnh

- `synopsis_short` dùng cho thẻ, `synopsis_full` dùng cho trang chi tiết. Độ dài khác nhau giữa các phim, nên hãy giới hạn (clamp) văn bản trong UI. `synopsis_full` có thể là `null`.
- `episodes[].synopsis` có thể là `null`. Khi đó đừng hiển thị gì.
- `poster_url` (phim) và `poster_uri` (tập) có thể là `null` trong lúc ảnh đang được chuẩn bị. Hãy hiển thị ảnh placeholder.

## Giữ bản sao luôn mới

Cache catalog trên server và làm mới theo lịch, thay vì gọi API mỗi lần mở app. Giấy phép hết hạn hoặc phim bị rút sẽ biến mất khỏi response kế tiếp; hãy gỡ mọi thứ không còn được liệt kê.

Catalog có bộ đếm rate limit riêng, tách khỏi playback và creatives. Xem [Rate limit](https://docs.wandura.ai/vi/developers/concepts/rate-limits).
