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:
parent
34c2fa22e5
commit
7219ded3e8
27 changed files with 659 additions and 19 deletions
|
|
@ -367,6 +367,9 @@ export interface AccountsConfig {
|
|||
signUp?: AccountSignUp[];
|
||||
}
|
||||
|
||||
export type TemplateArea = 'dataSafety' | 'appPrivacy' | 'reviewNotes' | 'ageRating' | 'accounts' | 'reviewAccess';
|
||||
export const TEMPLATE_AREAS: readonly TemplateArea[] = ['dataSafety', 'appPrivacy', 'reviewNotes', 'ageRating', 'accounts', 'reviewAccess'];
|
||||
|
||||
export type AccountSignUp = 'username' | 'username-password' | 'email-password' | 'email-link' | 'phone' | 'oauth' | 'other';
|
||||
export const ACCOUNT_SIGN_UPS: readonly AccountSignUp[] = ['username', 'username-password', 'email-password', 'email-link', 'phone', 'oauth', 'other'];
|
||||
|
||||
|
|
@ -645,6 +648,15 @@ export interface ShipConfig {
|
|||
/** App Store base territory of every price schedule (alpha-3). Default: the current one, else USA. */
|
||||
baseTerritory?: string;
|
||||
};
|
||||
/**
|
||||
* Compliance answers that are still the template's (`storebound init`) or not confirmed by the owner yet:
|
||||
* 'dataSafety', 'appPrivacy', 'reviewNotes', 'ageRating', 'accounts', 'reviewAccess'. While an area is listed, check
|
||||
* and validate report a blocker and nothing that sends it (play data-safety, apple review-details / appinfo, console
|
||||
* plan / fill) runs. Remove an entry once its answers are the owner's (derived from the code: `storebound scan
|
||||
* --write`, `storebound onboard --declarations`). `[]` = everything answered. Left out (configs before 0.8.4): the
|
||||
* template answers are recognised by their values (cli/lib/template-answers.ts).
|
||||
*/
|
||||
unanswered?: TemplateArea[];
|
||||
dataSafety?: DataSafety;
|
||||
/** App Store App Privacy answers storebound cannot derive from dataSafety (App Privacy has no API: the owner enters
|
||||
* them in App Store Connect). `storebound scan` proposes them from the detected SDKs and code. */
|
||||
|
|
@ -1077,6 +1089,8 @@ export function validateConfig(c: unknown): string[] {
|
|||
e.push(...validateCpp(cfg.apple.customProductPages, ids, Object.keys(cfg.shots?.variants ?? {})));
|
||||
e.push(...validateEvents(cfg.apple.events, ids));
|
||||
}
|
||||
if (cfg.unanswered !== undefined && !(Array.isArray(cfg.unanswered) && cfg.unanswered.every(x => TEMPLATE_AREAS.includes(x))))
|
||||
e.push(`unanswered: a list of ${TEMPLATE_AREAS.join(' | ')}`);
|
||||
if (cfg.appPrivacy) {
|
||||
if (cfg.appPrivacy.tracking !== undefined && typeof cfg.appPrivacy.tracking !== 'boolean') e.push('appPrivacy.tracking: true | false');
|
||||
if (cfg.appPrivacy.trackingDomains && !(Array.isArray(cfg.appPrivacy.trackingDomains) && cfg.appPrivacy.trackingDomains.every(d => typeof d === 'string' && /^[a-z0-9.-]+$/i.test(d))))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue