console: Play App content card Saves are the agent's (declaration-save; Send changes for review, Submit, Publish, Restart review stay forbidden), one owner batch per plan with the IARC Terms tick before the run, console plan play-app-content --all, New App fields typed not set, play.appId from the Create app redirect (console verify --url --write) and storebound play app-id across app list pages
This commit is contained in:
parent
1366e7e231
commit
f741c15829
29 changed files with 1029 additions and 165 deletions
|
|
@ -16,7 +16,7 @@
|
|||
import type { ShipConfig } from './config';
|
||||
import { PLAY_APP_CATEGORIES, PLAY_GAME_CATEGORIES, playCategoryOf, profileOf } from './config';
|
||||
import type { PlanFormId, PlanOnlyFormId } from './console-answers';
|
||||
import { NEVER_PRESS, playAppList } from './console-forms';
|
||||
import { NEVER_PRESS, PLAY_NEVER_PRESS, playAppList } from './console-forms';
|
||||
import type { ConsolePlan, PlanAnswer, PlanIds, PlanStatus, PlanStep } from './console-plan';
|
||||
import { AD_ID_PERMISSION, type ProjectSignals } from './project-signals';
|
||||
|
||||
|
|
@ -100,12 +100,20 @@ function steps(list: (Omit<PlanStep, 'n'> | false | undefined)[]): PlanStep[] {
|
|||
return list.filter((s): s is Omit<PlanStep, 'n'> => !!s).map((s, i) => ({ n: i + 1, ...s }));
|
||||
}
|
||||
|
||||
/** A declaration's Save: stores the answer, which Google reviews: the owner's (or the agent's after a clear yes in chat). */
|
||||
const DECLARATION_SAVE = 'Stop before Save: show the owner the filled card and let them press Save (or press it after the owner\'s clear yes in chat; one yes can cover the cards listed by `console plan play-app-content`). Google reviews the declaration with the next submission.';
|
||||
/** Publishing overview's button that sends every saved change to Google: the owner's (verified 2026-10-12). */
|
||||
export const SEND_FOR_REVIEW = 'Send changes for review';
|
||||
/** Where the owner presses it. */
|
||||
export const SEND_FOR_REVIEW_WHERE = 'Publishing overview (left menu): "Submit N changes for review", then "Send changes for review" in the "Send N changes for review?" dialog (a real click)';
|
||||
/**
|
||||
* A declaration's Save (verified 2026-10-13): it stores the card; nothing goes to Google before the owner presses Send
|
||||
* changes for review in Publishing overview. So the agent presses it, reads the card back and goes on.
|
||||
*/
|
||||
const DECLARATION_SAVE = `Press Save yourself (the agent's button: it stores the declaration; Google gets it only with the next "${SEND_FOR_REVIEW}" in Publishing overview, which stays the owner's). Read the card back.`;
|
||||
const declarationButtons = (where: string, extra: ConsolePlan['buttons']['allowed'] = []) => ({
|
||||
final: 'Save',
|
||||
neverPress: ['Save', 'Send changes for review', ...NEVER_PRESS],
|
||||
allowed: [{ button: 'Start <card> declaration / Manage', class: 'navigation', where: 'App content overview: opens the card' }, ...extra, { button: 'Back', class: 'navigation', where }],
|
||||
final: SEND_FOR_REVIEW,
|
||||
neverPress: [...new Set([...PLAY_NEVER_PRESS, ...NEVER_PRESS])],
|
||||
allowed: [{ button: 'Start <card> declaration / Manage', class: 'navigation', where: 'App content overview: opens the card' }, ...extra, { button: 'Back', class: 'navigation', where },
|
||||
{ button: 'Save', class: 'declaration-save', where: `${where}: stores the declaration; Google gets it only with the owner's ${SEND_FOR_REVIEW} (verified 2026-10-13)` }],
|
||||
});
|
||||
|
||||
// ---- Store settings: the App category (no API) ----
|
||||
|
|
@ -134,7 +142,7 @@ function storeSettings(config: ShipConfig, p: PlanIds): Part {
|
|||
]),
|
||||
answers: [type, category],
|
||||
final: 'Send changes for review',
|
||||
neverPress: ['Send changes for review', ...NEVER_PRESS],
|
||||
neverPress: [...PLAY_NEVER_PRESS, ...NEVER_PRESS],
|
||||
allowed: [
|
||||
{ button: 'Edit (the first one: App category)', class: 'navigation', where: 'Store settings: opens the App category section' },
|
||||
{ button: 'Save', class: 'draft-save', where: 'Store settings: stores the category. On a published app the change goes out with Google\'s review (with managed publishing: Publishing overview > Send changes for review, the owner\'s)' },
|
||||
|
|
@ -209,9 +217,16 @@ function signInDetails(config: ShipConfig, p: PlanIds): Part {
|
|||
if (ra?.signInRequired) {
|
||||
out.push(ra.instructions ? ans('instructions', 'Instructions for the reviewer', ra.instructions, 'certain', 'reviewAccess.instructions', { control: 'text', action: 'type', label: 'Any other information required to access your app', where: 'Add instructions' })
|
||||
: ans('instructions', 'Instructions for the reviewer', null, 'ask-owner', 'reviewAccess.instructions', { note: 'Set reviewAccess.instructions (how to sign in and reach the main features).' }));
|
||||
out.push(ans('credentials', 'Username and password of the demo account', null, 'ask-owner', '.storebound/credentials.json reviewDemoAccount', {
|
||||
control: 'text', where: 'Add instructions: Username, Password',
|
||||
note: `The owner types them from .storebound/credentials.json (reviewDemoAccount: ${p.demoAccount === undefined ? 'not checked' : p.demoAccount ? 'present' : 'MISSING, add it first'}). storebound never prints them; an agent never types a password.` }));
|
||||
// with reviewDemoAccount in .storebound/credentials.json the agent types it (never printed: not in chat, logs, the
|
||||
// plan or a commit); without it the owner types the username and password (or adds it there first)
|
||||
out.push(p.demoAccount
|
||||
? ans('credentials', 'Username and password of the demo account', null, 'certain', '.storebound/credentials.json reviewDemoAccount', {
|
||||
control: 'text', action: 'type', where: 'Add instructions: Username, Password',
|
||||
text: 'from .storebound/credentials.json (never printed)',
|
||||
note: 'reviewDemoAccount: present. The agent types reviewDemoAccount.username and .password from .storebound/credentials.json straight into the two fields (click, type), without echoing them in chat, logs, the plan or a commit.' })
|
||||
: ans('credentials', 'Username and password of the demo account', null, 'ask-owner', '.storebound/credentials.json reviewDemoAccount', {
|
||||
control: 'text', where: 'Add instructions: Username, Password',
|
||||
note: `reviewDemoAccount: ${p.demoAccount === undefined ? 'not checked' : 'MISSING'}. The owner adds it to .storebound/credentials.json before the run (then the agent types it, never printed), or types the username and password into the card themselves. storebound never prints them.` }));
|
||||
}
|
||||
return {
|
||||
title: 'Play Console: Sign in details (App access)',
|
||||
|
|
@ -219,13 +234,15 @@ function signInDetails(config: ShipConfig, p: PlanIds): Part {
|
|||
steps: steps([
|
||||
{ text: 'Open App content > Sign in details (/app-content/testing-credentials).' },
|
||||
{ text: 'Pick whether any functionality is restricted (material radio: JS click on the inner [role=radio]).', answers: ['access'] },
|
||||
ra?.signInRequired && { text: 'Restricted: press "Add instructions", type the instructions; leave Username and Password to the owner (the demo account in .storebound/credentials.json).', click: ['Add instructions'], answers: ['instructions', 'credentials'] },
|
||||
ra?.signInRequired && { text: p.demoAccount
|
||||
? 'Restricted: press "Add instructions", type the instructions, then type the Username and Password from .storebound/credentials.json (reviewDemoAccount; click each field and type: never echo them in chat or logs).'
|
||||
: 'Restricted: press "Add instructions", type the instructions; the Username and Password are the owner\'s (no reviewDemoAccount in .storebound/credentials.json: in the owner batch).', click: ['Add instructions'], answers: ['instructions', 'credentials'] },
|
||||
{ text: DECLARATION_SAVE },
|
||||
{ text: 'Verify: read the page text and pipe it to `storebound console verify play-sign-in-details --from-text -`.' },
|
||||
]),
|
||||
answers: out,
|
||||
...declarationButtons('Sign in details', [{ button: 'Add instructions', class: 'navigation', where: 'Sign in details: opens the instructions dialog' }]),
|
||||
uiFacts: ['Verified 2026-10-12: the Sign in details card (App access) is /app-content/testing-credentials.', 'Credentials are never in the config or in chat: the owner types them from .storebound/credentials.json.', PLAY_MATERIAL_FACT],
|
||||
uiFacts: ['Verified 2026-10-12: the Sign in details card (App access) is /app-content/testing-credentials.', 'Credentials are never in the config, the plan or chat: the agent types them from .storebound/credentials.json (reviewDemoAccount) without printing them; without that entry the owner types them.', PLAY_MATERIAL_FACT],
|
||||
verify: pageVerify('play-sign-in-details', ['The selected radio matches reviewAccess.signInRequired; with a sign-in, one set of instructions is listed.']),
|
||||
guidance: ['Open: Policy and programs > App content > Sign in details (App access)'],
|
||||
};
|
||||
|
|
@ -368,7 +385,7 @@ function productionCountries(config: ShipConfig, p: PlanIds): Part {
|
|||
]),
|
||||
answers,
|
||||
final: 'Send changes for review',
|
||||
neverPress: ['Send changes for review', ...NEVER_PRESS],
|
||||
neverPress: [...PLAY_NEVER_PRESS, ...NEVER_PRESS],
|
||||
allowed: [
|
||||
{ button: 'Countries / regions (tab), Edit countries / regions', class: 'navigation', where: 'production track: opens the country list' },
|
||||
{ button: 'Save', class: 'draft-save', where: 'country list: stores the countries of the draft production release; nothing is public before the owner sends the changes for review' },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue