Skip to content

Free series rotation

TwistCue’s free-day mechanic (per CONSTANTS: 1 rotating free series per day) is scheduled from Curation → Free today. Each day picks exactly one series that gets a free-full-run banner and unlocks all its episodes for anyone opening the app on that date (per user’s local timezone).

The free_series_rotations table is a simple date → series mapping:

(date UNIQUE, series_id, market_code?, notes?)
  • date: one row per calendar date (UTC).
  • series_id: must be a published series.
  • market_code: optional. If null, the rotation applies to all launch markets. If set, it’s market-scoped (e.g. run a Filipino romance in PH, a khaleeji drama in EG).

Curation → Free today shows a calendar-style planner:

  1. Click a future date.
  2. Search-pick a series (optionally scope by market).
  3. Save.

Same-day changes are allowed but affect only new sessions: users already scrolling see the previous free series until they refresh.

The Auto-generate next 30 days button (top-right) fills empty dates using a heuristic: newer series (younger than 60 days) with mid-range editorial_hero_score (avoid burning your best), rotating so no series repeats within 14 days.

Auto-fill only writes to empty dates; it never overwrites your hand-picked entries.

  • Cron: free-series-rotation-daily (5 0 * * * UTC)
  • File: services/api/src/modules/admin/analytics/rollups.cron.ts
  • Materializes today’s free series list into the feed composer’s cache for fast reads.

Delete the row for that date. If nothing is set for a given date, the mobile app simply shows no free-today banner (not “free” = default paywall behavior).

ActionEndpoint
List rotationsGET /v1/admin/free-series
Set/update a datePUT /v1/admin/free-series
Delete a dateDELETE /v1/admin/free-series/:date
Auto-generatePOST /v1/admin/free-series/generate-auto

Full details in API: Curation.