# Data Flow

This document describes how data moves through AjaxPress -- from settings storage to runtime behavior.

## Settings Lifecycle

### Load

```
WordPress Options DB
       |
       v
Options::get_settings()
  ├── Read each option with get_option()
  ├── Merge with defaults from get_default_settings()
  ├── Run migrations if needed (migrate_legacy_settings)
  └── Filter premium features if license inactive
       |
       +--> Admin: Serialized into window.ajaxpress_admin_vars.settings
       |           (consumed by Solid.js stores)
       |
       +--> Frontend: Serialized into window.ajaxpress_vars.settings
                      (consumed by IframeContainer)
```

### Save (Admin)

```
User changes setting in UI
       |
       v
Solid.js store mutation (reactive)
       |
       v
AutosaveContext detects dirty state
       |
       v (2-second debounce)
       |
       v
POST /wp-json/ajaxpress/settings
  └── X-WP-Nonce authentication
       |
       v
REST::save_settings()
  └── Options::update_settings()
       └── update_option() for each changed value
       |
       v
Response: { success: true }
       |
       v
AutosaveContext: status = 'saved' (2s) -> 'idle'
```

### Export/Import

```
Export: Settings store -> JSON blob -> File download
Import: JSON file -> Validation -> POST /settings -> Store update -> Page reload
Reset:  Double confirmation -> POST /settings (defaults) -> Page reload
```

## Frontend Navigation Data Flow

### Page-to-Page (SPA)

```
Child Iframe                    Parent Frame
     |                               |
     | -- AJAXPRESS_NAVIGATE ------> |
     |    { url }                     |
     |                               | Load URL in background iframe
     |                               |
     |    Background Iframe           |
     |         |                      |
     |         | -- AJAXPRESS_NAV --> |
     |         |    { url, title }    |
     |                               | Crossfade animation
     |                               | history.pushState()
     |                               | Scroll to top
     |                               |
     | <-- (now visible as main) --- |
```

### Prefetch

```
Child Iframe                    Parent Frame
     |                               |
     | -- PREFETCH_REQUEST --------> |
     |    { url }                     |
     |                               | Load in background iframe
     |                               |
     |    Background Iframe           |
     |         |                      |
     |         | -- AJAXPRESS_NAV --> |
     |                               | prefetchReady = true
     |                               | (waits for click)
     |                               |
     | -- AJAXPRESS_NAVIGATE ------> |
     |    { url }                     |
     |                               | Immediate crossfade
     |                               | (no loading wait)
```

### Form Submission

```
Child Iframe                    Parent Frame
     |                               |
     | -- FORM_SUBMIT -------------> |
     |    { action, method, data }    |
     |                               | Create form in background iframe
     |                               | Submit form
     |                               |
     |    Background Iframe           |
     |         |                      |
     |         | -- AJAXPRESS_NAV --> |
     |                               | Crossfade to response page
```

## Cloudflare Cache Data Flow

### Request Path (Edge)

```
Browser Request
       |
       v
Cloudflare Edge (Worker)
  ├── Check: GET request? (else BYPASS)
  ├── Check: Static asset? (else let pass)
  ├── Check: Logged-in cookie? (else BYPASS)
  ├── Check: Bypass pattern match? (else BYPASS)
  |
  ├── Cache lookup
  |   ├── HIT: Return cached response + X-AjaxPress-Cache: HIT
  |   └── MISS: Fetch from origin
  |             ├── Cache response at edge
  |             └── Return + X-AjaxPress-Cache: MISS
  |
  └── BYPASS: Fetch from origin + X-AjaxPress-Cache: BYPASS
```

### Auto-Purge Flow

```
WordPress Content Change (post save, term edit, comment, etc.)
       |
       v
Cloudflare\Hooks handler
       |
       v
Queue URLs in static $pending_urls
  ├── Post permalink
  ├── Archive pages
  ├── Category/tag archives
  ├── Author archive
  └── Home page
       |
       v (shutdown hook)
       |
  [> 25 URLs?]
       |            |
      yes          no
       |            |
       v            v
  purge_all()  purge_urls() (batches of 30)
       |            |
       v            v
  Cloudflare API v4 purge endpoint
```

## License Validation Flow

### Frontend (Public Site)

```
Page Load
       |
       v
License() initializes
       |
  [localStorage cache valid?] (12-hour TTL)
       |            |
      yes          no
       |            |
       v            v
  Use cached    [Online?]
  status           |
                  yes
                   |
                   v
              POST to license endpoint
              { site_url, license_key }
                   |
                   v
              Cache result in localStorage
                   |
                   v
              window.licenseStatus = { isValid }
```

### Admin Panel

```
Panel Load
       |
       v
LicenseContext initializes from window.ajaxpress_admin_vars
       |
       v
refreshLicense() checks age (1-hour threshold)
       |
  [Stale?]
       |      |
      yes    no
       |      |
       v      v
  POST to   Use current
  license   state
  endpoint
       |
       v
  Update store + localStorage cache
```

## State Synchronization

### Admin Vars (PHP -> JS)

PHP serializes state into two window globals consumed by JavaScript:

**`window.ajaxpress_admin_vars`** (Admin only):
- `settings` -- Current settings (all options)
- `default_settings` -- Default values
- `rest` -- `{ url, nonce }` for API calls
- `plugin` -- `{ url, path, version }`
- `site` -- `{ name, url, admin_url, language }`
- `server` -- `{ php, mysql, platform }`
- `license` -- License object
- `cf_status` -- Cloudflare connection status
- `diagnostic` -- Permission state
- `tour` -- Tour completion state

**`window.ajaxpress_vars`** (Frontend only):
- `settings` -- Current settings
- `rest` -- `{ url, nonce }`
- `site` -- `{ name, language, email }`
- `plugin` -- `{ url, version }`
- `navigation` -- Boolean (filterable)
- `user_logged_in` -- Boolean
- `license` -- License data
- `debug` -- WP_DEBUG flag
