# Prepare the app state

> How to start a tutorial with the right data: an existing record, future dates, a unique value per run, a demo data reset and learned requests.

A tutorial runs on the real app. Many screens need data in a specific state:
a signed offer that hasn't expired, a deal pending a condition, a client that
doesn't exist yet. Here are the ways to get there, simplest first.

## 1. Start from an existing record

The demo account usually has records in every state. Open one directly:

```yaml
steps:
  - id: review-offer
    start: /offers/OFF-1042          # a record of the demo data
```

If the id changes, look it up first and save it:

```yaml
setup:
  - goto: /offers?status=signed
  - remember: { name: offer, target: { id: offers-row }, attribute: data-offer-id }
steps:
  - id: review-offer
    start: /offers/{offer}
```

## 2. Dates that stay in the future

`{date+N}` is the date N days after the shoot (in the browser's time zone),
so `{date+7}` is always a week ahead. Use it wherever the app validates a
date (a deadline, an irrevocability date, a shift):

```yaml
- say: { en-US: Set the deadline one week from now. }
  type: { target: { id: offer-deadline-input }, text: "{date+7}" }
```

## 3. A value unique to each run

Apps often reject duplicates (a client email, a name). `{run}` is a short
value that's unique to each run and the same in every step of that run:

```yaml
type: { target: { id: client-email-input }, text: "client-{run}@example.com" }
```

The email must still match `safeEmail` in your settings.

## 4. Set up the data before filming

`setup:` runs off camera before the first step, with the same actions as a
shot (`goto`, `click`, `type`, `select`, `attach`). Use it to open the right
record, close a window the app might show, or change a date:

```yaml
setup:
  - click: { id: welcome-close-button }
    ifPresent: 5000                  # waits up to 5 s for it, skipped when it does not show
  - goto: /offers/{offer}/edit
  - type: { target: { id: offer-irrevocable-date }, text: "{date+3}" }
  - click: { id: offer-save-button }
writes:
  - '/updateOffer$'                  # the save above is a write: list it
```

A command from your repository can also prepare data off screen:
`run: "node scripts/demo-offer.cjs signed"`. This works on your
infrastructure only, never on Ondaclip Cloud. It runs from the repository
root for 120 seconds at most, with `TUTORIAL_ID`, `TUTORIAL_OUTPUT` and
`TUTORIAL_APP_URL`.

## 5. Leave the app as you found it

A tutorial that writes data needs one of these:

- `cleanup:` actions that undo its changes (they always run, even after a
  failure);
- or `demoData.reset` in `config.yaml`: the command your team uses to reset
  the demo data, when cleaning up after each tutorial isn't possible.

## 6. Responses that must stay the same

When a screen calls an AI model or an outside service, record its responses
once and replay them, so every video and every check shows the same thing:

```yaml
frozenResponses: { url: "invokeLLM|/suggestCondition" }
```

Checks never record, so a new tutorial with frozen responses needs one
shoot first.

## 7. Learn a new tutorial's requests

In a Firebase app, the SDK reads data with POST requests, and every callable
is a POST. Instead of finding them one check at a time, run a **learn check**
(MCP `check` with `learn: true`). Every request your settings don't allow is
logged with its step: reads go through, and anything else is blocked without
failing the run. `run_status` then suggests the `allowedWrites` for
`config.yaml` and the `writes:` for each tutorial. Review them, push, and
check again without `learn`.

## 8. When it fails

A problem report shows the step, the element, what covered it (a dialog, a
banner) and any messages the app showed at that moment (a toast, an error),
along with a screenshot of the failure. Read it before you change the
tutorial: the cause is often in the data (a duplicate, an empty required
field, a past date).

Is the data fine, but the screen is new and only exists on a branch? Film
the branch on its preview. See
[film a branch on a preview](/docs/connect-your-product/#film-a-branch-on-a-preview).

Source: https://ondaclip.com/docs/app-state/
