@smartico/public-api 0.0.411 → 0.0.412

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3279,18 +3279,46 @@ class WSAPIMissions extends WSAPIGeneral {
3279
3279
  * `only_in_custom_section: true` are intended for their custom-section
3280
3280
  * view only and should be hidden from the main mission list.
3281
3281
  *
3282
- * **Reading state from the returned mission**
3283
- * Drive availability chips ("missed", "coming soon", "needs opt-in",
3284
- * "in progress", "expired") from `availability_status` (enum
3285
- * {@link AchievementAvailabilityStatus}) — it's the canonical derived
3286
- * state and reflects all server-side timing/visibility rules in one
3287
- * field. For time-limited and recurring missions, `dt_start` doubles
3288
- * as the opt-in timestamp (for opt-in missions) or unlock timestamp
3289
- * (for previously-locked missions); the expiration of a time-limited
3290
- * mission is `dt_start + time_limit_ms`. `next_recurrence_date_ts`
3291
- * is populated for `RECURRING` / `RECURRING_QUANTITY` missions but
3292
- * is no longer meaningful once the mission's `active_till_ts` has
3293
- * passed.
3282
+ * **Status bucketing (which tab / section a mission belongs to)**
3283
+ * There is no pre-computed bucket field — assign each mission to exactly
3284
+ * ONE section reading the raw state fields directly (NOT `availability_status`;
3285
+ * see "Timers" below). Priority order, FIRST match wins:
3286
+ * 1. **Missed / Expired** — not completed and the window has closed:
3287
+ * `!is_completed && ((time_limit_ms && dt_start && dt_start + time_limit_ms < Date.now())`
3288
+ * `|| (active_till_ts && active_till_ts < Date.now()))`. Do NOT gate this on
3289
+ * opt-in — an opt-in mission whose window closed before the user ever
3290
+ * opted in is still Missed. Sort by `position` ASC.
3291
+ * 2. **Completed** — `is_completed === true`, OR (recurring-upon-completion
3292
+ * missions) at least one cycle done / the cap reached — see the recurring
3293
+ * caveats below. Sort by `complete_date_ts` DESC.
3294
+ * 3. **Locked** — `is_locked === true`, OR not yet started
3295
+ * (`active_from_ts > Date.now()`). Sort by `position` ASC.
3296
+ * 4. **In-progress** — `is_opted_in === true`, OR (no opt-in required and
3297
+ * `progress > 0`). Sort by `position` ASC.
3298
+ * 5. **Available** — everything else (opt-in required but not yet joined, or
3299
+ * an unrestricted mission not yet started). Sort by `position` ASC.
3300
+ *
3301
+ * **Recurring-upon-completion caveats** (the common mis-bucketing trap):
3302
+ * - `is_completed` NEVER flips true for a recurring-upon-completion mission
3303
+ * (only for one-shot missions) — detect a completed cycle from
3304
+ * `completion_count > 0`, not `is_completed`.
3305
+ * - A non-null `completion_count` is what identifies a recurring-upon-completion
3306
+ * mission. `max_completion_count === null` means an INFINITE cap (still
3307
+ * recurring — never read null as "not recurring"), so only test
3308
+ * `completion_count >= max_completion_count` when `max_completion_count` is set.
3309
+ *
3310
+ * **Timers & timestamps** (display only — NOT bucketing)
3311
+ * `availability_status` (enum {@link AchievementAvailabilityStatus}) is the
3312
+ * timer/window signal: use it to pick WHICH countdown to show and whether the
3313
+ * window has elapsed — NOT to choose the section. It does not read
3314
+ * `completion_count`, and between cycles the server may keep reporting the
3315
+ * just-elapsed cycle's `Missed*` value even after `dt_start` / `active_till_ts`
3316
+ * are cleared for the next attempt, so bucketing by it sends recurring missions
3317
+ * to the wrong tab. For time-limited / opt-in missions `dt_start` is the opt-in
3318
+ * timestamp (or unlock timestamp for previously-locked missions), and a
3319
+ * time-limited mission expires at `dt_start + time_limit_ms`.
3320
+ * `next_recurrence_date_ts` is populated for `RECURRING` / `RECURRING_QUANTITY`
3321
+ * missions but is no longer meaningful once `active_till_ts` has passed.
3294
3322
  *
3295
3323
  * **Refresh after a mutation**
3296
3324
  * After `requestMissionOptIn(...)` or `requestMissionClaimReward(...)`