# flow-complete.json - Comprehensive walkerOS Flow Example

This example demonstrates **ALL JSON-compatible walkerOS features** with
real-world patterns. It contains two named flows (`web` and `server`) showing a
complete event tracking architecture.

## Architecture

```
┌─────────────────────────────────────────────────────────────────────────────┐
│ WEB FLOW                                                                    │
│                                                                             │
│   Browser Source ─┐                                                         │
│   DataLayer Source ──▶ [Enricher] ──▶ Collector ──▶ GA4                     │
│   Demo Source ────┘                              ├──▶ API                   │
│                                                  └──▶ Debug                 │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│ SERVER FLOW                                                                 │
│                                                                             │
│   HTTP Source ──▶ [Filter] ──▶ [Fingerprint] ──▶ Collector                  │
│        │              │                          │                          │
│        │ ingest:      │ env:                     ▼                          │
│        │ IP, UA,      │ filter rules      Meta Destination                  │
│        │ lang, ref,   │                   Demo Destination                  │
│        │ anon-IP(fn)  │                                                     │
│        └──────────────┘                                                     │
│                                                                             │
│   Source cache: built-in tier (ttl 300s, on GET ingest.method+path)         │
└─────────────────────────────────────────────────────────────────────────────┘
```

## Quick Start

### Run Web Flow

```bash
cd walkerOS
npx walkeros run packages/cli/examples/flow-complete.json --flow web
# Open http://localhost:3000 - demo events fire automatically
```

### Run Server Flow

```bash
cd walkerOS
npx walkeros run packages/cli/examples/flow-complete.json --flow server

# Test health
curl http://localhost:8080/health

# Send test event
curl -X POST http://localhost:8080/collect \
  -H "Content-Type: application/json" \
  -d '{
    "name": "order complete",
    "data": {"id": "ORD-999", "total": 99.99, "currency": "EUR"},
    "user": {"email": "test@example.com", "id": "U-123"},
    "nested": [{"entity": "product", "data": {"id": "P1", "name": "Item", "price": 99.99, "quantity": 1}}]
  }'
```

### Run Both (Full Pipeline)

```bash
# Terminal 1: Start server
npx walkeros run packages/cli/examples/flow-complete.json --flow server

# Terminal 2: Start web (sends to server via API destination)
npx walkeros run packages/cli/examples/flow-complete.json --flow web
```

---

## Feature Inventory

### Features Used (68)

#### Mapping - Value Extraction

| Feature           | Location          | Example                                                      |
| ----------------- | ----------------- | ------------------------------------------------------------ |
| Key extraction    | GA4 page_view     | `"page_title": "data.title"`                                 |
| Static value      | Meta ViewContent  | `"content_type": { "value": "product" }`                     |
| Key with fallback | GA4 add_to_cart   | `{ "key": "data.currency", "value": "$variables.currency" }` |
| Nested key (deep) | dataLayer mapping | `"items.0.item_id"`                                          |
| Fallback array    | GA4 view_item     | `[{ "key": "data.sku" }, { "key": "data.id" }]`              |

#### Mapping - Structure

| Feature               | Location           | Example                                                     |
| --------------------- | ------------------ | ----------------------------------------------------------- |
| Map (object)          | GA4 purchase       | `"data": { "map": { ... } }`                                |
| Loop with "nested"    | GA4 purchase items | `{ "loop": ["nested", { "map": {...} }] }`                  |
| Loop with "this"      | GA4 add_to_cart    | `{ "loop": ["this", { "map": {...} }] }`                    |
| Set (single value)    | Meta ViewContent   | `"content_ids": { "set": ["data.id"] }`                     |
| Set (multiple values) | Meta settings      | `"external_id": { "set": ["user.device", "user.session"] }` |
| Direct passthrough    | Meta PageView      | `"data": "data"`                                            |
| Config-level data     | API destination    | `"data": { "map": { "sent_at": {...} } }`                   |

#### Mapping - Control

| Feature              | Location            | Example                                                     |
| -------------------- | ------------------- | ----------------------------------------------------------- |
| Consent-gated field  | API destination     | `{ "key": "user.email", "consent": { "marketing": true } }` |
| Ignore rule          | GA4/API test events | `{ "ignore": true }`                                        |
| Wildcard action (\*) | GA4 test, Meta      | `"test": { "*": { "ignore": true } }`                       |
| Wildcard entity (\*) | Meta click handler  | `"*": { "click": { "name": "CustomEvent" } }`               |

#### Variables

| Feature              | Location         | Example                                        |
| -------------------- | ---------------- | ---------------------------------------------- |
| Root-level variables | Root             | `"currency": "EUR"`                            |
| Flow-level variables | server.variables | `"metaPixelId": "$env.META_PIXEL_ID:..."`      |
| Environment variable | Variables        | `"$env.GA4_MEASUREMENT_ID:G-DEMO123456"`       |
| Env with default     | Variables        | `"$env.API_URL:http://localhost:8080/collect"` |
| $var reference       | GA4 settings     | `"$var.ga4MeasurementId"`                      |

#### Sources

| Feature                 | Location      | Example                                           |
| ----------------------- | ------------- | ------------------------------------------------- |
| Primary source          | browser       | `"primary": true`                                 |
| Multiple sources        | web flow      | browser + dataLayer + demo                        |
| Source-level mapping    | dataLayer     | `"mapping": { "gtag": { "add_to_cart": {...} } }` |
| Pre-collector chain     | dataLayer     | `"next": "enricher"`                              |
| Pre-collector array     | http (server) | `"next": ["filter"]` (array form)                 |
| Require (deferred init) | dataLayer     | `"require": ["session"]`                          |
| Demo source events      | demo          | Pre-configured test events                        |

#### Transformers

| Feature                 | Location  | Example                            |
| ----------------------- | --------- | ---------------------------------- |
| Fingerprint transformer | server    | Hash context fields to `user.hash` |
| Post-collector chain    | Meta      | `"before": "fingerprint"`          |
| Pre-collector chain     | dataLayer | `"next": "enricher"`               |

#### Destinations

| Feature                 | Location         | Example                                     |
| ----------------------- | ---------------- | ------------------------------------------- |
| Require (deferred init) | GA4              | `"require": ["consent", "user"]`            |
| Destination consent     | GA4              | `"consent": { "marketing": true }`          |
| Destination mapping     | All destinations | Entity/action to vendor events              |
| Multiple destinations   | Both flows       | GA4 + API, Meta + Demo                      |
| Batch option            | API              | `"batch": 5`                                |
| Transform function      | API              | `"transform": "$code:(data) => ..."`        |
| Empty consent (always)  | debug            | `"consent": {}` (fires without consent)     |
| Inline `validate:`      | GA4              | Step-level schema check on `order complete` |

#### Collector

| Feature           | Location         | Example                                 |
| ----------------- | ---------------- | --------------------------------------- |
| Tagging           | Both collectors  | `"tagging": 1`                          |
| Consent defaults  | Both collectors  | `"consent": { "functional": true }`     |
| Globals           | Both collectors  | `"environment": "demo"`                 |
| Custom properties | web collector    | `"custom": { "campaign": "flow-demo" }` |
| User defaults     | web collector    | `"user": { "id": "anonymous" }`         |
| Dynamic global    | server collector | `"startedAt": "$code:Date.now()"`       |

#### Server-Specific

| Feature               | Location        | Example                                                                 |
| --------------------- | --------------- | ----------------------------------------------------------------------- |
| Ingest metadata       | http source     | `"context.ip": "ip"`                                                    |
| Language header       | ingest          | `"context.language": "headers.accept-language"`                         |
| Ingest computed field | http source     | `"fn": "$code:(ip) => ip.replace(...)"`                                 |
| Policy                | Meta            | Pre-processing field transformation                                     |
| Policy consent-gated  | Meta            | `"user_data.em"` with consent                                           |
| Policy nested map     | Meta            | `"custom_data.request_meta": { "map": {...} }`                          |
| Local package path    | server packages | `"path": "../../core"` (resolve from filesystem)                        |
| Source cache          | http source     | `"cache": { "rules": [...] }` (built-in tier)                           |
| Cache match rule      | http source     | `"match": { "key": "ingest.method", "operator": "eq", "value": "GET" }` |
| Cache TTL             | http source     | `"ttl": 300` (seconds)                                                  |
| Cache response update | http source     | `"update": { "headers.X-Cache": { "key": "cache.status" } }`            |

#### Browser Source

| Feature         | Location | Example                            |
| --------------- | -------- | ---------------------------------- |
| Prefix          | browser  | `"prefix": "data-elb"`             |
| Auto pageview   | browser  | `"pageview": true`                 |
| Session consent | browser  | `"session": { "consent": {...} }`  |
| ELB binding     | browser  | `"elb": "elb"`, `"elbLayer": true` |

---

### Features NOT Used (6)

#### Now Available via $code: Prefix ✅

These features are now fully supported in JSON via `$code:` prefix (and ARE used
in this example):

| Feature                 | Status                            |
| ----------------------- | --------------------------------- |
| `fn:` function          | ✅ Used via `$code:` in GA4 value |
| `condition:`            | ✅ Used via `$code:` in variables |
| Custom transformer code | ✅ Used in enricher, filter       |
| Custom destination code | ✅ Used in debug logger           |

#### Omitted for Clarity (6)

These features could be added but were omitted to keep the example focused:

| Feature                   | Why Omitted                   |
| ------------------------- | ----------------------------- |
| Multiple named flows (3+) | Two flows sufficient for demo |
| Queue config              | Advanced batching scenario    |
| Retry config              | Advanced error handling       |
| Custom fetch options      | API destination advanced      |
| Custom headers in API     | Would add complexity          |

---

## Data Flow Examples

### Order Complete (Server Flow)

1. **Ingest**: Request metadata extracted (IP, user-agent, referer) to
   `context.*`
2. **Policy**: Pre-processes event:
   - `user_data.em` from `user.email` (only if marketing consent)
   - `user_data.external_id` from `user.id`
   - `custom_data.server_processed` = `true`
   - `custom_data.request_meta` = `{ ip, ua }` from context
3. **Fingerprint**: Hashes context fields to `user.hash`
4. **Mapping**: Transforms to Meta format:
   - `"name": "Purchase"`
   - `value`, `currency`, `order_id` extracted
   - `contents` via `$ref` to definition loop

### Product Add (Web Flow)

1. **DataLayer Source**: Captures `add_to_cart` event
2. **Source Mapping**: Transforms to `product add` with walkerOS structure
3. **Enricher**: Adds enrichedAt timestamp to context
4. **Collector**: Adds globals, consent, user data
5. **GA4 Mapping**: Transforms to `add_to_cart` with items array
6. **API Destination**: Batches and sends to server (if batch size reached)

---

## Environment Variables

| Variable             | Default                         | Description                |
| -------------------- | ------------------------------- | -------------------------- |
| `GA4_MEASUREMENT_ID` | `G-DEMO123456`                  | Google Analytics 4 ID      |
| `API_URL`            | `http://localhost:8080/collect` | Server collection endpoint |
| `META_PIXEL_ID`      | `123456789012345`               | Meta Pixel ID              |
| `META_ACCESS_TOKEN`  | `demo_token`                    | Meta Conversions API token |
