First in-app purchases left out of a review are caught (pitfall 70): firstProductGaps in validate / release plan (blocker) and the apple submit plan (refuses to leave a never-approved first product out); apple status (WARN + firstProductGaps in --json), release status and the desktop checks warn while a version waits for or is in review without it; iap-review says 'ready, not submitted yet' instead of 'complete'

This commit is contained in:
CRTkafa 2026-10-15 19:31:26 +08:00
parent 1c35a625e1
commit b830a99a5f
16 changed files with 288 additions and 18 deletions

View file

@ -3,7 +3,7 @@
// workspace (`storebound ws status`, `storebound release status`), so all of them read an app the same way.
// Every read is a storebound child command; `exec` runs it (serve tracks it for cancellation, the CLI just awaits it).
import type { AppStatus, ProjectSummary } from './desktop-protocol';
import { appIdentity, appleProductIds, appleReleases, catalogParity, playProductIds, playReleases, releaseTrains } from './portfolio';
import { appIdentity, appleFirstProductWarnings, appleProductIds, appleReleases, catalogParity, playProductIds, playReleases, releaseTrains } from './portfolio';
import type { RunResult } from './runner';
export type Exec = (argv: string[], cwd: string) => Promise<RunResult>;
@ -45,6 +45,10 @@ export async function fillAppStatus(e: AppStatus, dir: string, o: { live: boolea
if (play?.error) e.storeErrors.android = play.error;
const ios = apple?.data ? appleReleases(apple.data) : [], android = play?.data ? playReleases(play.data) : [];
e.release = { source: 'live', ...releaseTrains(ios, android), all: [...ios, ...android] };
// first in-app purchases left out of the review: a warning on the release status and in the desktop's checks
const firstWarn = apple?.data ? appleFirstProductWarnings(apple.data) : [];
if (firstWarn.length) e.warnings = firstWarn;
if (e.check) for (const w of firstWarn) if (!e.check.warnings.includes(w)) e.check.warnings.push(w);
e.catalog = catalogParity(summary, apple?.data ? appleProductIds(apple.data) : undefined, play?.data ? playProductIds(play.data) : undefined);
}
e.ok = e.check.ok && !e.storeErrors.ios && !e.storeErrors.android && (e.catalog?.ok ?? true);