@smartico/public-api 0.0.379 → 0.0.380

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 (99) hide show
  1. package/.nvmrc +1 -1
  2. package/README.md +31 -2
  3. package/dist/Store/BuyStoreItemErrorCode.d.ts +9 -1
  4. package/dist/Tournaments/TournamentRegistrationError.d.ts +3 -1
  5. package/dist/WSAPI/WSAPI.d.ts +13 -1235
  6. package/dist/WSAPI/WSAPIAvatars.d.ts +78 -0
  7. package/dist/WSAPI/WSAPIBase.d.ts +71 -0
  8. package/dist/WSAPI/WSAPIBonuses.d.ts +26 -0
  9. package/dist/WSAPI/WSAPIClans.d.ts +388 -0
  10. package/dist/WSAPI/WSAPIGamePick.d.ts +308 -0
  11. package/dist/WSAPI/WSAPIGeneral.d.ts +30 -0
  12. package/dist/WSAPI/WSAPIInbox.d.ts +126 -0
  13. package/dist/WSAPI/WSAPIJackpots.d.ts +109 -0
  14. package/dist/WSAPI/WSAPILeaderBoard.d.ts +25 -0
  15. package/dist/WSAPI/WSAPIMiniGames.d.ts +94 -0
  16. package/dist/WSAPI/WSAPIMissions.d.ts +517 -0
  17. package/dist/WSAPI/WSAPIRaffles.d.ts +119 -0
  18. package/dist/WSAPI/WSAPIStore.d.ts +656 -0
  19. package/dist/WSAPI/WSAPITournaments.d.ts +501 -0
  20. package/dist/WSAPI/WSAPITypes.d.ts +145 -85
  21. package/dist/WSAPI/WSAPIUser.d.ts +383 -0
  22. package/dist/index.js +3818 -1528
  23. package/dist/index.js.map +1 -1
  24. package/dist/index.modern.mjs +3180 -981
  25. package/dist/index.modern.mjs.map +1 -1
  26. package/docs/api/README.md +56 -2
  27. package/docs/api/classes/WSAPIAvatars.md +116 -0
  28. package/docs/api/classes/WSAPIBonuses.md +50 -0
  29. package/docs/api/classes/WSAPIClans.md +66 -0
  30. package/docs/api/classes/WSAPIGamePick.md +181 -0
  31. package/docs/api/classes/WSAPIGeneral.md +63 -0
  32. package/docs/api/classes/WSAPIInbox.md +277 -0
  33. package/docs/api/classes/WSAPIJackpots.md +185 -0
  34. package/docs/api/classes/WSAPILeaderBoard.md +39 -0
  35. package/docs/api/classes/WSAPIMiniGames.md +175 -0
  36. package/docs/api/classes/WSAPIMissions.md +611 -0
  37. package/docs/api/classes/WSAPIRaffles.md +195 -0
  38. package/docs/api/classes/WSAPIStore.md +744 -0
  39. package/docs/api/classes/WSAPITournaments.md +104 -0
  40. package/docs/api/classes/WSAPIUser.md +200 -0
  41. package/docs/api/enumerations/AchievementClaimPeriodTypeId.md +13 -0
  42. package/docs/api/enumerations/BuyStoreItemErrorCode.md +32 -0
  43. package/docs/api/interfaces/ClanPrizePublicMeta.md +41 -0
  44. package/docs/api/interfaces/ClanPrizeStructureEntry.md +7 -1
  45. package/docs/api/interfaces/ClanPublicMeta.md +4 -0
  46. package/docs/api/interfaces/SAWTemplateUI.md +10 -0
  47. package/docs/api/interfaces/TAchCategory.md +19 -4
  48. package/docs/api/interfaces/TBuyStoreItemResult.md +26 -8
  49. package/docs/api/interfaces/TMissionClaimRewardResult.md +14 -3
  50. package/docs/api/interfaces/TMissionOptInResult.md +10 -3
  51. package/docs/api/interfaces/TMissionOrBadge.md +6 -2
  52. package/docs/api/interfaces/TStoreItem.md +21 -1
  53. package/docs/api/interfaces/TTournamentDetailed.md +8 -0
  54. package/docs/api/interfaces/UserAchievement.md +1 -1
  55. package/docs/ui/clans/UIGuide_getClanInfo.md +153 -0
  56. package/docs/ui/clans/UIGuide_getClans.md +172 -0
  57. package/docs/ui/clans/UIGuide_joinClan.md +196 -0
  58. package/docs/ui/missions/UIGuide_getAchCategories.md +17 -0
  59. package/docs/ui/missions/UIGuide_getBadges.md +237 -0
  60. package/docs/ui/missions/UIGuide_getMissions.md +268 -0
  61. package/docs/ui/missions/UIGuide_requestMissionClaimReward.md +21 -0
  62. package/docs/ui/missions/UIGuide_requestMissionOptIn.md +16 -0
  63. package/docs/ui/store/UIGuide_buyStoreItem.md +133 -0
  64. package/docs/ui/store/UIGuide_getStoreCategories.md +19 -0
  65. package/docs/ui/store/UIGuide_getStoreItems.md +264 -0
  66. package/docs/ui/store/UIGuide_getStorePurchasedItems.md +122 -0
  67. package/docs/ui/tournaments/UIGuide_getClanTournamentPlayers.md +140 -0
  68. package/docs/ui/tournaments/UIGuide_getTournamentInstanceInfo.md +265 -0
  69. package/docs/ui/tournaments/UIGuide_getTournamentsList.md +236 -0
  70. package/docs/ui/tournaments/UIGuide_registerInTournament.md +156 -0
  71. package/docs/ui/user/UIGuide_getLevels.md +162 -0
  72. package/docs/ui/user/UIGuide_getUserProfile.md +213 -0
  73. package/package.json +3 -3
  74. package/scripts/postdoc-cleanup.js +195 -0
  75. package/src/Missions/MissionsUtils.ts +5 -2
  76. package/src/Store/BuyStoreItemErrorCode.ts +8 -0
  77. package/src/Store/StoreItem.ts +1 -0
  78. package/src/Store/StoreItemPurchased.ts +1 -0
  79. package/src/Store/StoreItemType.ts +1 -1
  80. package/src/Tournaments/TournamentRegistrationError.ts +4 -0
  81. package/src/WSAPI/WSAPI.ts +27 -2007
  82. package/src/WSAPI/WSAPIAvatars.ts +127 -0
  83. package/src/WSAPI/WSAPIBase.ts +93 -0
  84. package/src/WSAPI/WSAPIBonuses.ts +54 -0
  85. package/src/WSAPI/WSAPIClans.ts +417 -0
  86. package/src/WSAPI/WSAPIGamePick.ts +382 -0
  87. package/src/WSAPI/WSAPIGeneral.ts +57 -0
  88. package/src/WSAPI/WSAPIInbox.ts +222 -0
  89. package/src/WSAPI/WSAPIJackpots.ts +212 -0
  90. package/src/WSAPI/WSAPILeaderBoard.ts +40 -0
  91. package/src/WSAPI/WSAPIMiniGames.ts +181 -0
  92. package/src/WSAPI/WSAPIMissions.ts +572 -0
  93. package/src/WSAPI/WSAPIRaffles.ts +175 -0
  94. package/src/WSAPI/WSAPIStore.ts +732 -0
  95. package/src/WSAPI/WSAPITournaments.ts +541 -0
  96. package/src/WSAPI/WSAPITypes.ts +145 -87
  97. package/src/WSAPI/WSAPIUser.ts +456 -0
  98. package/tsconfig.json +17 -1
  99. package/docs/api/classes/WSAPI.md +0 -1927
@@ -0,0 +1,94 @@
1
+ import { SAWSpinsCountPush } from '../MiniGames';
2
+ import { TMiniGamePlayResult, TMiniGameTemplate, TMiniGamePlayBatchResult, TSawHistory } from './WSAPITypes';
3
+ import { WSAPIRaffles } from './WSAPIRaffles';
4
+ /** @group MiniGames */
5
+ export declare class WSAPIMiniGames extends WSAPIRaffles {
6
+ /**
7
+ * Returns the list of mini-games configured for the current user (not filtered by spin availability or Widget visibility).
8
+ * The returned list of mini-games is cached for 30 seconds. But you can pass the onUpdate callback as a parameter. Note that each time you call getMiniGames with a new onUpdate callback, the old one will be overwritten by the new one.
9
+ * The onUpdate callback will be called on available spin count change, if mini-game has increasing jackpot per spin or won prize is spin/jackpot and if max count of the available user spins equals one, also if the spins were issued to the user manually in the BO. Updated templates will be passed to onUpdate callback.
10
+ *
11
+ * **Example**:
12
+ * ```
13
+ * _smartico.api.getMiniGames().then((result) => {
14
+ * console.log(result);
15
+ * });
16
+ * ```
17
+ *
18
+ * **Example in the Visitor mode**:
19
+ * ```
20
+ * _smartico.vapi('EN').getMiniGames().then((result) => {
21
+ * console.log(result);
22
+ * });
23
+ * ```
24
+ *
25
+ */
26
+ getMiniGames({ onUpdate }?: {
27
+ onUpdate?: (data: TMiniGameTemplate[]) => void;
28
+ }): Promise<TMiniGameTemplate[]>;
29
+ /**
30
+ * Returns the list of mini-games based on the provided parameters. "Limit" and "offset" indicate the range of items to be fetched.
31
+ * The maximum number of items per request is limited to 20.
32
+ * You can leave this params empty and by default it will return list of mini-games ranging from 0 to 20.
33
+ * The returned list of mini-games history is cached for 30 seconds.
34
+ *
35
+ * **Example**:
36
+ * ```
37
+ * _smartico.api.getMiniGamesHistory().then((result) => {
38
+ * console.log(result);
39
+ * });
40
+ * ```
41
+ *
42
+ * **Visitor mode: not supported**
43
+ */
44
+ getMiniGamesHistory({ limit, offset, saw_template_id, }: {
45
+ limit?: number;
46
+ offset?: number;
47
+ saw_template_id?: number;
48
+ }): Promise<TSawHistory[]>;
49
+ /**
50
+ * Plays the specified by template_id mini-game on behalf of user and returns prize_id or err_code
51
+ * After playMiniGame is called, you can call getMiniGames to get the list of mini-games.The returned list of mini-games is cached for 30 seconds. But you can pass the onUpdate callback as a parameter. Note that each time you call playMiniGame with a new onUpdate callback, the old one will be overwritten by the new one.
52
+ * The onUpdate callback will be called on available spin count change, if mini-game has increasing jackpot per spin or won prize is spin/jackpot and if max count of the available user spins equals one, also if the spins were issued to the user manually in the BO. Updated templates will be passed to onUpdate callback.
53
+ *
54
+ * **Example**:
55
+ * ```
56
+ * _smartico.api.playMiniGame(55).then((result) => {
57
+ * console.log(result);
58
+ * });
59
+ * ```
60
+ *
61
+ * **Visitor mode: not supported**
62
+ */
63
+ playMiniGame(template_id: number, { onUpdate }?: {
64
+ onUpdate?: (data: TMiniGameTemplate[]) => void;
65
+ }): Promise<TMiniGamePlayResult>;
66
+ /**
67
+ * Sends the acknowledge request with specific client_request_id from minigame history in order to claim prize
68
+ * **Example**:
69
+ * ```
70
+ * _smartico.api.miniGameWinAcknowledgeRequest('2a189322-31bb-4119-b943-bx7868ff8dc3').then((result) => {
71
+ * console.log(result);
72
+ * });
73
+ * ```
74
+ */
75
+ miniGameWinAcknowledgeRequest(request_id: string): Promise<import("../MiniGames").SAWDoAknowledgeResponse>;
76
+ /**
77
+ * Plays the specified by template_id mini-game on behalf of user spin_count times and returns array of the prizes
78
+ * After playMiniGameBatch is called, you can call getMiniGames to get the list of mini-games. The returned list of mini-games is cached for 30 seconds. But you can pass the onUpdate callback as a parameter. Note that each time you call playMiniGameBatch with a new onUpdate callback, the old one will be overwritten by the new one.
79
+ * The onUpdate callback will be called on available spin count change, if mini-game has increasing jackpot per spin or won prize is spin/jackpot and if max count of the available user spins equals one, also if the spins were issued to the user manually in the BO. Updated templates will be passed to onUpdate callback.
80
+ *
81
+ * **Example**:
82
+ * ```
83
+ * _smartico.api.playMiniGameBatch(55, 10).then((result) => {
84
+ * console.log(result);
85
+ * });
86
+ * ```
87
+ * **Visitor mode: not supported**
88
+ */
89
+ playMiniGameBatch(template_id: number, spin_count: number, { onUpdate }?: {
90
+ onUpdate?: (data: TMiniGameTemplate[]) => void;
91
+ }): Promise<TMiniGamePlayBatchResult[]>;
92
+ protected updateOnSpin(data: SAWSpinsCountPush): Promise<void>;
93
+ protected reloadMiniGameTemplate(): Promise<void>;
94
+ }
@@ -0,0 +1,517 @@
1
+ import { TAchCategory, TMissionClaimRewardResult, TMissionOptInResult, TMissionOrBadge } from './WSAPITypes';
2
+ import { WSAPIGeneral } from './WSAPIGeneral';
3
+ /** @group Missions */
4
+ export declare class WSAPIMissions extends WSAPIGeneral {
5
+ /**
6
+ * Returns all missions visible to the current user, scoped server-side
7
+ * to what the user is qualified to see. Optionally subscribes to live
8
+ * updates via `onUpdate`: the callback is invoked with the full, refreshed
9
+ * mission array whenever the server pushes a mission-state-changing event.
10
+ *
11
+ * The returned list is the canonical source of truth for mission state
12
+ * (`is_opted_in`, `progress`, `is_completed`, `completion_count`, etc.).
13
+ * Consumers should NEVER mutate it optimistically — always wait for the
14
+ * `onUpdate` callback (or a fresh `getMissions()` call after the 30s cache
15
+ * window expires) to observe the new state.
16
+ *
17
+ * @remarks
18
+ * **Subscription model (`onUpdate`)**
19
+ * The callback receives the FULL refreshed mission array (never a
20
+ * diff/patch). Each subsequent call to `getMissions({ onUpdate })`
21
+ * REPLACES the prior callback — only one active subscriber at a time.
22
+ * Pass `onUpdate: undefined` (or omit it) to keep the prior callback in
23
+ * place; the callback is never auto-cleared.
24
+ *
25
+ * **Update triggers** — the callback fires when:
26
+ * 1. **Mutation responses**: `requestMissionOptIn(...)` or
27
+ * `requestMissionClaimReward(...)` resolves (any `err_code`).
28
+ * 2. **Asynchronous server pushes**: a user activity (deposit, bet,
29
+ * login, etc.) advances task progress on a task configured to push
30
+ * updates, or completes a mission.
31
+ * 3. **Visibility changes**: the user's level changes, or other
32
+ * gamification visibility tags change.
33
+ *
34
+ * Operator-side BO mission-config edits do NOT push to connected
35
+ * clients — those changes surface only on the next cache miss (after
36
+ * the 30 s TTL) or alongside the next trigger from (1)–(3).
37
+ *
38
+ * **What's in the returned list / what's filtered server-side**
39
+ * The response is pre-filtered by the server. Missions EXCLUDED before
40
+ * reaching the SDK:
41
+ * - Missions in `DRAFT` or `ARCHIVED` status (see {@link AchievementStatus}).
42
+ * - Missions where the user fails visibility conditions. Exception:
43
+ * completed missions may remain visible after the user no longer
44
+ * qualifies (configurable per-brand).
45
+ * - `FEATURED_MANUALLY` missions that are still locked — they appear
46
+ * only after the user unlocks them.
47
+ * - Locked missions configured to hide while locked — UNLESS the
48
+ * mission is configured to expose immediately on unlock (then the
49
+ * locked mission is included as a teaser).
50
+ * - `RECURRING` missions between cycles, until the next cycle starts.
51
+ * - `RECURRING_QUANTITY` missions outside their `active_from_ts` /
52
+ * `active_till_ts` window.
53
+ *
54
+ * Client-side filtering you may still want: missions with
55
+ * `only_in_custom_section: true` are intended for their custom-section
56
+ * view only and should be hidden from the main mission list.
57
+ *
58
+ * **Reading state from the returned mission**
59
+ * Drive availability chips ("missed", "coming soon", "needs opt-in",
60
+ * "in progress", "expired") from `availability_status` (enum
61
+ * {@link AchievementAvailabilityStatus}) — it's the canonical derived
62
+ * state and reflects all server-side timing/visibility rules in one
63
+ * field. For time-limited and recurring missions, `dt_start` doubles
64
+ * as the opt-in timestamp (for opt-in missions) or unlock timestamp
65
+ * (for previously-locked missions); the expiration of a time-limited
66
+ * mission is `dt_start + time_limit_ms`. `next_recurrence_date_ts`
67
+ * is populated for `RECURRING` / `RECURRING_QUANTITY` missions but
68
+ * is no longer meaningful once the mission's `active_till_ts` has
69
+ * passed.
70
+ *
71
+ * **Refresh after a mutation**
72
+ * After `requestMissionOptIn(...)` or `requestMissionClaimReward(...)`
73
+ * resolves, the SDK auto-refreshes the mission cache; the `onUpdate`
74
+ * callback fires with the new array shortly after. `is_opted_in`,
75
+ * `progress`, and `is_completed` flip on the refreshed mission — do
76
+ * NOT mutate them optimistically while the round-trip is pending.
77
+ * Render any pending state from your own loading flag.
78
+ *
79
+ * **UI guidance**: see [UI Guide — `getMissions`](../../docs/ui/missions/UIGuide_getMissions.md).
80
+ *
81
+ * @param params Optional. Omit to fetch without subscribing.
82
+ * @param params.onUpdate Callback invoked with the full refreshed
83
+ * mission array on every server-pushed update
84
+ * (after opt-in / claim-reward calls, or when
85
+ * the server pushes an asynchronous
86
+ * mission-state change). Each call to
87
+ * `getMissions` overwrites the prior callback.
88
+ * Never fires in visitor mode.
89
+ * @returns Promise resolving to the current list of
90
+ * missions visible to the user. Empty array if
91
+ * the user has no missions (or if the visitor
92
+ * proxy user has none configured).
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * // 1. Initial fetch + subscribe to live updates
97
+ * const missions = await window._smartico.api.getMissions({
98
+ * onUpdate: (refreshed) => {
99
+ * console.log('[smartico] mission list refreshed — re-render the entire mission list UI from this array, do not merge with prior state:', refreshed);
100
+ *
101
+ * // 2. onUpdate fires for: opt-in/claim responses, task-progress
102
+ * // pushes that complete a mission or move a "pushToClient" task,
103
+ * // and user-level changes. Treat each call as authoritative.
104
+ * const claimable = refreshed.filter(m =>
105
+ * m.is_completed && m.requires_prize_claim && !m.prize_claimed_date_ts,
106
+ * );
107
+ * if (claimable.length > 0) {
108
+ * console.log('[smartico] there are unclaimed mission prizes — surface a "Claim" CTA on each of these missions:', claimable.map(m => m.id));
109
+ * }
110
+ * },
111
+ * });
112
+ *
113
+ * // 3. Filter/render from the returned list. The server already excludes
114
+ * // DRAFT/ARCHIVED missions and ones the user can't see. You may need
115
+ * // client-side filters for view-specific concerns (custom sections,
116
+ * // completed/missed tabs).
117
+ * const generalView = missions
118
+ * .filter(m => !m.only_in_custom_section)
119
+ * .sort((a, b) => (a.position ?? 0) - (b.position ?? 0));
120
+ *
121
+ * console.log('[smartico] initial mission list ready — render', generalView.length, 'missions sorted by position');
122
+ *
123
+ * // 4. Visitor-mode equivalent: onUpdate is accepted but never fires.
124
+ * // Re-poll if you need fresh data.
125
+ * // const visitorMissions = await window._smartico.vapi('EN').getMissions();
126
+ * // console.log('[smartico] visitor missions are the brand proxy user\'s — per-user fields are not meaningful');
127
+ * ```
128
+ */
129
+ getMissions({ onUpdate }?: {
130
+ onUpdate?: (data: TMissionOrBadge[]) => void;
131
+ }): Promise<TMissionOrBadge[]>;
132
+ /**
133
+ * Returns all the badges available to the current user.
134
+ *
135
+ * Badges are completion-tracked achievements that auto-unlock once the user
136
+ * meets their criteria — there is no opt-in step, no claim step, and no
137
+ * task-description reveal. Contrast with {@link getMissions}, which returns
138
+ * the same `TMissionOrBadge[]` shape but represents explicit opt-in flows.
139
+ *
140
+ * @remarks
141
+ * **Why no `onUpdate` callback?**
142
+ * Unlike `getMissions({ onUpdate })`, this method does NOT accept an
143
+ * `onUpdate` subscription. Internally the SDK never refreshes the `Badges`
144
+ * cache from server pushes: the achievement-related push events
145
+ * (mission opt-in / claim / reload) refresh the missions cache, NOT
146
+ * the badges cache. The badges cache is flushed only by:
147
+ * - its 30-second TTL
148
+ * - a full SDK cache wipe at login / logout
149
+ *
150
+ * **How to refresh the badge list**
151
+ * If you need near-live badge state, poll manually after the TTL expires.
152
+ * The first call inside the 30 s window returns the cached payload; the
153
+ * first call after the TTL triggers a fresh server round-trip. Example:
154
+ * ```ts
155
+ * setInterval(async () => {
156
+ * const badges = await window._smartico.api.getBadges();
157
+ * console.log('[smartico] badge list polled — re-render badge grid from this array', badges);
158
+ * }, 30_000);
159
+ * ```
160
+ * Alternatively, re-fetch on a domain event your app already handles
161
+ * (e.g. after the user finishes a game round or claims a bonus).
162
+ *
163
+ * **Differences from missions** (same `TMissionOrBadge` shape, different
164
+ * feature)
165
+ * The opt-in, claim, recurring-cycle, and unlock-description fields on
166
+ * the returned objects are not populated for badges; treat their values
167
+ * as undefined / default. Time windows are absolute calendar timestamps
168
+ * (`active_from_ts` / `active_till_ts`), not opt-in-relative durations —
169
+ * drive availability chips from the SDK-computed `badgeTimeLimitState`
170
+ * (enum {@link BadgesTimeLimitStates}), not `time_limit_ms`. Locking for
171
+ * badges is purely time-based: `is_locked` is `true` only when
172
+ * `badgeTimeLimitState === BadgesTimeLimitStates.BeforeStartDate` (the
173
+ * time window hasn't started yet). The primary navigation field is
174
+ * `category_ids` — call {@link getAchCategories} to resolve category
175
+ * metadata and group badges by category.
176
+ *
177
+ * **Idempotency / Side effects**: fetch-only; safe to call repeatedly.
178
+ * The cache layer deduplicates concurrent calls within the TTL window.
179
+ *
180
+ * **UI guidance**: see [UI Guide — `getBadges`](../../docs/ui/missions/UIGuide_getBadges.md).
181
+ *
182
+ * @returns Promise resolving to `TMissionOrBadge[]`. Every item has
183
+ * `type === 'badge'`. Cached for 30 s under the `Badges` key.
184
+ *
185
+ * @example
186
+ * ```ts
187
+ * const [badges, categories] = await Promise.all([
188
+ * window._smartico.api.getBadges(),
189
+ * window._smartico.api.getAchCategories(),
190
+ * ]);
191
+ *
192
+ * console.log('[smartico] badges fetched — render grouped grid with', badges.length, 'badges across', categories.length, 'categories');
193
+ *
194
+ * for (const category of categories) {
195
+ * const inCategory = badges.filter(b => b.category_ids?.includes(category.id));
196
+ * const completed = inCategory.filter(b => b.is_completed).length;
197
+ * console.log(`[smartico] render category section "${category.name}" header showing ${completed}/${inCategory.length}`);
198
+ *
199
+ * for (const badge of inCategory) {
200
+ * // Use badgeTimeLimitState (not time_limit_ms) for availability chip
201
+ * if (badge.badgeTimeLimitState === 0) { // BadgesTimeLimitStates.BeforeStartDate
202
+ * console.log('[smartico] badge not yet started — render grayscaled card with "Starts on" chip for badge', badge.id);
203
+ * } else if (badge.is_completed) {
204
+ * console.log('[smartico] badge completed — render with completed styling and check-mark for badge', badge.id);
205
+ * } else {
206
+ * console.log('[smartico] badge in progress — render with stage counter (completed_tasks / total) for badge', badge.id);
207
+ * }
208
+ * }
209
+ * }
210
+ *
211
+ * // No onUpdate available — poll if live state matters
212
+ * setInterval(async () => {
213
+ * try {
214
+ * const fresh = await window._smartico.api.getBadges();
215
+ * console.log('[smartico] badge poll tick — diff against previous list and re-render any changed badge cards', fresh);
216
+ * } catch (e) {
217
+ * console.error('[smartico] badge poll failed — keep showing last known state, retry on next tick:', e);
218
+ * }
219
+ * }, 30_000);
220
+ * ```
221
+ */
222
+ getBadges(): Promise<TMissionOrBadge[]>;
223
+ /**
224
+ * Returns the list of active mission/badge categories configured for the current label.
225
+ * Categories are operator-defined groupings used to organize missions and badges into
226
+ * sections, tabs, or filter chips in the gamification UI. The same category list serves
227
+ * BOTH missions and badges — there is no separate "mission categories" vs "badge
228
+ * categories" split on the server.
229
+ *
230
+ * @remarks
231
+ * **What categories are**
232
+ * - Operator-defined groupings, configured per-label by the brand operator.
233
+ * Only active categories are returned; inactive/deleted ones are filtered out.
234
+ * - Each `TAchCategory` exposes `{ id, name, order }`. `name` is the display label;
235
+ * `order` is the relative position (lower = appears first).
236
+ * - The same array covers BOTH missions and badges — categories are not filtered by
237
+ * entity type on the server.
238
+ *
239
+ * **Localization / translation**
240
+ * - `name` is **pre-translated server-side** to the authenticated user's stored language.
241
+ * In visitor mode, the language passed to `_smartico.vapi(lang)` drives the
242
+ * translation. Consumers never need to translate `name` themselves.
243
+ * - Fallback if no translation exists for the user's language: the brand's EN value
244
+ * is returned. The field is never null.
245
+ *
246
+ * **Sort order**
247
+ * The server does NOT pre-sort. Sort client-side before rendering:
248
+ * `categories.sort((a, b) => a.order - b.order)`.
249
+ *
250
+ * **How missions/badges join to categories**
251
+ * Each `TMissionOrBadge` exposes `category_ids: number[]` (zero-or-more,
252
+ * many-to-many). A single mission/badge can belong to multiple categories
253
+ * simultaneously, or to none. To render a "category → items" view:
254
+ * `missions.filter(m => m.category_ids.includes(cat.id))`.
255
+ *
256
+ * **Uncategorized items**
257
+ * Items with `category_ids: []` are NOT represented by a synthetic "Other" entry.
258
+ * If your UI needs one, generate it client-side by checking
259
+ * `item.category_ids.length === 0`.
260
+ *
261
+ * **Empty categories**
262
+ * A category may be returned even if zero missions/badges reference it. Filter
263
+ * out empty categories on the consumer side if you don't want to render section
264
+ * headers for them.
265
+ *
266
+ * **Refresh cadence / cache**
267
+ * - The SDK caches the response for 30 seconds. Subsequent calls within that
268
+ * window return the cached array without a network round-trip.
269
+ * - The cache is NOT invalidated by mission/badge push events — operator-driven
270
+ * category changes propagate at the next 30 s cache miss.
271
+ * - Cache is fully cleared on login / logout.
272
+ * - In **visitor mode** additional server-side caching applies on top of the
273
+ * SDK cache; worst-case staleness for an edited/added category is on the order
274
+ * of a few minutes for anonymous viewers.
275
+ *
276
+ * **Idempotency**: safe. Read-only metadata fetch. Cache de-duplicates concurrent calls.
277
+ *
278
+ * **Side effects**: none — pure metadata read.
279
+ *
280
+ * **UI guidance**: see [UI Guide — `getAchCategories`](../../docs/ui/missions/UIGuide_getAchCategories.md).
281
+ *
282
+ * @returns Array of `{ id, name, order }`. Empty array if no active categories are
283
+ * configured for the label. `name` is pre-translated. Order is NOT applied — caller
284
+ * must sort.
285
+ *
286
+ * @example
287
+ * ```ts
288
+ * const categories = await window._smartico.api.getAchCategories();
289
+ *
290
+ * if (categories.length === 0) {
291
+ * console.log('[smartico] no categories configured — render missions/badges as a flat list without section headers');
292
+ * } else {
293
+ * const sorted = [...categories].sort((a, b) => a.order - b.order);
294
+ * console.log('[smartico] categories loaded — render one tab/section per entry in this order:', sorted.map(c => c.name));
295
+ *
296
+ * // Join to missions: render each category as a section
297
+ * const missions = await window._smartico.api.getMissions();
298
+ * for (const cat of sorted) {
299
+ * const items = missions.filter(m => m.category_ids.includes(cat.id));
300
+ * if (items.length === 0) {
301
+ * console.log('[smartico] category has no missions — skip rendering its section header:', cat.name);
302
+ * continue;
303
+ * }
304
+ * console.log(`[smartico] render section "${cat.name}" with ${items.length} mission(s)`);
305
+ * }
306
+ *
307
+ * // Uncategorized items: surface in a caller-provided "Other" bucket if needed
308
+ * const uncategorized = missions.filter(m => m.category_ids.length === 0);
309
+ * if (uncategorized.length > 0) {
310
+ * console.log('[smartico] uncategorized missions exist — render a caller-provided "Other" section; server does NOT return id:-1:', uncategorized.length);
311
+ * }
312
+ * }
313
+ *
314
+ * // Visitor mode — same shape, language driven by vapi(lang) argument
315
+ * const visitorCats = await window._smartico.vapi('DE').getAchCategories();
316
+ * console.log('[smartico] visitor-mode categories (names translated to DE):', visitorCats);
317
+ * ```
318
+ */
319
+ getAchCategories(): Promise<TAchCategory[]>;
320
+ /**
321
+ * Opt the current user in to a mission. The mission must have
322
+ * `is_requires_optin: true` (from `getMissions()`) and must not already
323
+ * be opted-in or locked. After a successful opt-in, the user's task
324
+ * progress starts counting toward this mission — events fired BEFORE
325
+ * opt-in do not count retroactively (except `UNLOCK_ACHIEVEMENT` tasks,
326
+ * which are exempt and can fire pre-opt-in).
327
+ *
328
+ * @remarks
329
+ * **Preconditions**
330
+ * Only call when the mission has `is_requires_optin === true`,
331
+ * `is_opted_in === false`, and `is_locked === false`. Calling on a
332
+ * mission that does not require opt-in is wasted; calling twice returns
333
+ * `40010`.
334
+ *
335
+ * **Error codes** (in `err_code`)
336
+ * - `0` — success; task progress counting begins
337
+ * - `105` — wrong mission id (different label) OR visibility conditions
338
+ * not met. Same code covers both; use `err_message` to disambiguate.
339
+ * - `40010` — already opted-in. Safe to treat as "no-op success"; usually
340
+ * means local mission state was stale (e.g. user opted in from another
341
+ * session/tab).
342
+ * - `40013` — mission not opt-in-able: missing `requires_optin`, in
343
+ * DRAFT/ARCHIVED state, or outside its `active_from_ts` /
344
+ * `active_till_ts` window.
345
+ * - `40014` — mission is locked; user has unlock-tasks remaining.
346
+ * Surface the mission's `unlock_mission_description` to guide them.
347
+ * - other non-zero — generic server error. Surface `err_message` if any.
348
+ *
349
+ * **Time-limited missions**
350
+ * For missions with `time_limit_ms > 0`, the countdown begins at opt-in
351
+ * time, not at mission creation. Server records expiration as
352
+ * `optin_date + time_limit_ms`.
353
+ *
354
+ * **Refresh after success**
355
+ * The SDK refreshes its mission cache automatically on opt-in response;
356
+ * any `onUpdate` callback passed to a prior `getMissions({ onUpdate })`
357
+ * fires with the new state shortly after. No manual re-fetch needed.
358
+ *
359
+ * **Idempotency**: not idempotent. A second call returns `40010`. Guard
360
+ * the call site against double-clicks.
361
+ *
362
+ * **Side effects**: does NOT award points / badges / levels directly.
363
+ * Rewards come from task completion, which is itself gated on opt-in.
364
+ * May affect visibility of other missions whose visibility conditions
365
+ * depend on this opt-in.
366
+ *
367
+ * **UI guidance**: see [UI Guide — `requestMissionOptIn`](../../docs/ui/missions/UIGuide_requestMissionOptIn.md).
368
+ *
369
+ * **Visitor mode: not supported**
370
+ *
371
+ * @param mission_id The mission `id` (from `getMissions()`)
372
+ * @returns `{ err_code, err_message }`; success when `err_code === 0`
373
+ *
374
+ * @example
375
+ * ```ts
376
+ * const missions = await window._smartico.api.getMissions({
377
+ * onUpdate: (m) => console.log('[smartico] mission list updated — re-render mission UI from this new array', m),
378
+ * });
379
+ * const mission = missions.find(m => m.id === missionId);
380
+ *
381
+ * if (!mission || !mission.is_requires_optin || mission.is_opted_in || mission.is_locked) {
382
+ * console.log('[smartico] opt-in not applicable — keep UI as-is');
383
+ * return;
384
+ * }
385
+ *
386
+ * console.log('[smartico] opt-in starting — show loading spinner on opt-in button and disable it to prevent double-clicks');
387
+ * const r = await window._smartico.api.requestMissionOptIn(mission.id);
388
+ * console.log('[smartico] opt-in response received — clear loading spinner');
389
+ *
390
+ * if (r.err_code === 0 || r.err_code === 40010) {
391
+ * console.log('[smartico] opt-in succeeded (or was already done) — onUpdate above will fire with refreshed mission state; no manual re-fetch needed');
392
+ * } else if (r.err_code === 40014) {
393
+ * console.error('[smartico] mission is locked — surface the unlock description as guidance:', mission.unlock_mission_description);
394
+ * } else {
395
+ * console.error('[smartico] opt-in failed — show an error toast with this message to the user:', r.err_message);
396
+ * }
397
+ * ```
398
+ */
399
+ requestMissionOptIn(mission_id: number): Promise<TMissionOptInResult>;
400
+ /**
401
+ * Claim the prize for a completed mission. This is the step that runs
402
+ * AFTER `requestMissionOptIn()` (when applicable) and AFTER the user has
403
+ * completed all of the mission's tasks. Only call when the mission has
404
+ * `requires_prize_claim === true`, `is_completed === true`, and the prize
405
+ * has not already been claimed.
406
+ *
407
+ * The points / bonuses / badge grants associated with the mission are
408
+ * awarded server-side synchronously inside this call (before the response
409
+ * is returned), so a successful response (`err_code === 0`) means the
410
+ * reward has already landed in the user's account.
411
+ *
412
+ * @remarks
413
+ * **Preconditions**
414
+ * Only call when, on the mission object from `getMissions()`:
415
+ * - `is_completed === true`
416
+ * - `requires_prize_claim === true`
417
+ * - `prize_claimed_date_ts == null` (i.e. not already claimed)
418
+ * - `prize_claim_expiration_date` is `null` OR still in the future
419
+ *
420
+ * The `ach_completed_id` argument must be passed straight from the same
421
+ * mission object (`mission.ach_completed_id`). It is a server-side primary
422
+ * key identifying the specific completion row; the SDK consumer should
423
+ * never synthesise or cache it across sessions — always re-read it from a
424
+ * fresh `getMissions()` result.
425
+ *
426
+ * **Error codes** (in `err_code`)
427
+ * - `0` — success; the prize was claimed and rewards have been credited.
428
+ * - `1` — generic server error. Covers several distinct underlying
429
+ * conditions, all collapsed into the same code: stale or wrong
430
+ * `ach_completed_id` (does not match user / mission), the mission no
431
+ * longer requiring a prize claim, the mission being archived/draft,
432
+ * label mismatch, or the completion being too old (server enforces a
433
+ * freshness window of several months). Recovery: re-fetch missions
434
+ * with `getMissions()`; if the mission still appears claimable,
435
+ * surface a generic error.
436
+ * - `40015` — claim window expired (`prize_claim_expiration_date` has
437
+ * passed). Show a "claim period ended" message; do not retry.
438
+ * - `40016` — mission is not completed yet. Indicates a race or a stale
439
+ * local cache. Re-fetch via `getMissions()`; if `is_completed` is still
440
+ * false, the UI should hide the claim button.
441
+ * - `40017` — prize already claimed. Treat as idempotent success: refresh
442
+ * the mission list (auto-refresh will fire) and hide the claim button.
443
+ * Usually means another tab/session already claimed it.
444
+ * - other non-zero — generic server error. Surface `err_message` if any.
445
+ *
446
+ * **Recurring missions**
447
+ * The server transparently handles both one-shot and recurring mission
448
+ * completions. The SDK consumer passes a single `ach_completed_id`
449
+ * regardless of mission type; the server resolves the correct completion.
450
+ *
451
+ * **Refresh after success**
452
+ * On any claim response (success OR failure), the SDK automatically
453
+ * re-fetches the mission list and fires any `onUpdate` callback
454
+ * registered via `getMissions({ onUpdate })`. No manual re-fetch needed.
455
+ * Note: points balance, badges, and level state arrive through their
456
+ * own push channels — subscribe to them separately if your UI shows
457
+ * those values.
458
+ *
459
+ * **Idempotency**: not idempotent at the row level. A second call on the
460
+ * same `ach_completed_id` returns `40017` (already claimed). For a stale
461
+ * `ach_completed_id` the second call returns `1`. Guard the call site
462
+ * against double-clicks; the SDK does not enforce its own in-flight lock.
463
+ *
464
+ * **Side effects** (consumer-observable effects of a successful claim):
465
+ * - Points credited to the user's balance.
466
+ * - CRM-rule activities executed (may grant bonuses, badges; may unlock
467
+ * follow-up missions, which arrive as a later mission auto-refresh).
468
+ * - Analytics / automation events fired downstream; not directly observable
469
+ * in the response, but visible via the mission auto-refresh and any
470
+ * subsequent bonus / badge updates.
471
+ *
472
+ * **UI guidance**: see [UI Guide — `requestMissionClaimReward`](../../docs/ui/missions/UIGuide_requestMissionClaimReward.md).
473
+ *
474
+ * @param mission_id The mission `ach_id` (from `getMissions()`).
475
+ * @param ach_completed_id The completion-row identifier, read from
476
+ * `mission.ach_completed_id` on the same mission
477
+ * object fetched via `getMissions()`. Never
478
+ * fabricate or cache across sessions.
479
+ * @returns `{ err_code, err_message }`; success when `err_code === 0`
480
+ * (or `40017` when treated as idempotent no-op).
481
+ *
482
+ * @example
483
+ * ```ts
484
+ * const missions = await window._smartico.api.getMissions({
485
+ * onUpdate: (m) => console.log('[smartico] mission list updated — re-render mission UI from this new array', m),
486
+ * });
487
+ * const mission = missions.find(m => m.ach_id === missionId);
488
+ *
489
+ * if (
490
+ * !mission ||
491
+ * !mission.is_completed ||
492
+ * !mission.requires_prize_claim ||
493
+ * mission.prize_claimed_date_ts ||
494
+ * (mission.prize_claim_expiration_date && Date.now() >= mission.prize_claim_expiration_date)
495
+ * ) {
496
+ * console.log('[smartico] claim not applicable — keep claim button hidden');
497
+ * return;
498
+ * }
499
+ *
500
+ * console.log('[smartico] claim starting — show loading spinner on claim button and disable it to prevent double-clicks');
501
+ * const r = await window._smartico.api.requestMissionClaimReward(mission.ach_id, mission.ach_completed_id);
502
+ * console.log('[smartico] claim response received — clear loading spinner');
503
+ *
504
+ * if (r.err_code === 0 || r.err_code === 40017) {
505
+ * console.log('[smartico] claim succeeded (or was already claimed) — points/bonuses are credited; mission list auto-refresh will fire via the onUpdate above; hide the claim button');
506
+ * } else if (r.err_code === 40015) {
507
+ * console.error('[smartico] claim window expired — show a "claim period ended" message and remove the claim button:', mission.prize_claim_expiration_date);
508
+ * } else if (r.err_code === 40016) {
509
+ * console.error('[smartico] mission reported as not completed by server — local state was stale; auto-refresh will reconcile, do not retry');
510
+ * } else {
511
+ * console.error('[smartico] claim failed — show an error toast with this message to the user (and re-fetch missions to recover from a stale ach_completed_id):', r.err_message);
512
+ * }
513
+ * ```
514
+ */
515
+ requestMissionClaimReward(mission_id: number, ach_completed_id: number): Promise<TMissionClaimRewardResult>;
516
+ protected updateMissions(): Promise<void>;
517
+ }