[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CBQP3G4DY6NSCAEGPS2HF2":3,"skill-same:01M6CBQP3G4DY6NSCAEGPS2HF2":50},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":21,"frontMatter":22,"refName":23,"commitSha":24,"skillDirectory":25,"forksCount":13,"repositoryHtmlUrl":26,"repositoryHomepageUrl":6,"ownerHtmlUrl":27,"ownerBlogUrl":6,"ownerDescription":28,"updatedAt":29,"install":30,"resources":43},"01M6CBQP3G4DY6NSCAEGPS2HF2","13-leaderboard-season-reward-manager",null,"devwinsoft\u002Fdevian","devwinsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F22570160?v=4","01M6C6RR8W05NH8NPKQNCE3Q72","maoshy","01M6C6RRDJ5TJJCZXRTY801YDH",0,"MIT","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian-unity\u002F50-mobile-package\u002F50-leaderboard\u002F13-leaderboard-season-reward-manager\u002FSKILL.md",[],[18],"13 leaderboard season reward manager","2026-11-10 10:12:30",false,"# 13-leaderboard-season-reward-manager\n\nStatus: DEPRECATED\nAppliesTo: v10\nType: Design \u002F Runtime Orchestration\n\n시즌 전환 보상 평가\u002F지급 로직은 `LeaderboardManager`로 통합되었다.\n\n---\n\n## Implementation Location (3-path mirror)\n\n- UPM (정본):\n  - `framework-cs\u002Fupm\u002Fcom.devian.foundation\u002FSamples~\u002FMobilePackage\u002FRuntime\u002FLeaderboard\u002FLeaderboardManager.cs`\n- Packages (sync):\n  - `framework-cs\u002Fapps\u002FUnityExample\u002FPackages\u002Fcom.devian.foundation\u002FSamples~\u002FMobilePackage\u002FRuntime\u002FLeaderboard\u002FLeaderboardManager.cs`\n- Assets\u002FSamples (import):\n  - `framework-cs\u002Fapps\u002FUnityExample\u002FAssets\u002FSamples\u002FDevian Samples\u002F{version}\u002FMobilePackage\u002FRuntime\u002FLeaderboard\u002FLeaderboardManager.cs`\n- Login 연동:\n  - `framework-cs\u002Fupm\u002Fcom.devian.foundation\u002FSamples~\u002FMobilePackage\u002FRuntime\u002FLogin\u002FLoginManager.cs`\n  - `framework-cs\u002Fapps\u002FUnityExample\u002FAssets\u002FSamples\u002FDevian Samples\u002F{version}\u002FMobilePackage\u002FRuntime\u002FLogin\u002FLoginManager.cs`\n\n---\n\n## Ownership\n\n- `LeaderboardManager`가 `LeaderboardSeasonRewardStorage`를 소유한다.\n- 시즌 보상 지급 여부 판단의 SSOT는 `LeaderboardManager.Storage.processedClaims`다.\n\n---\n\n## Public API\n\n- `LeaderboardManager.SyncSeasonTransitionRewardsAsync(ct)` -> `Task\u003CGameResult>`\n\n---\n\n## Core Flow\n\n1. 초기화 상태 확인\n2. 서버 시간 확보 (`RemoteDataManager.ServerNowUtcMs`)\n3. `TB_LEADERBOARD`에서 active season row 수집 (`LEADERBOARD.season_id → TB_SEASON`으로 시간 조회)\n4. 모드별(`LEADERBOARD_MODE`) current season \u002F previous season 계산 (TB_SEASON 시간 기준)\n5. grace period 통과 여부 확인\n6. `processedClaims` 중복 체크 (`{leaderboard_id}`)\n7. `LeaderboardManager.GetPlayerSnapshotAsync(...)` 조회\n8. snapshot status별 분기\n9. rank 기준 `TB_LEADERBOARD_REWARD.GetByGroup(leaderboard_id)` 매칭\n10. `RewardManager.ApplyRewardGroup(reward_group_id)` 수행\n11. claim 기록 후 `SaveDataManager.SaveGameStorageAsync(true, ct)` 저장\n\n---\n\n## Hard Rules\n\n### 1) Grace Period는 상수만 사용\n\n- `SeasonRewardGracePeriod = TimeSpan.FromMinutes(10)`\n- `IsSeasonRewardEvaluationReady(prevSeasonEndUtcMs, serverNowUtcMs)`로만 판정\n- magic number 금지\n\n### 2) processedClaims 단일 기준\n\n- claim key: `{leaderboard_id}`\n- 중복 지급 방지 기준은 해당 키 존재 여부 단일 체크\n- 별도 `lastProcessedSeasonId` 상태를 두지 않는다\n\n### 3) Snapshot 상태 처리\n\n- `PlatformUnavailable` \u002F `NotLoggedIn` \u002F `Failed`: 기록하지 않고 재시도\n- `NoScore`: `NO_PARTICIPATION` 기록\n- `Success + rank 미매칭`: `RANK_OUT_OF_REWARD` 기록\n- `Success + rank 매칭`: reward 지급 후 `CLAIMED` 기록\n\n### 4) 보상 소스는 LEADERBOARD_REWARD\n\n- `reward_group_id`는 `LEADERBOARD_REWARD` 구간 매칭 결과로만 결정\n- 하드코딩 보상\u002F직접 RewardData 생성 금지\n\n### 5) 스케줄러 없음\n\n- period 개념이 아니라 시즌 경계 평가이므로 별도 scheduler를 두지 않는다\n- 로그인 완료 경로에서 sync를 호출한다\n- 추가 평가가 필요하면 상위 앱 로직이 `SyncSeasonTransitionRewardsAsync`를 명시 호출한다\n\n---\n\n## Test Boundary\n\n- 시즌 종료 + 9분: 미평가\n- 시즌 종료 + 10분: 평가 시작\n\n---\n\n## Related\n\n- [03-ssot](..\u002F03-ssot\u002FSKILL.md)\n- [14-leaderboard-season-reward-storage](..\u002F14-leaderboard-season-reward-storage\u002FSKILL.md)\n- [10-leaderboard-manager](..\u002F10-leaderboard-manager\u002FSKILL.md)\n- [49-reward-system\u002F10-reward-manager](..\u002F..\u002F49-reward-system\u002F10-reward-manager\u002FSKILL.md)\n- [11-mobile-application](..\u002F..\u002F11-mobile-application\u002FSKILL.md)\n",{},"main","8cb5bd877a3a7004867d2f55697cb9e4ff2f1734","skills\u002Fdevian-unity\u002F50-mobile-package\u002F50-leaderboard\u002F13-leaderboard-season-reward-manager","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian","https:\u002F\u002Fgithub.com\u002Fdevwinsoft","Kim Hyong Joon","2026-04-12 18:44:10",{"source":7,"skillName":5,"commands":31,"prompt":41,"zipAvailable":42},[32,35,38],{"tool":33,"command":34},"npx","npx skills add devwinsoft\u002Fdevian --skill 13-leaderboard-season-reward-manager",{"tool":36,"command":37},"bunx","bunx skills add devwinsoft\u002Fdevian --skill 13-leaderboard-season-reward-manager",{"tool":39,"command":40},"pnpm","pnpm dlx skills add devwinsoft\u002Fdevian --skill 13-leaderboard-season-reward-manager","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian-unity\u002F50-mobile-package\u002F50-leaderboard\u002F13-leaderboard-season-reward-manager\u002FSKILL.md",true,[44],{"path":45,"resourceType":46,"resourceTypeDesc":47,"sizeBytes":48,"sourceHtmlUrl":49},"agents\u002Fopenai.yaml","REFERENCE","参考文档",136,"https:\u002F\u002Fgithub.com\u002Ffernando-delosrios-sp\u002Fsailpoint-utils\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fcaveman\u002Fagents\u002Fopenai.yaml",[51,57,65,73,82,89],{"skillNo":52,"name":53,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":54,"categories":55,"keywords":56,"publishedAt":19},"01M6CBX3K2JJV38ANHVGCAT8A0","devian","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002FSKILL.md",[],[53],{"skillNo":58,"name":59,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":60,"categories":61,"keywords":62,"publishedAt":19},"01M6CBX210BFMM8AMN770J9WY8","90-project-archive","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F90-project-archive\u002FSKILL.md",[],[63,64],"archive","90 project archive",{"skillNo":66,"name":67,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":70,"publishedAt":19},"01M6CBWZSGRR9R3YJZB3177667","30-env-management","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F30-env-management\u002FSKILL.md",[],[71,72],"management","30 env management",{"skillNo":74,"name":75,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":78,"publishedAt":19},"01M6CBWYD3TGWBQV7V35551THF","19-page-push-send","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F19-page-push-send\u002FSKILL.md",[],[79,80,81],"push","page","19 page push send",{"skillNo":83,"name":84,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":87,"publishedAt":19},"01M6CBWWRQ05A7604GHJKTPJTF","18-page-savedata","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F18-page-savedata\u002FSKILL.md",[],[80,88],"18 page savedata",{"skillNo":90,"name":91,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":94,"publishedAt":19},"01M6CBWVH4S2VF1V7B2GBTESCT","17-page-deobfuscate","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F17-page-deobfuscate\u002FSKILL.md",[],[80,95],"17 page deobfuscate"]