Onboarding live apps without owner questions for what the stores and the code prove: storebound onboard imports the live products and subscriptions with USD / base prices (catalog diff clean), contact values, the App Review contact and demo account (credentials.json, masked), sign-in for review from Apple's review detail and auth code, and the account deletion page from the app's site; App Store keywords count characters (live fields up to 265 bytes accepted); validate accepts the 6.5-inch iPhone set and Play's default-language graphics fallback; Play Reporting API off gives the project's enable link and apps list falls back to local apps; accounts default <profile>; store-only apps (apps add --store --app-id) shown read-only in the desktop (pitfalls 43-52)

This commit is contained in:
CRTkafa 2026-10-13 07:25:01 +08:00
parent d2ce185441
commit e5f148e534
55 changed files with 1648 additions and 158 deletions

View file

@ -307,7 +307,7 @@ const fence = (t: string) => '```\n' + t + '\n```';
const https = (u: string | undefined): string | undefined => (u && /^https:\/\/\S+$/.test(u.trim()) ? u.trim() : undefined);
const YOUTUBE = /^https:\/\/(www\.youtube\.com\/watch\?v=[\w-]{6,}|youtu\.be\/[\w-]{6,})$/;
/** Keywords "a, b ,c" -> "a,b,c" (spaces after commas count against the 100 bytes on the App Store). */
/** Keywords "a, b ,c" -> "a,b,c" (spaces after commas count against the 100 characters on the App Store). */
export const normalizeKeywords = (k: string): string => k.split(/[,\n]/).map(x => x.trim()).filter(Boolean).join(',');
/** Image size, null when the header is not PNG / JPEG. */
@ -453,7 +453,7 @@ export function planImport(scan: FastlaneScan, o: PlanOptions): ImportPlan {
add('promotionalText', f.promotionalText);
if (f.keywords) {
const k = normalizeKeywords(f.keywords);
if (k !== f.keywords) warnings.push(`${l.locale}: keywords normalized (spaces after commas removed; they count against 100 bytes)`);
if (k !== f.keywords) warnings.push(`${l.locale}: keywords normalized (spaces after commas removed; they count against 100 characters)`);
add('keywords', k);
}
add('description', f.description);
@ -472,7 +472,7 @@ export function planImport(scan: FastlaneScan, o: PlanOptions): ImportPlan {
Imported from fastlane deliver (\`storebound import fastlane\`). Source for \`storebound apple listing\`. One
\`## <ASC locale>\` section per locale, one fenced block per \`### <field>\`: \`name\` (optional, defaults to \`apple.name\`, else \`app.name\`),
\`subtitle\` (30), \`promotionalText\` (170), \`keywords\` (100 bytes, comma separated, no spaces after commas),
\`subtitle\` (30), \`promotionalText\` (170), \`keywords\` (100 characters, comma separated, no spaces after commas),
\`description\` (4000), \`whatsNew\` (optional). Privacy policy, support and marketing URL come from
\`storebound.config.ts\`.