# PrerequisiteGate

Canonical page: https://docs.ovok.com/native-sdk/guide/components/ui/prerequisite-gate

`PrerequisiteGate` prevents app content from flashing before an asynchronous,
host-owned prerequisite check finishes. The host's `check` callback reads the
current account/project state; the SDK does not assume a backend endpoint or
store prerequisite state on the device.

```tsx
<PrerequisiteGate
  scopeKey={`${projectId}:${profileId}`}
  check={() => loadRequiredTaskForCurrentAccount()}
  pending={<FullScreenActivityIndicator />}
  renderRequired={(task, refresh) => (
    <RequiredTaskScreen task={task} onSaved={refresh} />
  )}
  onError={logPrerequisiteCheckFailure}
>
  <AppNavigator />
</PrerequisiteGate>
```

- `scopeKey` must change when the signed-in account or project changes. A result
  from the previous scope is hidden immediately while the new check runs.
- Return `null` when nothing is required, or return the host's requirement value
  for `renderRequired`. After saving the required task, call `refresh`; the gate
  checks the server again before revealing its children.
- While loading, `pending` is shown. It defaults to `null`, so the children do
  not render early. Keep the loading view non-blocking and app-localized.
- If `check` rejects (for example, because the device is offline or access is
  unavailable), `onError` is called and the gate renders its children. This is
  deliberately fail-open: it must not lock a person out because a check failed.

This is a presentation gate, not an authorization boundary. The server must
still enforce access rules on protected data and operations. The host must use
an account-scoped, authorized source if the requirement needs to follow the
person across devices. Keep the `check` callback stable where practical; it is
re-read when the `scopeKey` changes or `refresh` is called.
