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

@ -7,6 +7,7 @@
// - content rights declaration
// - price Free (USA base) and availability in every territory + new ones (when apple.info.free !== false)
// App Privacy ("nutrition label") has no API: web UI only (store-declarations skill).
import { refuseTemplate } from '../lib/template-answers';
import type { Ctx } from '../lib/ctx';
import { confirm, need } from '../lib/ctx';
import { type ItemPlan, itemLines, planItem } from '../lib/listing-plan';
@ -69,6 +70,7 @@ export async function run(ctx: Ctx): Promise<void> {
const { config, root } = ctx.loaded;
const info = config.apple?.info ?? {};
const dry = ctx.args.has('dry');
refuseTemplate(config, ['ageRating'], 'apple appinfo (age rating declaration)');
const c = await ascClient(root, need(config.apple?.bundleId, 'apple.bundleId'), config.apple?.appId);
const appId = await c.app();
const p = await planAppInfo(ctx, c, appId);