# Split Query Log Integration into Two-Step Flow

**Source:** feat/pbac-enforcement branch (PR #3247)

## Problem Statement

The current `POST /query-log-config` endpoint atomically creates both a `ConnectionConfig` (with secrets) and a `QueryLogConfig` in a single API call. This deviates from the established pattern used by discovery monitors, where:

1. **Step 1:** The integration (ConnectionConfig) is created first via `PATCH /connection`
2. **Step 2:** The user optionally creates a MonitorConfig on top of it, referencing the existing `connection_config_key`

The two-step pattern is better because:
- The integration can exist independently (useful for testing connections before committing to a config)
- It reuses the existing ConnectionConfig CRUD endpoints instead of reimplementing connection management
- The frontend already understands this pattern from monitors
- It separates concerns: connection management vs. query log config management

## Current State

**Atomic route** (`query_log_config.py:118-179`):
- `POST /query-log-config` accepts `QueryLogConfigCreate` which includes `connection_type`, `secrets`, and `description`
- Route helper `_create_or_get_connection_config()` creates a `ConnectionConfig` directly via ORM
- Then creates a `QueryLogConfig` (Redis-backed) referencing that connection

**Monitor reference pattern** (`discovery_monitors.py:2207-2336`):
- `EditableMonitorConfig` requires `connection_config_key: str` — an **already-existing** ConnectionConfig
- Calls `get_connection_config_or_error(db, monitor_config.connection_config_key)` to validate the link
- Never creates a ConnectionConfig itself

## Implementation Approach

Strip connection creation out of the query log config route. The ConnectionConfig is created via the existing fides `PATCH /connection` endpoint (already available). The `POST /query-log-config` endpoint only creates the Redis-backed `QueryLogConfig`, referencing an existing connection.

### Changes

**1. Update `QueryLogConfigCreate` schema** (`api/schemas/violation.py`)

Remove `connection_type`, `secrets`, `description` fields. Add required `connection_config_key` field:

```python
class QueryLogConfigCreate(BaseModel):
    name: str
    key: Optional[str] = None
    connection_config_key: str  # must reference an existing ConnectionConfig
    enabled: bool = True
    poll_interval_seconds: int = 300
```

**2. Simplify `create_query_log_config` route** (`api/routes/pbac/query_log_config.py`)

- Remove `_create_or_get_connection_config()` helper
- Remove `_resolve_connection_type()` helper
- Validate that the referenced `ConnectionConfig` exists (like monitors do)
- Validate that the connection type is supported for query logging
- Create only the `QueryLogConfig` entity

```python
@router.post("/query-log-config", ...)
def create_query_log_config(data: QueryLogConfigCreate, ...):
    # 1. Validate ConnectionConfig exists
    connection_config = db.query(ConnectionConfig).filter(
        ConnectionConfig.key == data.connection_config_key
    ).first()
    if not connection_config:
        raise HTTPException(404, "ConnectionConfig not found")

    # 2. Validate connection type supports query logging
    if connection_config.connection_type not in QUERY_LOG_CONNECTORS_BY_TYPE:
        raise HTTPException(422, "Connection type does not support query logging")

    # 3. Create QueryLogConfig only
    entity = query_log_service._config_repo.create(...)
    ...
```

**3. Update `QueryLogConfigResponse`** to derive `connection_type` from the `ConnectionConfig` lookup instead of storing it.

**4. Update demo script** (`demo/pbac_demo.py`) — create the ConnectionConfig via `PATCH /connection` first, then create the query log config referencing it.

**5. Update tests** (`tests/ops/api/test_access_control_routes.py`) — fixture creates ConnectionConfig separately, then creates query log config pointing to it.

## Story Breakdown

| # | Story | Repo | Type | Estimate | Dependencies |
|---|-------|------|------|----------|--------------|
| 1 | Remove connection creation from query log config; require existing `connection_config_key` | Fidesplus | Story | S | - |
| 2 | Update demo script to use two-step flow | Fidesplus | Task | S | #1 |
| 3 | Update route tests for two-step flow | Fidesplus | Task | S | #1 |

## Testing Strategy

- Route tests: create a `ConnectionConfig` fixture, then `POST /query-log-config` with `connection_config_key`
- Negative tests: 404 when `connection_config_key` doesn't exist, 422 when connection type unsupported
- Demo script: verify end-to-end flow still works

## Out of Scope

- Changes to the fides `PATCH /connection` endpoint (already supports all needed connection types)
- Frontend changes (no frontend exists for this yet)
- Changes to the `QueryLogConfig` Redis entity or repository (only the route + schema change)
