# edgeLakeCodeQuery

Execute JavaScript programs server-side against Edge Lake event data for complex analysis that requires multiple queries, joins, aggregations, or funnel analysis.

{% hint style="warning" %}
Use dedicated analytics tools first (`domainAnalytics`, `domainErrors`, `edgeLakeTrafficAnalysis`) before falling back to Edge Lake queries. Use `edgeLakeQuery` for simple single queries. Use `edgeLakeCodeQuery` only when you need multi-step analysis.
{% endhint %}

### Parameters

| Parameter   | Type          | Required | Description                                                                                                                               |
| ----------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `channelId` | string (UUID) | Yes      | The Edge Lake channel ID. Must be a channel with `providerId: "edgeLake"`. Get this from the `domains` tool.                              |
| `teamId`    | string (UUID) | Yes      | The team ID the domain belongs to.                                                                                                        |
| `code`      | string        | Yes      | JavaScript code to execute server-side. Has access to `codemode.query(sql)` which returns `{ rows, meta }`. Must return the final result. |

### Constraints

* Maximum 20 queries per execution
* 80-second timeout
* 100KB maximum result size
* Must return a final result (the last expression or explicit return)

### API

Your code has access to:

* **`codemode.query(sql)`** - Execute an SQL query against `lake.events`. Returns `{ rows, meta }`.
* **`Promise.all()`** - Run multiple queries in parallel.
* Standard JavaScript (no external libraries).

### Examples

#### Conversion funnel

```javascript
const [pageViews, addToCarts, checkouts, purchases] = await Promise.all([
  codemode.query(`SELECT COUNT(*) as count FROM lake.events WHERE event_name = 'PageView' AND event_timestamp BETWEEN '2024-01-01T00:00:00Z' AND '2024-01-07T23:59:59Z'`),
  codemode.query(`SELECT COUNT(*) as count FROM lake.events WHERE event_name = 'AddToCart' AND event_timestamp BETWEEN '2024-01-01T00:00:00Z' AND '2024-01-07T23:59:59Z'`),
  codemode.query(`SELECT COUNT(*) as count FROM lake.events WHERE event_name = 'InitiateCheckout' AND event_timestamp BETWEEN '2024-01-01T00:00:00Z' AND '2024-01-07T23:59:59Z'`),
  codemode.query(`SELECT COUNT(*) as count FROM lake.events WHERE event_name = 'Purchase' AND event_timestamp BETWEEN '2024-01-01T00:00:00Z' AND '2024-01-07T23:59:59Z'`)
]);

({
  funnel: [
    { step: 'PageView', count: pageViews.rows[0].count },
    { step: 'AddToCart', count: addToCarts.rows[0].count },
    { step: 'InitiateCheckout', count: checkouts.rows[0].count },
    { step: 'Purchase', count: purchases.rows[0].count }
  ]
})
```

#### Daily revenue trend

```javascript
const result = await codemode.query(`
  SELECT event_timestamp, payload_value, payload_currency
  FROM lake.events
  WHERE event_name = 'Purchase'
    AND event_timestamp BETWEEN '2024-01-01T00:00:00Z' AND '2024-01-07T23:59:59Z'
  ORDER BY event_timestamp
  LIMIT 10000
`);

const dailyRevenue = {};
for (const row of result.rows) {
  const day = row.event_timestamp.split('T')[0];
  if (!dailyRevenue[day]) dailyRevenue[day] = 0;
  dailyRevenue[day] += Number(row.payload_value || 0);
}

Object.entries(dailyRevenue).map(([date, revenue]) => ({ date, revenue }));
```

{% hint style="info" %}
Edge Lake Querying must be enabled for your domain. Contact <support@blotout.io> if you get an "Action not permitted!" error.
{% endhint %}
