# Integration Settings Workflow & Data Flow ## Part 1: How Global Settings Load on Frontend ### Admin Configures Global Settings **URL**: `https://api.igny8.com/admin/system/globalintegrationsettings/1/change/` **What's Stored**: - Platform-wide API keys (OpenAI, DALL-E, Runware) - Default model selections (gpt-4o-mini, dall-e-3, runware:97@1) - Default parameters (temperature: 0.7, max_tokens: 8192) - Default image settings (size, quality, style) **Who Can Access**: Only platform administrators ### Normal User Opens Integration Page **URL**: `https://app.igny8.com/settings/integration` **What Happens**: 1. **Frontend Request**: - User browser requests: `GET /api/v1/system/settings/integrations/openai/` - User browser requests: `GET /api/v1/system/settings/integrations/image_generation/` 2. **Backend Processing** (`integration_views.py` - `get_settings()` method): - Checks if user's account has custom overrides in `IntegrationSettings` table - Gets global defaults from `GlobalIntegrationSettings` singleton - Merges data with this priority: - If account has overrides → use account settings - If no overrides → use global defaults - **NEVER returns API keys** (security) 3. **Response to Frontend**: ``` { "id": "openai", "enabled": true, "model": "gpt-4o-mini", // From global OR account override "temperature": 0.7, // From global OR account override "max_tokens": 8192, // From global OR account override "using_global": true // Flag: true if using defaults } ``` 4. **Frontend Display**: - Shows current model selection - Shows "Using platform defaults" badge if `using_global: true` - Shows "Custom settings" badge if `using_global: false` - User can change model, temperature, etc. - **API key status is NOT shown** (user cannot see/change platform keys) --- ## Part 2: How User Changes Are Saved ### User Changes Settings on Frontend 1. **User Actions**: - Opens settings modal - Changes model from `gpt-4o-mini` to `gpt-4o` - Changes temperature from `0.7` to `0.8` - Clicks "Save" 2. **Frontend Request**: - Sends: `PUT /api/v1/system/settings/integrations/openai/` - Body: `{"model": "gpt-4o", "temperature": 0.8, "max_tokens": 8192}` 3. **Backend Processing** (`integration_views.py` - `save_settings()` method): - **CRITICAL SECURITY**: Strips ANY API keys from request (apiKey, api_key, openai_api_key, etc.) - Validates account exists - Builds clean config with ONLY allowed overrides: - For OpenAI: model, temperature, max_tokens - For Image: service, model, image_quality, image_style, sizes - Saves to `IntegrationSettings` table: ``` account_id: 123 integration_type: "openai" config: {"model": "gpt-4o", "temperature": 0.8, "max_tokens": 8192} is_active: true ``` 4. **Database Structure**: - **GlobalIntegrationSettings** (1 row, pk=1): - Contains: API keys + default settings - Used by: ALL accounts for API keys - **IntegrationSettings** (multiple rows): - Row per account per integration type - Contains: ONLY overrides (no API keys) - Example: ``` id | account_id | integration_type | config 100 | 123 | openai | {"model": "gpt-4o", "temperature": 0.8} 101 | 456 | openai | {"model": "gpt-4.1", "max_tokens": 4000} 102 | 123 | image_generation| {"service": "runware", "model": "runware:100@1"} ``` 5. **Next Request from User**: - Frontend requests: `GET /api/v1/system/settings/integrations/openai/` - Backend finds IntegrationSettings row for account 123 - Returns: `{"model": "gpt-4o", "temperature": 0.8, "using_global": false}` - User sees their custom settings --- ## Data Flow Architecture ``` ┌─────────────────────────────────────────────────────────────┐ │ ADMIN SIDE │ │ https://api.igny8.com/admin/ │ │ │ │ GlobalIntegrationSettings (pk=1) │ │ ├── openai_api_key: "sk-xxx" ← Platform-wide │ │ ├── openai_model: "gpt-4o-mini" ← Default │ │ ├── openai_temperature: 0.7 ← Default │ │ ├── dalle_api_key: "sk-xxx" ← Platform-wide │ │ ├── runware_api_key: "xxx" ← Platform-wide │ │ └── image_quality: "standard" ← Default │ └─────────────────────────────────────────────────────────────┘ │ │ Backend reads from ↓ ┌─────────────────────────────────────────────────────────────┐ │ BACKEND API LAYER │ │ integration_views.py │ │ │ │ get_settings(): │ │ 1. Load GlobalIntegrationSettings (for defaults) │ │ 2. Check IntegrationSettings (for account overrides) │ │ 3. Merge: account overrides > global defaults │ │ 4. Return to frontend (NO API keys) │ │ │ │ save_settings(): │ │ 1. Receive request from frontend │ │ 2. Strip ALL API keys (security) │ │ 3. Save ONLY overrides to IntegrationSettings │ └─────────────────────────────────────────────────────────────┘ │ │ API sends data ↓ ┌─────────────────────────────────────────────────────────────┐ │ FRONTEND - USER SIDE │ │ https://app.igny8.com/settings/integration │ │ │ │ User sees: │ │ ├── Model: gpt-4o-mini (dropdown) │ │ ├── Temperature: 0.7 (slider) │ │ ├── Status: ✓ Connected (test connection works) │ │ └── Badge: "Using platform defaults" │ │ │ │ User CANNOT see: │ │ ✗ API keys (security) │ │ ✗ Platform configuration │ └─────────────────────────────────────────────────────────────┘ │ │ User changes settings ↓ ┌─────────────────────────────────────────────────────────────┐ │ IntegrationSettings Table │ │ (Per-account overrides - NO API KEYS) │ │ │ │ Account 123: │ │ ├── openai: {"model": "gpt-4o", "temperature": 0.8} │ │ └── image_generation: {"service": "runware"} │ │ │ │ Account 456: │ │ ├── openai: {"model": "gpt-4.1"} │ │ └── image_generation: (no row = uses global defaults) │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Important Security Rules 1. **API Keys Flow**: - Admin sets → GlobalIntegrationSettings - Backend uses → For ALL accounts - Frontend NEVER sees → Security - Users NEVER save → Stripped by backend 2. **Settings Flow**: - Admin sets defaults → GlobalIntegrationSettings - Users customize → IntegrationSettings (overrides only) - Backend merges → Global defaults + account overrides - Frontend displays → Merged result (no keys) 3. **Free Plan Restriction**: - Cannot create IntegrationSettings rows - Must use global defaults only - Enforced at frontend (UI disabled) - TODO: Add backend validation --- ## Example Scenarios ### Scenario 1: New User First Visit - User has NO IntegrationSettings row - Backend returns global defaults - `using_global: true` - User sees platform defaults - API operations use platform API key ### Scenario 2: User Customizes Model - User changes model to "gpt-4o" - Frontend sends: `{"model": "gpt-4o"}` - Backend creates IntegrationSettings row - Next visit: `using_global: false` - API operations use platform API key + user's model choice ### Scenario 3: User Resets to Default - Frontend sends: `{"model": "gpt-4o-mini"}` (same as global) - Backend still saves override row - Alternative: Delete row to truly use global - TODO: Add "Reset to defaults" button ### Scenario 4: Admin Changes Global Default - Admin changes global model to "gpt-4.1" - Users WITH overrides: See their custom model - Users WITHOUT overrides: See new "gpt-4.1" default - All users: Use platform API key