# SNACK 3.0 CHALLENGES In the admin panel: Challenges (v2.0): - SNACKUP Challenges - Completed Challenges - Completed Gift Challenges - Challenges Promo Codes New [v3.0] ``` GET ?version=1 POST { version:1 } ex: v2.0 GET /snack/admin/challenge/getList?pagenumber=1&pagesize=20&order=asc v3.0 GET /snack/admin/challenge/getList?pagenumber=1&pagesize=20&order=asc&version=1 ``` Challenges (v3.0): - Challenges (v3.0) [6 challenge types] - Groups (v3.0) - Completed Challenges (v3.0) - Leader Board (Dashboard) ## Type of challenges: | Challenge Type | Value (Int) | | -------- | -------- | | XXX Paid Premium Amount | 0 | | Hit XXX steps | 1 | | X no of days lower Bio Age than the actual age | 2 | | Spend X no of Unique partners | 3 | | X no of refer friends | 4 | | Group Challenges | 5 | | X no of transactions by partner | 6 | | X no of transactions with any partners | 7 | | Community challenge | 8 | **NOTE: SIT & UAT need to confirm: Admin panel + BE + DB** Note: only for below challenge type: start Date & endDate, no of days max of 30 Days Hit XXX steps X no of days lower Bio Age than the actual age --- challenges [current v2.0]: ```json= { id, // auto generated one uid, // we are generating it our end. brandPremiumAppId, brandName, description, title, subtitle, icon, imageBackground, startDate, endDate, content, terms, status, // 0 -> inactive, 1 -> active type, // 0 -> normal, 1 -> gift createdAt, updatedAt, } ``` challenges_v3.0 [New v3.0]: ```json= { id, // auto generated one uid, // we are generating it our end. brandPremiumAppId, // optional Default -> NULL brandName, // optional Default -> NULL title, subtitle, description, icon, imageBackground, // optional in create challenge, If it empty from Admin -> default Image. listingActiveIcon, // New listingInactiveIcon, // New startDate, endDate, content, terms, status, // 0 -> inactive, 1 -> active type, // 0 - 5 isDashboard, sortNum, createdAt, updatedAt, completionValue, // New Type. VARCHAR(255), we cast the type based on the challenge type., dashboardSortNum // Default -> 0 } ``` challenge_groups ```json= { id, // Auto Generated one. displayName, // ex: NUS title, // National University of Singapore logo, // Upload Image createdAt, updatedAt, status, // 0 -> inactive, 1 -> active } ``` group_challenges ```json= { id, challengeUid, groupId, status, // 0 -> inactive, 1 -> active, createdAt, updatedAt, } ``` ### Completed Challenges ```json= user_challenges_v3 { id, challengeUid, groupdId, channelUserId, email, status, // 0 -> Joined but not completed, 1 -> completed, 2 -> completed and redeemed progressValue, createdAt, updatedAt, completedAt, redeemedAt, rewardedAt, // isRewarded, // flag to update the procurement of the Rewards sent to user by email. } ``` ### Leader Board 1. Scheudle the job to update the completed challengs everyday at 12AM 2. Update the completed challenges based on the user action. - An API call in the background to update the completed challenges in the DB - Challenge List -> - ZA -> Data required for ML; - Query -> pass the data to ML: - every end of the Month we can do a data patch to completed challenges: startDate: 17:05:2022 - 00:00:00 endDate: 18:05:2022 - 23:59:59 ## XXX Paid Premium Amount Within the challenge duration, ZA paid the premium value: user's progress (paid premium) Value: $20 Admin user configured as: $45 ``` ZA: ${snackUrl}/snack/query/statisticsByUser statisticsType: TOTAL_PAID_PREMIUM Response: { ... "totalPaidPremium":"21.00", } ``` ## Hit XXX steps Within the challenge duration, get the total number of steps: user's progress Value: 12,000 Admin user configured as: 20000 ``` ZA: ${snackUrl}/snack/query/snackFitActivity Response: "historyActivityList": [ { "activityDate": "2021‐08‐24", "height": 180, "weight": "60", "steps": 8100, "kcal": 750, "sleep": "8.5", "rhr": "50.5", "bioAge": "26", "ageBalance": "1", "calcuationTime": "2021‐08‐25 09:39:31" }, "steps": 8100 Get the accumated value. ``` ## X no of days lower Bio Age than the actual age Within the challenge duration, get the bioAge: user's progress Value: 6 (Get the no of days use's bio age is greater than zero) Admin user configured as: 20 ``` ZA: ${snackUrl}/snack/query/snackFitActivity Response: "historyActivityList": [ { "activityDate": "2021‐08‐24", "height": 180, "weight": "60", "steps": 8100, "kcal": 750, "sleep": "8.5", "rhr": "50.5", "bioAge": "26", "ageBalance": "1", "calcuationTime": "2021‐08‐25 09:39:31" }, "ageBalance": "1", 23.02.2022 - 2 24.02.2022 - 0 25.02.2022 - 1 26.02.2022 - 0 ... total: 2 2 / 20 = ``` ## Spend X no of Unique partners Within the challenge duration, check how many SNACKUP partners user is spending. user's progress Value: 2 Admin user configured as: 5 ``` ZA: ${snackUrl}/snack/query/statisticsByUser statisticsType: TOTAL_FREE_COVERAGE { "value": { "totalFreeCoverage": "20000", "partnerCount": 4, "partnerList": [ "FOODPANDA", "UOB", "REVOLUT", "KIPOS" ], partnerCount: 4 (progress Value) ``` ## X no of refer friends Within the challenge duration, check how many referrals user has. user's progress Value: 2 Admin user configured as: 5 GET no of referral count from user.referrals where channelUserId='' AND (uppadtedAt >= challenge.startDate && updaatedAt <= challenge.endDate) ``` ML DB ``` ## Group challenge points calculation group_user_challenge_points ```json= { id, channelUserId, challengeUid, groupId, referralCount, points // 0 -> Bonus points completed referrals and No of completed challenges. createdAt, updatedAt } ``` 1. on the fly get the individual referral count by a channelUserId 2. on the fly get the grp referral count by a group channelUserID: 134454 No of completed challenges: 3 challengeUid: (ABC), completionValue: 20 pts User(134454)'s total points for the challenge ABC is 60 pts (3 * 20) ### A schedular will be run every day, time will be provided by MG. ## Leader Board (Dashboard) @subhaish, @joy, @yahui ```json= challenge_leaderboard { id, challengeUid, status, // 0 -> inactive, 1 -> active, title, // description, imageUrl, createdAt, updatedAt } challenge_leaderboard_points { id, leaderboardId, points, groupId, // logo and the display name or | and title from there. createdAt, updatedAt } ``` challenge Use cases. 1. When the challenge is active / completed, admin can edit except [statDate, endDate, completionValue, type of the challenge, title, subtitle] 2. For future grp challenge admin user can able to remove / add a new grp, and able to edit the fields. For the PROGRESS UPDATE API: 1. Get all the challenges that user joined. 2. Based on each challenge type update the progress Value. **@Joy, - Feedback from client by 14 Jun 2022 For query the data to update the progress of the challenge, start date will be the joined date of the challenge by the user.** type == 4 user.referrals & filter user.referrals.updatedAt ## Completed challenges CSV ## Challenge Query ```javascript= List: QUERY: (startDate <= currentDate && currentDate <= endDate) && staus == 1 SORT: sortNum Dashboard QUERY: (startDate <= currentDate && currentDate <= endDate) && staus == 1 && isDashboard == 1 SORT: dashboardSortNum History (User): challenges: noOfDays(currentDate - challenge.startDate) <= 90 && staus == 1 user_challenges: status = 0 [Joined not completed] && challenge.endDate < currentDate status = 1 [Completed] && challenge.endDate < currentDate status = 2 [Completed and Redeemed] ``` Update from clinet: 15 June 2022: `These 2 parts I am wondering if it is possible. Replace the top 3 leaderboard to school leaderboard, and display the student's rank in their school` ![](https://i.imgur.com/mZ9C8BQ.jpg) @Joy can we check the rank for the user within a grp challenge? Note: Query to MG For leaderboard points: CRON JOB vs MANUAL (override the value or not) @Karthik As checked with MG it will be MANUAL for phase1, in phase2 we can update the logic with CRON JOB. 1. Update Progress: User request - ZA: snackFitActivity, statisticsByUser [1:1] CRON - Job, 15K - 15K per one challenge, 4 = 60K Graphene 2.0 - Batch update API [100], ## Phase2: Challenges: API specification: ZA -> ML: CRON - grp challenges /status/update ZA -> ML -> AML status [ML DB]: ## Challenge Enhancement for update progress ### Real Time ML provide an API, ZA will call the ML API whenever the values updated. - Request body for all challenge types: - date - current Date ## XXX Paid Premium Amount ```json { "channelUserId": 33434, "date": "27-08-2022" "statisticsType": "TOTAL_PAID_PREMIUM" "statisticsValue":"21.00" } ``` ## Spend X no of Unique partners ```json { "channelUserId": 33434, "date": "27-08-2022" "statisticsType": "TOTAL_FREE_COVERAGE_NO_OF_PARTNERS" "statisticsValue": 4 } ``` ## Hit XXX steps ```json { "channelUserId": 33434, "date": "27-08-2022" "statisticsType": "SNACK_FIT_TOTAL_STEPS" "statisticsValue": 2000 } ``` ## X no of days lower Bio Age than the actual age ```json { "channelUserId": 33434, "date": "27-08-2022" "statisticsType": "SNACK_FIT_AGE_BALANCE" "statisticsValue": 0 } ``` Note: Export the data from ZA and import in ML DB before rollout this enhancement. ## upcoming challenges. ```json { "channelUserId": 33434, "date": "27-08-2022" "statisticsType": "TOTAL_FREE_COVERAGE" "statisticsValue": "20000" } ``` statisticsByUser snackFitActivity ### statisticsTypes TOTAL_PAID_PREMIUM TOTAL_FREE_COVERAGE_NO_OF_PARTNERS SNACK_FIT_AGE_BALANCE SNACK_FIT_TOTAL_STEPS CRON JOB, bulk Query: [ ".. channelUserIds", "statisticsType": "TOTAL_FREE_COVERAGE", ] Note: Each challenge for a user has diff startDate (joined date of the challenge), endDate will be challenge end Date. ## 14.12.2022 => Community Challenge 1. Dashboard [New Template] Type "EXPLORE_CHALLENGE" Title Image Template => TOP IMAGE htmlDescription => html text contentImage => NEW IMAGE INPUT [optional] backgroundColor: { startColor: "", [text input] [hex value] endColor: "" [text input] [hex value] } [optional], Active Order Content ![](https://i.imgur.com/At8pKjx.png) ![](https://i.imgur.com/HskWc5y.png) 2. Community Challenge: ![](https://i.imgur.com/jYfJhWX.png) ![](https://i.imgur.com/BN8kgne.png) Challenge Type => Community challenge (8) Challenge Title [html text] Challenge Subtitle [html text] Description [html text] Scheduled on Image Background Icon Listing Active Icon Url Listing Inactive Icon Url Content Terms and Conditions Completion Value Order Is Dashboard Active NEW TABLE: `community_challenge_additional_info` id, title [html text], description [html text], image, backgroundColor: { startColor: "", [text input] [hex value] endColor: "" [text input] [hex value] } [JSON], content: [ { label [html text], value [html text], info [html text], subInfo [html text] [optional], } ] [JSON], tiers: [ { displayText (required) [html text], displayLabel (required) [html text], activeImage (optional), inactiveImage (optional), isActive (required) [bool] } ] [JSON], contentUpdatedAt, [datetime input] // SGT createdAt, updatedAt # 7.12.2022 - X no of transactions by partner, X no of transaction by any partner include datasouce in the Filter: ![](https://i.imgur.com/bUJHo7k.png) Dropdown: ```json { "None": "", "Visa": "DS0005", "Mastercard": "DS0013" } ```