# Raw SQL Query Setup Guide

## Overview

The backend now supports raw SQL queries (Script 1 style) for complex options flow analysis. This guide explains how to set it up.

## Prerequisites

1. **Supabase RPC Function**: You need to create the `exec_sql` function in your Supabase database
2. **Script 1 SQL**: Your complex SQL query needs to be parameterized and added to the codebase

## Step 1: Create RPC Function in Supabase

Run the SQL from `database/rpc_functions.sql` in your Supabase SQL Editor:

```sql
CREATE OR REPLACE FUNCTION exec_sql(
  query_text text,
  params jsonb DEFAULT '[]'::jsonb
)
RETURNS jsonb
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
-- See database/rpc_functions.sql for full definition
$$;
```

## Step 2: Add Your Script 1 SQL Query

1. **Open** `backend/src/queries/optionsFlowQuery.js`
2. **Find** the `optionsFlowQuerySQL` constant (around line 20)
3. **Replace** the placeholder comment with your actual Script 1 SQL query
4. **Parameterize** all values using `$1`, `$2`, `$3`, etc.

### Example Parameterization

**Before (hardcoded):**
```sql
WHERE created_at >= '2024-01-01'
  AND created_at <= '2024-01-31'
  AND total_premium >= 1000000
LIMIT 100;
```

**After (parameterized):**
```sql
WHERE created_at >= $1::date
  AND created_at <= $2::date
  AND total_premium >= $3::numeric
LIMIT $4::integer;
```

## Step 3: Update Parameter Builder

Update `buildOptionsFlowParams()` in `optionsFlowQuery.js` to match your SQL parameter order:

```javascript
export function buildOptionsFlowParams(params = {}) {
  return [
    params.startDate,           // $1
    params.endDate,             // $2
    params.minNotional,         // $3
    params.limit                // $4
    // Add more as needed
  ];
}
```

## Step 4: Enable Raw SQL in API Calls

### In Routes

The route automatically supports raw SQL via query parameter:

```javascript
// Use raw SQL
GET /api/options-flow?useRawSQL=true&startDate=2024-01-01&endDate=2024-01-31

// Use query builder (default)
GET /api/options-flow?startDate=2024-01-01
```

### In Code

```javascript
import { OptionsFlowQuery } from './queries/optionsFlowQuery.js';

// Use raw SQL
const flows = await OptionsFlowQuery.getRecentFlow(filters, true);

// Use query builder (default)
const flows = await OptionsFlowQuery.getRecentFlow(filters, false);
```

## Parameter Types

Use these PostgreSQL type casts in your SQL:

- **Dates**: `$1::date`, `$2::timestamp`
- **Numbers**: `$3::numeric`, `$4::integer`, `$5::float`
- **Text**: `$6::text`, `$7::varchar(10)`
- **Booleans**: `$8::boolean`

## Fallback Behavior

If raw SQL fails or isn't configured:
- The system automatically falls back to the query builder
- No errors are thrown (warning logged to console)
- API continues to work normally

This ensures backward compatibility and graceful degradation.

## Testing

### Test in Supabase SQL Editor First

```sql
SELECT * FROM exec_sql(
  'SELECT * FROM options_flow WHERE created_at >= $1::date LIMIT $2::integer',
  '["2024-01-01", 10]'::jsonb
);
```

### Test via API

```bash
# With raw SQL
curl "http://localhost:3001/api/options-flow?useRawSQL=true&startDate=2024-01-01&limit=10"

# Without (query builder)
curl "http://localhost:3001/api/options-flow?startDate=2024-01-01&limit=10"
```

## Environment Variables

Ensure your `.env` has:

```env
SUPABASE_URL=your_url
SUPABASE_KEY=your_service_key
SUPABASE_ANON_KEY=your_anon_key  # Optional but recommended
```

## Troubleshooting

### Error: "exec_sql RPC function not found"

- Run `database/rpc_functions.sql` in Supabase SQL Editor
- Verify the function exists: `SELECT proname FROM pg_proc WHERE proname = 'exec_sql';`

### Error: "SQL query failed"

- Check your SQL syntax in Supabase SQL Editor first
- Verify parameter types match (e.g., `$1::date` not `$1::text`)
- Check parameter count matches your `buildOptionsFlowParams()` function

### Query returns empty results

- Test the SQL directly in Supabase SQL Editor with sample parameters
- Verify date formats are correct (YYYY-MM-DD)
- Check table names and column names match your schema

## Security Notes

⚠️ **Important**: The `exec_sql` function uses `SECURITY DEFINER` which runs with elevated privileges. 

- Only grant execute permission to trusted roles
- Always use parameterized queries (never string concatenation)
- Validate input parameters before passing to `rawQuery()`
- Consider creating specific stored procedures for each query type instead of generic `exec_sql`

## Best Practices

1. **Test First**: Always test SQL queries in Supabase SQL Editor before adding to code
2. **Parameterize Everything**: Never use string interpolation for SQL queries
3. **Type Safety**: Always use PostgreSQL type casts (`::date`, `::numeric`, etc.)
4. **Error Handling**: The system falls back gracefully, but log errors for debugging
5. **Documentation**: Document your SQL query parameters in code comments

