template compliance answers never reach a store: init writes unanswered (dataSafety, appPrivacy, reviewNotes, ageRating, accounts, reviewAccess), older configs are recognised by the template values; check / validate / scan block, play data-safety (also --dry), console plan / fill, apple review-details and appinfo refuse. onboard --declarations replaces them on a live app: name and copyright from the stores (a copyright with a private term is left out), the rows the code proves (scan proposal, sign-up methods from auth code and login SDKs), the rest as one owner question list. play data-safety --dry prints the answers that change (old -> new, account and deletion first) against the last uploaded CSV; pitfall 60; tests

This commit is contained in:
CRTkafa 2026-10-14 11:36:30 +08:00
parent 34c2fa22e5
commit 7219ded3e8
27 changed files with 659 additions and 19 deletions

View file

@ -13,6 +13,7 @@
// blockers stay blockers, high and medium risks are warnings, owner-accepted ones (scan.ignore) are left out. --no-scan skips.
// Live apps: crash / ANR vitals (Play Reporting API) and App Store diagnostics, as in `storebound health`: over a Play
// bad behavior threshold is a blocker, near it a warning; a store without vitals access is only noted. --no-health skips.
import { templateBlockers } from './lib/template-answers';
import { ascClient, type J } from './apple/asc';
import { requiredDisplayTypes } from './apple/screenshots';
import { type Loaded, playCategoryOf, playCodes, profileOf, sellsOn } from './lib/config';
@ -191,6 +192,8 @@ export async function run(ctx: Ctx): Promise<void> {
try { findings.push(...playRules({ ...(await collectPlay(ctx)), renders: local?.play })); }
catch (e) { findings.push({ store: 'play', level: 'blocker', code: 'api', msg: (e as Error).message.slice(0, 400) }, ...rendersFindings('play', local?.play)); }
} else if (a.has('play')) warn('validate', 'no play section in the config');
// template compliance answers: the scan reports them; without the scan, here
if (a.has('no-scan')) for (const msg of templateBlockers(config)) findings.push({ store: config.apple ? 'apple' : 'play', level: 'blocker', code: 'template-answers', msg });
if (!a.has('no-scan')) {
log('validate', 'project scan (offline): rejection risks in the project files');
try {