@smartico/public-api 0.0.411 → 0.0.413

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.
Files changed (34) hide show
  1. package/dist/Jackpots/JackpotPublicMeta.d.ts +1 -1
  2. package/dist/Level/LevelPublicMeta.d.ts +1 -1
  3. package/dist/MiniGames/SAWTemplate.d.ts +2 -0
  4. package/dist/Raffle/Raffle.d.ts +1 -1
  5. package/dist/SmarticoLib/index.d.ts +3 -3
  6. package/dist/WSAPI/WSAPIJackpots.d.ts +3 -1
  7. package/dist/WSAPI/WSAPIMissions.d.ts +40 -12
  8. package/dist/WSAPI/WSAPITypes.d.ts +7 -5
  9. package/dist/index.js +47 -14
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.modern.mjs +47 -14
  12. package/dist/index.modern.mjs.map +1 -1
  13. package/docs/api/classes/WSAPIMissions.md +40 -12
  14. package/docs/api/interfaces/JackpotPublicMeta.md +1 -1
  15. package/docs/api/interfaces/LevelPublicMeta.md +1 -1
  16. package/docs/api/interfaces/RafflePublicMeta.md +1 -1
  17. package/docs/api/interfaces/SAWTemplate.md +8 -0
  18. package/docs/api/interfaces/TMissionOrBadge.md +6 -4
  19. package/docs/api/interfaces/TRaffle.md +1 -1
  20. package/docs/capabilities/getBadges.md +4 -4
  21. package/docs/capabilities/getMissions.md +44 -16
  22. package/docs/capabilities/getRaffles.md +1 -1
  23. package/docs/capabilities/jackpotGet.md +1 -1
  24. package/docs/ui/jackpots/UIGuide_getJackpotWinners.md +3 -2
  25. package/docs/ui/missions/UIGuide_getMissions.md +44 -24
  26. package/package.json +1 -1
  27. package/src/Jackpots/JackpotPublicMeta.ts +1 -1
  28. package/src/Level/LevelPublicMeta.ts +1 -1
  29. package/src/MiniGames/SAWTemplate.ts +2 -0
  30. package/src/Raffle/Raffle.ts +1 -1
  31. package/src/SmarticoLib/index.ts +3 -3
  32. package/src/WSAPI/WSAPIJackpots.ts +7 -2
  33. package/src/WSAPI/WSAPIMissions.ts +40 -12
  34. package/src/WSAPI/WSAPITypes.ts +7 -5
@@ -85,18 +85,46 @@ Client-side filtering you may still want: missions with
85
85
  `only_in_custom_section: true` are intended for their custom-section
86
86
  view only and should be hidden from the main mission list.
87
87
 
88
- **Reading state from the returned mission**
89
- Drive availability chips ("missed", "coming soon", "needs opt-in",
90
- "in progress", "expired") from `availability_status` (enum
91
- [AchievementAvailabilityStatus](../enumerations/AchievementAvailabilityStatus.md)) — it's the canonical derived
92
- state and reflects all server-side timing/visibility rules in one
93
- field. For time-limited and recurring missions, `dt_start` doubles
94
- as the opt-in timestamp (for opt-in missions) or unlock timestamp
95
- (for previously-locked missions); the expiration of a time-limited
96
- mission is `dt_start + time_limit_ms`. `next_recurrence_date_ts`
97
- is populated for `RECURRING` / `RECURRING_QUANTITY` missions but
98
- is no longer meaningful once the mission's `active_till_ts` has
99
- passed.
88
+ **Status bucketing (which tab / section a mission belongs to)**
89
+ There is no pre-computed bucket field — assign each mission to exactly
90
+ ONE section reading the raw state fields directly (NOT `availability_status`;
91
+ see "Timers" below). Priority order, FIRST match wins:
92
+ 1. **Missed / Expired** — not completed and the window has closed:
93
+ `!is_completed && ((time_limit_ms && dt_start && dt_start + time_limit_ms < Date.now())`
94
+ `|| (active_till_ts && active_till_ts < Date.now()))`. Do NOT gate this on
95
+ opt-in — an opt-in mission whose window closed before the user ever
96
+ opted in is still Missed. Sort by `position` ASC.
97
+ 2. **Completed** — `is_completed === true`, OR (recurring-upon-completion
98
+ missions) at least one cycle done / the cap reached — see the recurring
99
+ caveats below. Sort by `complete_date_ts` DESC.
100
+ 3. **Locked** — `is_locked === true`, OR not yet started
101
+ (`active_from_ts > Date.now()`). Sort by `position` ASC.
102
+ 4. **In-progress** — `is_opted_in === true`, OR (no opt-in required and
103
+ `progress > 0`). Sort by `position` ASC.
104
+ 5. **Available** — everything else (opt-in required but not yet joined, or
105
+ an unrestricted mission not yet started). Sort by `position` ASC.
106
+
107
+ **Recurring-upon-completion caveats** (the common mis-bucketing trap):
108
+ - `is_completed` NEVER flips true for a recurring-upon-completion mission
109
+ (only for one-shot missions) — detect a completed cycle from
110
+ `completion_count > 0`, not `is_completed`.
111
+ - A non-null `completion_count` is what identifies a recurring-upon-completion
112
+ mission. `max_completion_count === null` means an INFINITE cap (still
113
+ recurring — never read null as "not recurring"), so only test
114
+ `completion_count >= max_completion_count` when `max_completion_count` is set.
115
+
116
+ **Timers & timestamps** (display only — NOT bucketing)
117
+ `availability_status` (enum [AchievementAvailabilityStatus](../enumerations/AchievementAvailabilityStatus.md)) is the
118
+ timer/window signal: use it to pick WHICH countdown to show and whether the
119
+ window has elapsed — NOT to choose the section. It does not read
120
+ `completion_count`, and between cycles the server may keep reporting the
121
+ just-elapsed cycle's `Missed*` value even after `dt_start` / `active_till_ts`
122
+ are cleared for the next attempt, so bucketing by it sends recurring missions
123
+ to the wrong tab. For time-limited / opt-in missions `dt_start` is the opt-in
124
+ timestamp (or unlock timestamp for previously-locked missions), and a
125
+ time-limited mission expires at `dt_start + time_limit_ms`.
126
+ `next_recurrence_date_ts` is populated for `RECURRING` / `RECURRING_QUANTITY`
127
+ missions but is no longer meaningful once `active_till_ts` has passed.
100
128
 
101
129
  **Refresh after a mutation**
102
130
  After `requestMissionOptIn(...)` or `requestMissionClaimReward(...)`
@@ -64,4 +64,4 @@ custom value of placeholder2 defined by operator and can be used in the HTML tem
64
64
 
65
65
  Custom data as string or JSON string that can be used in API to build custom UI
66
66
  You can request from Smartico to define fields for your specific case that will be managed from Smartico BackOffice
67
- Read more here - <https://help.smartico.ai/welcome/products/general-concepts/custom-fields-attributes>
67
+ Read more here - <https://help.smartico.ai/welcome/products/tools-and-guides/custom-fields-attributes>
@@ -64,4 +64,4 @@ X & Y coordinates of level on the visual mission map, for desktop and mobile
64
64
 
65
65
  Custom data as string or JSON string that can be used in API to build custom UI
66
66
  You can request from Smartico to define fields for your specific case that will be managed from Smartico BackOffice
67
- Read more here - https://help.smartico.ai/welcome/products/general-concepts/custom-fields-attributes
67
+ Read more here - https://help.smartico.ai/welcome/products/tools-and-guides/custom-fields-attributes
@@ -56,7 +56,7 @@ Text for Terms and Conditions
56
56
 
57
57
  Custom data as string or JSON string that can be used in API to build custom UI
58
58
  You can request from Smartico to define fields for your specific case that will be managed from Smartico BackOffice
59
- Read more here - <https://help.smartico.ai/welcome/products/general-concepts/custom-fields-attributes>
59
+ Read more here - <https://help.smartico.ai/welcome/products/tools-and-guides/custom-fields-attributes>
60
60
 
61
61
  ***
62
62
 
@@ -210,6 +210,14 @@ Prize Drop only: when true, the pushed prize requires an explicit claim by the u
210
210
 
211
211
  ***
212
212
 
213
+ ### requires\_manual\_claim?
214
+
215
+ > `optional` **requires\_manual\_claim?**: `boolean`
216
+
217
+ Prize Drop only: when true, the pushed prize requires a manual claim by the user before it is credited. The difference between this and `requires_prize_claim` is that requires_manual_claim gives the user the ability to cancel the claim.
218
+
219
+ ***
220
+
213
221
  ### relative\_period\_timezone?
214
222
 
215
223
  > `optional` **relative\_period\_timezone?**: `number`
@@ -64,7 +64,9 @@ URL of the image of the mission or badge, 256x256px
64
64
 
65
65
  > **is\_completed**: `boolean`
66
66
 
67
- Indicator if the mission is completed or badge is granted
67
+ Indicator if the mission is completed or badge is granted. Stays `false` for
68
+ Recurring-upon-completion missions even after cycles complete — use `completion_count`
69
+ to detect completed cycles (see `getMissions` bucketing).
68
70
 
69
71
  ***
70
72
 
@@ -311,7 +313,7 @@ ID of specific Custom Section type
311
313
 
312
314
  > `optional` **max\_completion\_count?**: `number`
313
315
 
314
- Max number of times the user can complete a mission in case if mission type is Recurring upon completion. NULL equals infinite.
316
+ Max number of times the user can complete a mission in case if mission type is Recurring upon completion. NULL equals infinite (still recurring — not "no cap disables recurring").
315
317
 
316
318
  ***
317
319
 
@@ -319,7 +321,7 @@ Max number of times the user can complete a mission in case if mission type is R
319
321
 
320
322
  > `optional` **completion\_count?**: `number`
321
323
 
322
- Current completion count for Recurring upon completion missions
324
+ Current completion count for Recurring-upon-completion missions. Non-null ONLY for that mission type, so its presence identifies one; `> 0` means at least one cycle completed.
323
325
 
324
326
  ***
325
327
 
@@ -336,7 +338,7 @@ Note that if a mission has an "Active till" date defined, this field is not rele
336
338
 
337
339
  > `optional` **availability\_status?**: [`AchievementAvailabilityStatus`](../enumerations/AchievementAvailabilityStatus.md)
338
340
 
339
- Availability status of the mission depends on the defined time limits
341
+ Timer/window state derived from the mission's time limits (which countdown to show / whether the window elapsed). NOT a tab-bucketing signal — it ignores `completion_count`, so bucket sections from the raw fields instead (see `getMissions`).
340
342
 
341
343
  ***
342
344
 
@@ -56,7 +56,7 @@ URL of the mobile image that represents the raffle, 300x142px
56
56
 
57
57
  Custom data as string or JSON string that can be used in API to build custom UI
58
58
  You can request from Smartico to define fields for your specific case that will be managed from Smartico BackOffice
59
- Read more here - https://help.smartico.ai/welcome/products/general-concepts/custom-fields-attributes
59
+ Read more here - https://help.smartico.ai/welcome/products/tools-and-guides/custom-fields-attributes
60
60
 
61
61
  ***
62
62
 
@@ -21,7 +21,7 @@ Array of `TMissionOrBadge`. Each item:
21
21
  - `description` (string) — Description of the mission or badge, translated to the user language
22
22
  - `reward` (string) — Description of the mission reward if defined
23
23
  - `image` (string) — URL of the image of the mission or badge, 256x256px
24
- - `is_completed` (boolean) — Indicator if the mission is completed or badge is granted
24
+ - `is_completed` (boolean) — Indicator if the mission is completed or badge is granted. Stays `false` for Recurring-upon-completion missions even after cycles complete — use `completion_count` to detect completed cycles (see `getMissions` bucketing).
25
25
  - `is_locked` (boolean) — Indicator if the mission is locked. Means that it's visible to the user, but he cannot progress in it until it's unlocked. Mission may optionally contain the explanation of what should be done to unlock it in the unlock_mission_description property
26
26
  - `unlock_mission_description` (string) — Optional explaination of what should be done to unlock the mission
27
27
  - `is_requires_optin` (boolean) — Indicator if the mission requires opt-in. Means that user should explicitly opt-in to the mission in order to start progressing in it
@@ -79,10 +79,10 @@ Array of `TMissionOrBadge`. Each item:
79
79
  - `completed_this_week` (boolean) — Flag for mission/badge indicating that mission/badge completed this week
80
80
  - `completed_this_month` (boolean) — Flag for mission/badge indicating that mission/badge completed this month
81
81
  - `custom_section_type_id` (number) — ID of specific Custom Section type
82
- - `max_completion_count` (number) — Max number of times the user can complete a mission in case if mission type is Recurring upon completion. NULL equals infinite.
83
- - `completion_count` (number) — Current completion count for Recurring upon completion missions
82
+ - `max_completion_count` (number) — Max number of times the user can complete a mission in case if mission type is Recurring upon completion. NULL equals infinite (still recurring — not "no cap disables recurring").
83
+ - `completion_count` (number) — Current completion count for Recurring-upon-completion missions. Non-null ONLY for that mission type, so its presence identifies one; `> 0` means at least one cycle completed.
84
84
  - `next_recurrence_date_ts` (number) — The date/timestamp for recurring missions, which indicating the time remaining until the next recurrence of the mission. Note that if a mission has an "Active till" date defined, this field is not relevant after that date.
85
- - `availability_status` (AchievementAvailabilityStatus) — Availability status of the mission depends on the defined time limits
85
+ - `availability_status` (AchievementAvailabilityStatus) — Timer/window state derived from the mission's time limits (which countdown to show / whether the window elapsed). NOT a tab-bucketing signal — it ignores `completion_count`, so bucket sections from the raw fields instead (see `getMissions`).
86
86
  - `claim_button_title` (string) — Title for the claim reward button
87
87
  - `claim_button_action` (string) — Action for the claim reward button
88
88
  - `prize_claim_expiration_date` (number) — The date/timestamp indicating when the mission claim will expire
@@ -22,7 +22,7 @@ Array of `TMissionOrBadge`. Each item:
22
22
  - `description` (string) — Description of the mission or badge, translated to the user language
23
23
  - `reward` (string) — Description of the mission reward if defined
24
24
  - `image` (string) — URL of the image of the mission or badge, 256x256px
25
- - `is_completed` (boolean) — Indicator if the mission is completed or badge is granted
25
+ - `is_completed` (boolean) — Indicator if the mission is completed or badge is granted. Stays `false` for Recurring-upon-completion missions even after cycles complete — use `completion_count` to detect completed cycles (see `getMissions` bucketing).
26
26
  - `is_locked` (boolean) — Indicator if the mission is locked. Means that it's visible to the user, but he cannot progress in it until it's unlocked. Mission may optionally contain the explanation of what should be done to unlock it in the unlock_mission_description property
27
27
  - `unlock_mission_description` (string) — Optional explaination of what should be done to unlock the mission
28
28
  - `is_requires_optin` (boolean) — Indicator if the mission requires opt-in. Means that user should explicitly opt-in to the mission in order to start progressing in it
@@ -80,10 +80,10 @@ Array of `TMissionOrBadge`. Each item:
80
80
  - `completed_this_week` (boolean) — Flag for mission/badge indicating that mission/badge completed this week
81
81
  - `completed_this_month` (boolean) — Flag for mission/badge indicating that mission/badge completed this month
82
82
  - `custom_section_type_id` (number) — ID of specific Custom Section type
83
- - `max_completion_count` (number) — Max number of times the user can complete a mission in case if mission type is Recurring upon completion. NULL equals infinite.
84
- - `completion_count` (number) — Current completion count for Recurring upon completion missions
83
+ - `max_completion_count` (number) — Max number of times the user can complete a mission in case if mission type is Recurring upon completion. NULL equals infinite (still recurring — not "no cap disables recurring").
84
+ - `completion_count` (number) — Current completion count for Recurring-upon-completion missions. Non-null ONLY for that mission type, so its presence identifies one; `> 0` means at least one cycle completed.
85
85
  - `next_recurrence_date_ts` (number) — The date/timestamp for recurring missions, which indicating the time remaining until the next recurrence of the mission. Note that if a mission has an "Active till" date defined, this field is not relevant after that date.
86
- - `availability_status` (AchievementAvailabilityStatus) — Availability status of the mission depends on the defined time limits
86
+ - `availability_status` (AchievementAvailabilityStatus) — Timer/window state derived from the mission's time limits (which countdown to show / whether the window elapsed). NOT a tab-bucketing signal — it ignores `completion_count`, so bucket sections from the raw fields instead (see `getMissions`).
87
87
  - `claim_button_title` (string) — Title for the claim reward button
88
88
  - `claim_button_action` (string) — Action for the claim reward button
89
89
  - `prize_claim_expiration_date` (number) — The date/timestamp indicating when the mission claim will expire
@@ -132,18 +132,46 @@ Client-side filtering you may still want: missions with
132
132
  `only_in_custom_section: true` are intended for their custom-section
133
133
  view only and should be hidden from the main mission list.
134
134
 
135
- **Reading state from the returned mission**
136
- Drive availability chips ("missed", "coming soon", "needs opt-in",
137
- "in progress", "expired") from `availability_status` (enum
138
- `AchievementAvailabilityStatus`) — it's the canonical derived
139
- state and reflects all server-side timing/visibility rules in one
140
- field. For time-limited and recurring missions, `dt_start` doubles
141
- as the opt-in timestamp (for opt-in missions) or unlock timestamp
142
- (for previously-locked missions); the expiration of a time-limited
143
- mission is `dt_start + time_limit_ms`. `next_recurrence_date_ts`
144
- is populated for `RECURRING` / `RECURRING_QUANTITY` missions but
145
- is no longer meaningful once the mission's `active_till_ts` has
146
- passed.
135
+ **Status bucketing (which tab / section a mission belongs to)**
136
+ There is no pre-computed bucket field — assign each mission to exactly
137
+ ONE section reading the raw state fields directly (NOT `availability_status`;
138
+ see "Timers" below). Priority order, FIRST match wins:
139
+ 1. **Missed / Expired** — not completed and the window has closed:
140
+ `!is_completed && ((time_limit_ms && dt_start && dt_start + time_limit_ms < Date.now())`
141
+ `|| (active_till_ts && active_till_ts < Date.now()))`. Do NOT gate this on
142
+ opt-in — an opt-in mission whose window closed before the user ever
143
+ opted in is still Missed. Sort by `position` ASC.
144
+ 2. **Completed** — `is_completed === true`, OR (recurring-upon-completion
145
+ missions) at least one cycle done / the cap reached — see the recurring
146
+ caveats below. Sort by `complete_date_ts` DESC.
147
+ 3. **Locked** — `is_locked === true`, OR not yet started
148
+ (`active_from_ts > Date.now()`). Sort by `position` ASC.
149
+ 4. **In-progress** — `is_opted_in === true`, OR (no opt-in required and
150
+ `progress > 0`). Sort by `position` ASC.
151
+ 5. **Available** — everything else (opt-in required but not yet joined, or
152
+ an unrestricted mission not yet started). Sort by `position` ASC.
153
+
154
+ **Recurring-upon-completion caveats** (the common mis-bucketing trap):
155
+ - `is_completed` NEVER flips true for a recurring-upon-completion mission
156
+ (only for one-shot missions) — detect a completed cycle from
157
+ `completion_count > 0`, not `is_completed`.
158
+ - A non-null `completion_count` is what identifies a recurring-upon-completion
159
+ mission. `max_completion_count === null` means an INFINITE cap (still
160
+ recurring — never read null as "not recurring"), so only test
161
+ `completion_count >= max_completion_count` when `max_completion_count` is set.
162
+
163
+ **Timers & timestamps** (display only — NOT bucketing)
164
+ `availability_status` (enum `AchievementAvailabilityStatus`) is the
165
+ timer/window signal: use it to pick WHICH countdown to show and whether the
166
+ window has elapsed — NOT to choose the section. It does not read
167
+ `completion_count`, and between cycles the server may keep reporting the
168
+ just-elapsed cycle's `Missed*` value even after `dt_start` / `active_till_ts`
169
+ are cleared for the next attempt, so bucketing by it sends recurring missions
170
+ to the wrong tab. For time-limited / opt-in missions `dt_start` is the opt-in
171
+ timestamp (or unlock timestamp for previously-locked missions), and a
172
+ time-limited mission expires at `dt_start + time_limit_ms`.
173
+ `next_recurrence_date_ts` is populated for `RECURRING` / `RECURRING_QUANTITY`
174
+ missions but is no longer meaningful once `active_till_ts` has passed.
147
175
 
148
176
  **Refresh after a mutation**
149
177
  After `requestMissionOptIn(...)` or `requestMissionClaimReward(...)`
@@ -21,7 +21,7 @@ Array of `TRaffle`. Each item:
21
21
  - `custom_section_id` (number) — ID of the custom section that is linked to the raffle in the Gamification widget
22
22
  - `image_url` (string) — URL of the image that represents the raffle, 890x193px
23
23
  - `image_url_mobile` (string) — URL of the mobile image that represents the raffle, 300x142px
24
- - `custom_data` (string) — Custom data as string or JSON string that can be used in API to build custom UI You can request from Smartico to define fields for your specific case that will be managed from Smartico BackOffice Read more here - https://help.smartico.ai/welcome/products/general-concepts/custom-fields-attributes
24
+ - `custom_data` (string) — Custom data as string or JSON string that can be used in API to build custom UI You can request from Smartico to define fields for your specific case that will be managed from Smartico BackOffice Read more here - https://help.smartico.ai/welcome/products/tools-and-guides/custom-fields-attributes
25
25
  - `start_date` (number) — Date of start
26
26
  - `end_date` (number) — Date of end
27
27
  - `max_tickets_count` (number) — Maximum numer of tickets that can be given to all users for the whole period of raffle
@@ -30,7 +30,7 @@ Array of `JackpotDetails`. Each item:
30
30
  - `content` (string)
31
31
  - `placeholder1` (string) — custom value of placeholder1 defined by operator and can be used in the HTML templates
32
32
  - `placeholder2` (string) — custom value of placeholder2 defined by operator and can be used in the HTML templates
33
- - `custom_data` (string) — Custom data as string or JSON string that can be used in API to build custom UI You can request from Smartico to define fields for your specific case that will be managed from Smartico BackOffice Read more here - <https://help.smartico.ai/welcome/products/general-concepts/custom-fields-attributes>
33
+ - `custom_data` (string) — Custom data as string or JSON string that can be used in API to build custom UI You can request from Smartico to define fields for your specific case that will be managed from Smartico BackOffice Read more here - <https://help.smartico.ai/welcome/products/tools-and-guides/custom-fields-attributes>
34
34
  - `jp_currency` (string) — Native jackpot currency (ISO 4217). Used for winner-history amounts.
35
35
  - `user_currency` (string) — Current user's wallet currency. Used to display the pot via `pot.current_pot_amount_user_currency`.
36
36
  - `contribution_type` (JackpotContributionType) — Whether the contribution is a fixed amount or a percentage of the bet; see `JackpotContributionType`.
@@ -4,7 +4,7 @@
4
4
  - Paginated list of past winners of a specific jackpot template.
5
5
  - Powers the "Recent Winners" / "Win History" tab inside the jackpot
6
6
  detail modal.
7
- - 30 s cache per template.
7
+ - 30 s cache per page (template + `limit`/`offset`).
8
8
  - Gated by the operator's `expose_winners_over_api` flag — but only on
9
9
  the client side. Custom UIs must check this flag before calling.
10
10
 
@@ -59,7 +59,8 @@ client-side using the exchange rate available on the platform.
59
59
 
60
60
  ## Refresh
61
61
 
62
- - 30 s SDK cache per `jp_template_id`.
62
+ - 30 s SDK cache per page — keyed by `jp_template_id` + `limit` +
63
+ `offset`, so each page is cached independently.
63
64
  - Cache clears on jackpot-win push events — when the pot explodes, the
64
65
  new winner row appears on the next call.
65
66
  - Cache also clears on opt-in / opt-out.
@@ -13,31 +13,43 @@
13
13
  field. Consumers apply the bucketing filter chain below themselves.
14
14
 
15
15
  ## Status bucketing
16
- Partition the array using this **priority order — first match wins**:
16
+ Partition the array using this **priority order — first match wins** —
17
+ reading the raw state fields directly (NOT `availability_status`; see the
18
+ note below):
17
19
 
18
- 1. **Missed** — time window passed before completion. Test:
19
- `(!is_completed) && ((is_requires_optin && is_opted_in || !is_requires_optin)`
20
- ` && time_limit_ms && dt_start && (dt_start + time_limit_ms) < Date.now())`
21
- `|| (active_till_ts && active_till_ts < Date.now())`.
22
- Sort: `position` ASC.
23
- 2. **Completed** — `is_completed === true`, OR for missions of type
24
- `AchievementStatus.RecurringUponCompletion`,
25
- `max_completion_count === completion_count` (cap reached) OR
26
- `completion_count > 0` (at least one cycle completed).
20
+ 1. **Missed / Expired** — not completed and the window has closed:
21
+ `(!is_completed) && ((time_limit_ms && dt_start && (dt_start + time_limit_ms) < Date.now())`
22
+ `|| (active_till_ts && active_till_ts < Date.now()))`.
23
+ Do NOT gate this on opt-in — an opt-in mission whose window closed
24
+ before the user ever opted in still belongs in Missed. Sort: `position` ASC.
25
+ 2. **Completed** — `is_completed === true`, OR (recurring-upon-completion
26
+ missions) at least one cycle done / the cap reached:
27
+ `completion_count > 0`, or `max_completion_count != null && completion_count >= max_completion_count`.
28
+ `is_completed` NEVER flips for recurring-upon-completion missions, so use
29
+ `completion_count`; a non-null `completion_count` is what identifies the
30
+ type, and `max_completion_count === null` means an INFINITE cap (still
31
+ recurring), so only compare against it when it is set.
27
32
  Sort: `complete_date_ts` DESC (most recent first).
28
33
  3. **Locked** — `is_locked === true`, OR not yet available
29
34
  (`active_from_ts > Date.now()`). Sort: `position` ASC.
30
- 4. **Available (in-progress)** — none of the above.
31
- Sort: `position` ASC.
35
+ 4. **In progress** — `is_opted_in === true`, OR (no opt-in required and
36
+ `progress > 0`). Sort: `position` ASC.
37
+ 5. **Available** — everything else: opt-in required but not yet joined, or
38
+ an unrestricted mission not yet started. Sort: `position` ASC.
32
39
 
33
40
  Each mission belongs to exactly ONE bucket. Many UIs render these as
34
- status tabs / sections. The `availability_status` field
35
- ([AchievementAvailabilityStatus](../../api/enumerations/AchievementAvailabilityStatus.md)) is authoritative for **timer /
36
- window state** (which countdown to show, whether the window has
37
- elapsed) — but it is NOT a substitute for bucketing: distinguishing
38
- "locked" from "opt-in required" requires reading `is_locked` and
39
- `is_opted_in` directly. An "Overview" tab curating featured +
40
- in-progress + a sample locked is a common pattern.
41
+ status tabs / sections; an "Overview" tab curating featured + in-progress +
42
+ a sample locked is a common pattern.
43
+
44
+ **Do not bucket by `availability_status`.** That field
45
+ ([AchievementAvailabilityStatus](../../api/enumerations/AchievementAvailabilityStatus.md))
46
+ is the **timer / window** signal only — which countdown to show, whether the
47
+ window elapsed. It does NOT read `completion_count`, so for
48
+ recurring-upon-completion missions it reports a stale `Missed*` value from the
49
+ just-elapsed cycle even after `dt_start` / `active_till_ts` are cleared for the
50
+ next attempt — using it to bucket sends recurring missions to the wrong tab.
51
+ Distinguishing "locked" from "opt-in required" likewise needs `is_locked` /
52
+ `is_opted_in` read directly.
41
53
 
42
54
  ## Mission card / tile (list view)
43
55
 
@@ -53,7 +65,10 @@ Fields to render on the card:
53
65
  - Description (fallback chain): `description` → `unlock_mission_description`
54
66
  (when `is_locked`) → `tasks[0].name` (when no description and tasks
55
67
  exist).
56
- - Progress bar — render only when `progress > 0` (the 0–100 integer).
68
+ - Progress bar — render only when `progress > 0` (the 0–100 integer),
69
+ with one exception: a mission that requires opt-in and isn't opted in
70
+ yet (`is_requires_optin && !is_opted_in`) shows the bar at 0%, so the
71
+ card/modal signals it has a progress track waiting behind opt-in.
57
72
  Hide for completed recurring missions (`AchievementStatus.RecurringUponCompletion`
58
73
  on the Completed tab) to avoid showing residual percentage from a
59
74
  prior cycle.
@@ -103,8 +118,11 @@ Top-to-bottom structure (omit sections whose source field is empty):
103
118
  list is redundant). Each task row: completion indicator
104
119
  (checkbox/circle) + `task.name`. Append "N / M" using
105
120
  `execution_count_actual / execution_count_expected` when the
106
- operator has enabled count display. Show a points stamp for
107
- tasks with `points_reward > 0`.
121
+ operator has enabled count display. A single task can grant MORE
122
+ THAN ONE reward type — render one reward badge per non-zero amount
123
+ among `points_reward`, `gems_reward` and `diamonds_reward` (stack
124
+ them when a task grants several), each with that reward type's icon.
125
+ Don't assume points-only.
108
126
  13. Progress bar (conditional, same rule as card).
109
127
  14. Reward block (`reward`).
110
128
  15. Related games — only games where `game_public_meta.enabled === true`.
@@ -193,8 +211,10 @@ on click — it does NOT wait for the claim RPC to succeed. Consequences:
193
211
  Missions stay visible in the Missed bucket unless an operator
194
212
  config hides expired missions after N days.
195
213
  - **In progress**: default styling.
196
- - **Opt-in required**: same as in-progress; the status chip alone
197
- signals "opt-in required".
214
+ - **Opt-in required** (`is_requires_optin && !is_opted_in`): styled like
215
+ in-progress, but the status chip carries a "Requires opt-in" label
216
+ (not "Available") to signal the mission needs opt-in before progress
217
+ starts; pair it with the 0%-progress bar noted above.
198
218
  - **Featured**: replace the ribbon (when no `ribbon` is set) with a
199
219
  "featured" modifier; some brands use a gold border / glow.
200
220
  - **Claimable** (claim button visible): add a "claimable" modifier
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartico/public-api",
3
- "version": "0.0.411",
3
+ "version": "0.0.413",
4
4
  "description": "Smartico public API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -17,7 +17,7 @@ interface JackpotPublicMeta {
17
17
  /**
18
18
  * Custom data as string or JSON string that can be used in API to build custom UI
19
19
  * You can request from Smartico to define fields for your specific case that will be managed from Smartico BackOffice
20
- * Read more here - <https://help.smartico.ai/welcome/products/general-concepts/custom-fields-attributes>
20
+ * Read more here - <https://help.smartico.ai/welcome/products/tools-and-guides/custom-fields-attributes>
21
21
  */
22
22
  custom_data: string;
23
23
  }
@@ -17,7 +17,7 @@ export interface LevelPublicMeta {
17
17
  /**
18
18
  * Custom data as string or JSON string that can be used in API to build custom UI
19
19
  * You can request from Smartico to define fields for your specific case that will be managed from Smartico BackOffice
20
- * Read more here - https://help.smartico.ai/welcome/products/general-concepts/custom-fields-attributes
20
+ * Read more here - https://help.smartico.ai/welcome/products/tools-and-guides/custom-fields-attributes
21
21
  */
22
22
  custom_data?: string;
23
23
  }
@@ -69,6 +69,8 @@ export interface SAWTemplate {
69
69
 
70
70
  /** Prize Drop only: when true, the pushed prize requires an explicit claim by the user before it is credited */
71
71
  requires_prize_claim?: boolean;
72
+ /** Prize Drop only: when true, the pushed prize requires a manual claim by the user before it is credited. The difference between this and `requires_prize_claim` is that requires_manual_claim gives the user the ability to cancel the claim. */
73
+ requires_manual_claim?: boolean;
72
74
 
73
75
  /** Timezone offset in minutes used to evaluate the template's period-based rules (UTC minus local, as in JS `Date.getTimezoneOffset()`) */
74
76
  relative_period_timezone?: number;
@@ -25,7 +25,7 @@ interface RafflePublicMeta {
25
25
  /**
26
26
  * Custom data as string or JSON string that can be used in API to build custom UI
27
27
  * You can request from Smartico to define fields for your specific case that will be managed from Smartico BackOffice
28
- * Read more here - <https://help.smartico.ai/welcome/products/general-concepts/custom-fields-attributes>
28
+ * Read more here - <https://help.smartico.ai/welcome/products/tools-and-guides/custom-fields-attributes>
29
29
  */
30
30
  custom_data: string;
31
31
 
@@ -873,21 +873,21 @@ export interface TLevel {
873
873
  /**
874
874
  * The counter of 1st metric used to reach the Level.
875
875
  * Relevant in case of using advanced leveling logic
876
- * https://help.smartico.ai/welcome/more/release-notes/september-2022#new-logic-for-leveling-users
876
+ * https://help.smartico.ai/welcome/products/release-notes/september-2022#new-logic-for-leveling-users
877
877
  *
878
878
  */
879
879
  required_level_counter_1: number;
880
880
  /**
881
881
  * The counter of 2nd metric used to reach the Level.
882
882
  * Relevant in case of using advanced leveling logic
883
- * https://help.smartico.ai/welcome/more/release-notes/september-2022#new-logic-for-leveling-users
883
+ * https://help.smartico.ai/welcome/products/release-notes/september-2022#new-logic-for-leveling-users
884
884
  *
885
885
  */
886
886
  required_level_counter_2: number;
887
887
  /**
888
888
  * Custom data as string or JSON string that can be used in API to build custom UI
889
889
  * You can request from Smartico to define fields for your specific case that will be managed from Smartico BackOffice
890
- * Read more here - https://help.smartico.ai/welcome/products/general-concepts/custom-fields-attributes
890
+ * Read more here - https://help.smartico.ai/welcome/products/tools-and-guides/custom-fields-attributes
891
891
  */
892
892
  custom_data: string;
893
893
  }
@@ -332,7 +332,9 @@ export class WSAPIJackpots extends WSAPIClans {
332
332
  * user-currency display is needed, the consumer must convert client-side.
333
333
  *
334
334
  * **Refresh**
335
- * - The SDK caches per `jp_template_id` for 30 seconds.
335
+ * - The SDK caches each page separately (per `jp_template_id` +
336
+ * `limit` + `offset`) for 30 seconds, so paging back and forth is
337
+ * served from cache and each page keeps its own fresh copy.
336
338
  * - Caches clear on jackpot-win push events and on opt-in / opt-out.
337
339
  *
338
340
  * **Error handling**
@@ -375,8 +377,11 @@ export class WSAPIJackpots extends WSAPIClans {
375
377
  /** Jackpot template ID (required). */
376
378
  jp_template_id?: number;
377
379
  }): Promise<JackpotWinnerHistory[]> {
380
+ // Cache per (jp_template_id, limit, offset) so paging or switching
381
+ // jackpot within the TTL doesn't return a colliding winners list.
382
+ const cacheKey = `${onUpdateContextKey.JackpotWinners}${jp_template_id}:${limit}:${offset}`;
378
383
  return OCache.use(
379
- onUpdateContextKey.JackpotWinners + jp_template_id,
384
+ cacheKey,
380
385
  ECacheContext.WSAPI,
381
386
  () => this.api.getJackpotWinnersT(this.userExtId, limit, offset, jp_template_id),
382
387
  JACKPOT_WINNERS_CACHE_SEC,
@@ -66,18 +66,46 @@ export class WSAPIMissions extends WSAPIGeneral {
66
66
  * `only_in_custom_section: true` are intended for their custom-section
67
67
  * view only and should be hidden from the main mission list.
68
68
  *
69
- * **Reading state from the returned mission**
70
- * Drive availability chips ("missed", "coming soon", "needs opt-in",
71
- * "in progress", "expired") from `availability_status` (enum
72
- * {@link AchievementAvailabilityStatus}) — it's the canonical derived
73
- * state and reflects all server-side timing/visibility rules in one
74
- * field. For time-limited and recurring missions, `dt_start` doubles
75
- * as the opt-in timestamp (for opt-in missions) or unlock timestamp
76
- * (for previously-locked missions); the expiration of a time-limited
77
- * mission is `dt_start + time_limit_ms`. `next_recurrence_date_ts`
78
- * is populated for `RECURRING` / `RECURRING_QUANTITY` missions but
79
- * is no longer meaningful once the mission's `active_till_ts` has
80
- * passed.
69
+ * **Status bucketing (which tab / section a mission belongs to)**
70
+ * There is no pre-computed bucket field — assign each mission to exactly
71
+ * ONE section reading the raw state fields directly (NOT `availability_status`;
72
+ * see "Timers" below). Priority order, FIRST match wins:
73
+ * 1. **Missed / Expired** — not completed and the window has closed:
74
+ * `!is_completed && ((time_limit_ms && dt_start && dt_start + time_limit_ms < Date.now())`
75
+ * `|| (active_till_ts && active_till_ts < Date.now()))`. Do NOT gate this on
76
+ * opt-in — an opt-in mission whose window closed before the user ever
77
+ * opted in is still Missed. Sort by `position` ASC.
78
+ * 2. **Completed** — `is_completed === true`, OR (recurring-upon-completion
79
+ * missions) at least one cycle done / the cap reached — see the recurring
80
+ * caveats below. Sort by `complete_date_ts` DESC.
81
+ * 3. **Locked** — `is_locked === true`, OR not yet started
82
+ * (`active_from_ts > Date.now()`). Sort by `position` ASC.
83
+ * 4. **In-progress** — `is_opted_in === true`, OR (no opt-in required and
84
+ * `progress > 0`). Sort by `position` ASC.
85
+ * 5. **Available** — everything else (opt-in required but not yet joined, or
86
+ * an unrestricted mission not yet started). Sort by `position` ASC.
87
+ *
88
+ * **Recurring-upon-completion caveats** (the common mis-bucketing trap):
89
+ * - `is_completed` NEVER flips true for a recurring-upon-completion mission
90
+ * (only for one-shot missions) — detect a completed cycle from
91
+ * `completion_count > 0`, not `is_completed`.
92
+ * - A non-null `completion_count` is what identifies a recurring-upon-completion
93
+ * mission. `max_completion_count === null` means an INFINITE cap (still
94
+ * recurring — never read null as "not recurring"), so only test
95
+ * `completion_count >= max_completion_count` when `max_completion_count` is set.
96
+ *
97
+ * **Timers & timestamps** (display only — NOT bucketing)
98
+ * `availability_status` (enum {@link AchievementAvailabilityStatus}) is the
99
+ * timer/window signal: use it to pick WHICH countdown to show and whether the
100
+ * window has elapsed — NOT to choose the section. It does not read
101
+ * `completion_count`, and between cycles the server may keep reporting the
102
+ * just-elapsed cycle's `Missed*` value even after `dt_start` / `active_till_ts`
103
+ * are cleared for the next attempt, so bucketing by it sends recurring missions
104
+ * to the wrong tab. For time-limited / opt-in missions `dt_start` is the opt-in
105
+ * timestamp (or unlock timestamp for previously-locked missions), and a
106
+ * time-limited mission expires at `dt_start + time_limit_ms`.
107
+ * `next_recurrence_date_ts` is populated for `RECURRING` / `RECURRING_QUANTITY`
108
+ * missions but is no longer meaningful once `active_till_ts` has passed.
81
109
  *
82
110
  * **Refresh after a mutation**
83
111
  * After `requestMissionOptIn(...)` or `requestMissionClaimReward(...)`