> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pastures.farm/llms.txt
> Use this file to discover all available pages before exploring further.

# Demo Mode Development Guide

> How to add and maintain demo data for Pastures features.

## Overview

Demo mode lets developers and users explore the full Pastures UI without a running Engine backend. When enabled, all API calls return synthetic data with a simulated network delay.

## Data Flow

```
isGlobalDemoMode()
  ├── true  → load DEMO_* constants (with simulated delay)
  └── false → isEngineConfigured()?
                ├── true  → engineFetch() → safeJson()
                └── false → show "Configure Engine" prompt
```

## Two Demo Data Patterns

### Pattern 1: `engineFetch`-based pages

Pages that call `engineFetch()` get demo data automatically via `getDemoResponse()` in `lib/demoResponses.ts`. Add a new case for your API path:

```typescript theme={null}
// lib/demoResponses.ts
export function getDemoResponse(path: string): any {
  switch (path) {
    // ... existing cases
    case '/api/my-feature':
      return {
        items: [
          { id: 'demo-1', name: 'Demo item', status: 'healthy' },
          { id: 'demo-2', name: 'Another item', status: 'warning' },
        ],
      };
  }
}
```

### Pattern 2: Inline `fetch` pages

Pages that use `fetch` directly (instead of `engineFetch`) define `DEMO_*` constants and check demo mode in `onMounted`:

```typescript theme={null}
const DEMO_METRICS = {
  cpu: 42.5,
  memory: 68.1,
  pods: 127,
};

onMounted(async () => {
  if (isGlobalDemoMode()) {
    await new Promise((r) => setTimeout(r, 400));
    metrics.value = DEMO_METRICS;
    loading.value = false;
    return;
  }

  // real API call
  const res = await fetch(`${engineUrl}/api/metrics`, { headers });
  metrics.value = await res.json();
  loading.value = false;
});
```

## Best Practices

<Warning>
  Never silently fall back to demo data when the Engine is configured and expected to respond. If an API call fails in non-demo mode, surface the error to the user rather than quietly substituting synthetic data.
</Warning>

### Realistic data

* Use plausible values: realistic cluster names (`prod-us-east-1`), version strings (`v1.28.4+rke2r1`), timestamps, and counts.
* Include a mix of healthy and unhealthy states so the UI exercises all code paths.
* Match the exact response shape the Engine returns — demo data doubles as a contract test.

### Simulated delay

Always add a short delay (300–500 ms) before resolving demo data. This exercises loading states and prevents UI flicker bugs from hiding behind instant responses.

```typescript theme={null}
await new Promise((r) => setTimeout(r, 400));
```

### Naming conventions

* Prefix constants with `DEMO_` (e.g., `DEMO_ADVISORIES`, `DEMO_CLUSTERS`).
* Keep constants at the top of the `<script setup>` block or in `lib/demoResponses.ts`.

### Testing both paths

When developing a feature, toggle demo mode on and off in **Settings** to verify:

1. The UI renders correctly with demo data.
2. The UI renders correctly with live Engine data (or shows an appropriate error).
3. Loading states display during the simulated delay.
