[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CBP0ARS6TCSDSRZ0MJRSRA":3,"skill-same:01M6CBP0ARS6TCSDSRZ0MJRSRA":45},{"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":20,"linkOnly":21,"markdownContent":22,"markdownBody":22,"frontMatter":23,"refName":24,"commitSha":25,"skillDirectory":26,"forksCount":13,"repositoryHtmlUrl":27,"repositoryHomepageUrl":6,"ownerHtmlUrl":28,"ownerBlogUrl":6,"ownerDescription":29,"updatedAt":30,"install":31,"resources":44},"01M6CBP0ARS6TCSDSRZ0MJRSRA","09-ssot-operations",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\u002F47-advertise-system\u002F09-ssot-operations\u002FSKILL.md",[],[18,19],"operations","09 ssot operations","2026-11-10 10:12:30",false,"# 09-ssot-operations — 47-advertise-system\n\n\nStatus: ACTIVE\nAppliesTo: v10\n\n\n이 문서는 47-advertise-system의 운영\u002F테스트\u002FDoD 정본이다.\n테이블\u002F보상\u002F매니저 경계는 [03-ssot](..\u002F03-ssot\u002FSKILL.md)가 정본이다.\n\n\n---\n\n\n## 운영 시나리오(정본)\n\n\n### 1) 기본 개발\u002FCI 경로\n\n- Editor, CI, 로컬 개발 기본 provider는 `MockAdProvider`\n- 실제 네트워크 광고 요청 없이 load\u002Fshow\u002Freward\u002Ffail 시나리오를 scripted callback으로 재현\n- UI\u002Fscene 전환\u002F버튼 흐름 검증은 mock 결과로 수행\n\n\n### 2) 실기기 smoke test 경로\n\n- 실 SDK 검증은 test ad unit 또는 test device 기반 수동 smoke test로만 수행\n- placement별 최소 체크만 한다: initialize, load success, show success\u002Ffail, close, rewarded callback\n- 한 세션에서 과도하게 반복 호출하지 않는다\n\n\n### 3) 라이브 광고 운영 경로\n\n- 라이브 ad unit은 QA 자동화\u002F반복 회귀 테스트에 사용하지 않는다\n- 무효 트래픽으로 오해될 수 있는 반복 노출\u002F클릭\u002F스크립트 호출을 금지\n- 배포 전 검증은 mock + test unit + 제한된 실제 smoke test를 조합한다\n\n\n### 4) Rewarded 지급 검증\n\n- rewarded 완료 전에는 보상이 지급되지 않아야 한다\n- reward callback 발생 시 `RewardManager.ApplyRewardGroup(reward_group_id)`가 1회만 호출되어야 한다\n- close-only \u002F fail \u002F no fill 경로에서는 보상 지급이 없어야 한다\n\n\n### 5) SSV 콜백 검증\n\n- Firebase Functions 에뮬레이터에서 SSV 콜백 엔드포인트가 정상 응답(HTTP 200)하는지 확인\n- ECDSA 서명 검증 실패 시에도 HTTP 200 반환 + 에러 로깅 확인\n- 동일 transaction_id 재요청 시 Firestore 중복 기록이 발생하지 않는지 확인\n- custom_data 파싱(`{uid}:{advertise_id}:{reward_group_id}`)이 정상 동작하는지 확인\n\n\n---\n\n\n## 테스트 체크리스트(정본)\n\n- Editor에서 mock provider로 initialize\u002Fload\u002Fshow\u002Freward\u002Ffail이 모두 재현된다\n- `REWARDED` placement는 `reward_group_id` 누락 시 안전 실패한다\n- `BANNER` \u002F `INTERSTITIAL` \u002F `APP_OPEN`은 `reward_group_id` 없이 동작한다\n- 동일 rewarded show cycle에서 reward callback이 2번 와도 보상 지급은 1회다\n- NoAds 활성 시 banner\u002Finterstitial\u002Fapp-open이 차단된다\n- unsupported platform \u002F SDK 미초기화 \u002F no fill에서 예외 폭발 없이 실패 결과를 반환한다\n- 실제 SDK smoke test는 test ad unit 또는 test device로만 수행한다\n- SSV 콜백 엔드포인트가 Firebase 에뮬레이터에서 HTTP 200 응답한다\n- SSV 서명 검증 실패 시에도 앱 크래시 없이 에러 로깅만 수행한다\n\n\n---\n\n\n## DoD (구현 단계 기준)\n\n\n### Hard (반드시 0)\n\n- live ad unit 기반 반복 자동 테스트 0건\n- rewarded 중복 지급(동일 show cycle) 0건\n- 미지원 플랫폼\u002FEditor에서 크래시 0건\n- reward callback 이전 선지급 0건\n- `ADVERTISE` 정본 외 설정 하드코딩 0건\n\n\n### Soft\n\n- provider 전환이 AdsManager 상위 API 변경 없이 가능\n- mock scenario 스위칭이 간단한 enum\u002F설정 수준으로 가능\n",{},"main","8cb5bd877a3a7004867d2f55697cb9e4ff2f1734","skills\u002Fdevian-unity\u002F50-mobile-package\u002F47-advertise-system\u002F09-ssot-operations","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":32,"prompt":42,"zipAvailable":43},[33,36,39],{"tool":34,"command":35},"npx","npx skills add devwinsoft\u002Fdevian --skill 09-ssot-operations",{"tool":37,"command":38},"bunx","bunx skills add devwinsoft\u002Fdevian --skill 09-ssot-operations",{"tool":40,"command":41},"pnpm","pnpm dlx skills add devwinsoft\u002Fdevian --skill 09-ssot-operations","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian-unity\u002F50-mobile-package\u002F47-advertise-system\u002F09-ssot-operations\u002FSKILL.md",true,[],[46,52,60,68,77,84],{"skillNo":47,"name":48,"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":49,"categories":50,"keywords":51,"publishedAt":20},"01M6CBX3K2JJV38ANHVGCAT8A0","devian","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002FSKILL.md",[],[48],{"skillNo":53,"name":54,"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":55,"categories":56,"keywords":57,"publishedAt":20},"01M6CBX210BFMM8AMN770J9WY8","90-project-archive","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F90-project-archive\u002FSKILL.md",[],[58,59],"archive","90 project archive",{"skillNo":61,"name":62,"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":63,"categories":64,"keywords":65,"publishedAt":20},"01M6CBWZSGRR9R3YJZB3177667","30-env-management","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F30-env-management\u002FSKILL.md",[],[66,67],"management","30 env management",{"skillNo":69,"name":70,"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":71,"categories":72,"keywords":73,"publishedAt":20},"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",[],[74,75,76],"push","page","19 page push send",{"skillNo":78,"name":79,"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":80,"categories":81,"keywords":82,"publishedAt":20},"01M6CBWWRQ05A7604GHJKTPJTF","18-page-savedata","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F18-page-savedata\u002FSKILL.md",[],[75,83],"18 page savedata",{"skillNo":85,"name":86,"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":87,"categories":88,"keywords":89,"publishedAt":20},"01M6CBWVH4S2VF1V7B2GBTESCT","17-page-deobfuscate","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F17-page-deobfuscate\u002FSKILL.md",[],[75,90],"17 page deobfuscate"]