apple resubmit: REJECTED review submission items are marked resolved before the submit (PATCH reviewSubmissionItems resolved: true; the version item by default, IAP / subscription items with --resolve-iaps), plan table 'mark resolved' rows; on 409 'not ready yet' the items are re-read and a REJECTED item out of scope stops the run at once naming it and how to resolve it, backoff only when none is left; an empty READY_FOR_REVIEW draft is never canceled (409 'not in cancellable state'): left as is, no cancel command, apple status labels it harmless and treats the cancel 409 as such; fake ASC blocks submit on REJECTED items and refuses to cancel empty drafts. Pitfall 30

This commit is contained in:
CRTkafa 2026-10-12 10:45:05 +08:00
parent 0da5ee9d01
commit 1724296e59
17 changed files with 291 additions and 78 deletions

View file

@ -262,9 +262,20 @@ export class FakeAsc {
Object.assign(self.attributes, rest, { assetDeliveryState: { state: this.parts.includes(self.id) ? 'COMPLETE' : 'FAILED' } });
delete self.attributes.uploadOperations;
} else if (self.type === 'reviewSubmissions' && (attrs.submitted === true || attrs.canceled === true)) {
// seen live (2026-10-12): a REJECTED item that is not marked resolved blocks every submit with this 409, and an
// empty draft cannot be canceled
const items = this.children(self.id, 'reviewSubmissionItems');
if (attrs.submitted && items.some(it => it.attributes.state === 'REJECTED'))
return json({ errors: [{ status: '409', code: 'STATE_ERROR', title: 'The request cannot be fulfilled because of the state of another resource.', detail: 'Version is not ready to be submitted yet, please try again later' }] }, 409);
if (attrs.canceled && self.attributes.state === 'READY_FOR_REVIEW' && !items.length)
return json({ errors: [{ status: '409', code: 'STATE_ERROR', title: 'The request cannot be fulfilled because of the state of another resource.', detail: 'Resource is not in cancellable state' }] }, 409);
// submitting moves the submission (and its items) on; canceling ends it
self.attributes.state = attrs.submitted ? 'WAITING_FOR_REVIEW' : 'CANCELING';
if (attrs.submitted) for (const it of this.children(self.id, 'reviewSubmissionItems')) it.attributes.state = 'READY_FOR_REVIEW';
} else if (self.type === 'reviewSubmissionItems' && attrs.resolved === true) {
// marking a REJECTED item resolved puts it back to READY_FOR_REVIEW (seen live)
if (self.attributes.state === 'REJECTED') self.attributes.state = 'READY_FOR_REVIEW';
self.attributes.resolved = true;
} else Object.assign(self.attributes, attrs);
return json({ data: this.view(self) });
}