diff --git a/recipe-portal/.claude/claude.md b/recipe-portal/.claude/claude.md new file mode 100644 index 00000000..93872bf9 --- /dev/null +++ b/recipe-portal/.claude/claude.md @@ -0,0 +1,218 @@ +# QuickStarts API Toolkit - VERSION 1.0 COMPLETE ✅ + +## Project Status: PRODUCTION READY +The recipe portal has been fully implemented with all core functionality working correctly. Version 1.0 includes robust authentication, smart parameters, race condition fixes, and comprehensive recipe execution capabilities. + +## ✅ VERSION 1.0 FEATURES IMPLEMENTED + +### Authentication System +- **Multi-Configuration Support**: Named configs for different environments (Production, Staging, etc.) +- **Configuration-Specific Token Caching**: Isolated token storage per client configuration +- **Race Condition Fixes**: AbortController-based request cancellation prevents mixed authentication data +- **Seamless Config Switching**: No browser refresh required when switching between authentication configs +- **Smart Parameter Isolation**: Dropdowns always show correct data for current authenticated configuration +- **Session Management**: Clean session termination with "End Session" functionality + +### Smart Parameter System +- **Automatic Resource Detection**: Detects workbooks, teams, members, data models, etc. +- **Dynamic Dropdown Population**: Auto-populates selection lists with authenticated user's available resources +- **Dependency Management**: Dependent parameters (e.g., workbook → materialization schedules) +- **Cross-Configuration Isolation**: Parameters refresh correctly when switching authentication configs +- **Real-time Updates**: Parameters update immediately upon authentication changes + +### Recipe Execution Engine +- **Binary File Support**: Proper handling of PDF, CSV, and other binary downloads +- **Multi-Output Methods**: Browser downloads AND console responses +- **Extended Timeouts**: 5-minute timeout for long-running operations (materialization, exports) +- **Progress Monitoring**: Real-time status updates during execution +- **Error Handling**: Comprehensive error reporting and recovery + +### User Interface +- **Consistent Tab Styling**: Professional blue theme across all tab interfaces +- **Responsive Design**: Works on desktop and mobile devices +- **Real-time Feedback**: Immediate visual feedback for all user actions +- **Clean Professional Appearance**: No emojis in production logging (configurable) + +## 🎉 VERSION 1.0 PRODUCTION RELEASE READY + +The QuickStarts API Toolkit Version 1.0 is a complete, production-ready application that provides: + +- **Professional API exploration interface** for Sigma Computing APIs +- **Robust authentication system** with multi-environment support +- **Smart parameter detection** with real-time dropdown population +- **Comprehensive recipe execution engine** with proper file handling +- **Race condition-free user experience** with seamless config switching +- **Standalone code compatibility** for direct VS Code/Node.js usage +- **Clean, maintainable architecture** ready for future enhancements + +All core functionality has been implemented, tested, and documented. The application is ready for user adoption and production deployment. + +## 🔧 AUTHENTICATION CONFIG RACE CONDITION FIX + +### Problem Description +When switching between different authentication configurations (e.g., Production vs Staging environments), endpoint operations would use data from the wrong Sigma instance. This occurred because: + +1. User authenticates with Config A (e.g., AWS US West) +2. User switches to Config B (e.g., GCP) and authenticates +3. Smart parameters and API calls still used the baseURL from Config A +4. Operations returned data from the wrong Sigma environment + +### Root Cause Analysis +The race condition was caused by: +- Token cache files only stored `token` and `clientId` but not the associated `baseURL` +- API routes used hardcoded/environment baseURLs instead of auth config baseURLs +- Frontend components didn't pass the current config's baseURL through to API calls +- No connection between cached authentication tokens and their originating server configurations + +### Solution Implementation (August 2025) + +**1. Enhanced Token Storage** +- Modified `recipes/get-access-token.js` to cache `baseURL` and `authURL` with tokens +- Updated `app/api/token/route.ts` to return baseURL with token data +- Enhanced token cache structure to include server configuration + +**2. API Route Updates** +- `/api/resources/route.ts`: Now accepts `baseURL` parameter and uses it for all fetches +- `/api/call/route.ts`: Uses provided baseURL instead of environment default +- `/api/execute/route.ts`: Caches tokens with their associated baseURL/authURL + +**3. Frontend Component Chain** +- `app/page.tsx`: Stores and passes `authBaseURL` from auth config +- `components/CodeViewer.tsx`: Retrieves and passes baseURL to SmartParameterForm +- `components/SmartParameterForm.tsx`: Uses baseURL for resource API calls +- `components/QuickApiExplorer.tsx` & `QuickApiModal.tsx`: Pass baseURL for API operations + +**4. Race Condition Prevention** +- All API calls now use the baseURL from the current authentication configuration +- Token cache includes server configuration to prevent cross-environment data mixing +- AbortController cancellation prevents stale requests from completing + +### Files Modified +- `recipes/get-access-token.js` - Enhanced token caching +- `app/api/token/route.ts` - Return baseURL with tokens +- `app/api/resources/route.ts` - Accept and use provided baseURL +- `app/api/call/route.ts` - Use auth config baseURL +- `app/api/execute/route.ts` - Cache tokens with server config +- `components/CodeViewer.tsx` - Store and pass authBaseURL +- `components/SmartParameterForm.tsx` - Use baseURL for resource calls +- `components/QuickApiExplorer.tsx` - Pass baseURL to modal +- `components/QuickApiModal.tsx` - Use baseURL for API calls +- `app/page.tsx` - Track authBaseURL state + +### Testing Strategy +1. Authenticate with Config A (e.g., AWS US West) +2. Load smart parameters - verify data is from Config A environment +3. Switch to Config B (e.g., GCP) and authenticate +4. Load smart parameters - verify data is now from Config B environment +5. Execute recipes - confirm operations use correct Sigma instance +6. Verify no cross-environment data contamination + +### Prevention Measures +- All authentication tokens now include their originating server configuration +- API calls require explicit baseURL parameter instead of using defaults +- Frontend components maintain auth config state throughout the chain +- Request cancellation prevents race conditions during config switching + +This fix ensures that endpoint operations always use data from the correct Sigma instance matching the current authentication configuration. + +## 🚨 CRITICAL BUG FIX: Authentication Configuration Selection Race Condition (August 28, 2025) + +### Issue Discovered +Even after implementing the comprehensive race condition fix above, a **deeper issue** was discovered where the authentication script (`get-access-token.js`) was **always using the default configuration** from encrypted storage instead of the user-selected configuration. + +### Symptoms +- User clicks "End Session" and clears all tokens ✅ +- User selects "PhilB - PROD" configuration from dropdown ✅ +- User clicks "🔐 Authenticate Now" ✅ +- **BUG**: System still authenticates with "QS Fundamentals" (default config) ❌ +- Token created with wrong clientId (`8f92dcde` instead of `77d4c471`) ❌ +- API calls return data from wrong Sigma environment ❌ + +### Root Cause Analysis +The authentication script had **no mechanism** to receive the user's configuration selection: + +```javascript +// In get-access-token.js - BEFORE FIX +function getStoredCredentials(configName) { + // configName was always undefined! + let targetName = configName; + if (!targetName) { + // Always fell back to default + targetName = allCredentials._metadata?.defaultSet || Object.keys(allCredentials).find(k => k !== '_metadata'); + } +} +``` + +**The authentication modal UI had config selection, but the selection was never passed to the authentication script.** + +### Detailed Fix Implementation + +**1. Authentication Script Enhancement** +```javascript +// Modified recipes/get-access-token.js +async function getBearerToken(configName) { + // NEW: Allow configName via environment variable for portal integration + const envConfigName = process.env.CONFIG_NAME; + if (!configName && envConfigName) { + configName = envConfigName; + console.log('Using config name from environment:', configName); + } + // ... rest of function +} +``` + +**2. Frontend Integration** +```javascript +// Modified components/CodeViewer.tsx +// For authentication script, always add CONFIG_NAME to debug +if (fileName === 'get-access-token.js') { + console.log('DEBUG AUTH SCRIPT - selectedCredentialSet:', selectedCredentialSet); + allEnvVariables['CONFIG_NAME'] = selectedCredentialSet || ''; + console.log('Added CONFIG_NAME to env variables:', allEnvVariables['CONFIG_NAME']); +} +``` + +**3. Environment Variable Chain** +- UI stores `selectedCredentialSet` when user selects configuration +- `CodeViewer.executeScript()` passes it as `CONFIG_NAME` environment variable +- `/api/execute` route includes `CONFIG_NAME` in environment variables +- `get-access-token.js` reads `process.env.CONFIG_NAME` and uses selected config + +### Verification Logs +**Working Fix Evidence:** +``` +DEBUG AUTH SCRIPT - selectedCredentialSet: PhilB - PROD +Added CONFIG_NAME to env variables: PhilB - PROD +Using config name from environment: PhilB - PROD +Successfully decrypted config for: PhilB - PROD +ClientId starts with: 77d4c471 // ✅ CORRECT CONFIG +``` + +**Before Fix (Broken):** +``` +Requested config name: undefined +No config name provided, using: QS Fundamentals +ClientId starts with: 8f92dcde // ❌ WRONG CONFIG (default) +``` + +### User Workflow (Fixed) +1. Click "End Session" to clear all tokens +2. Click "Authentication Required" to open modal +3. **Select desired configuration** from "Quick Start - Load Saved Config" dropdown +4. Click "🔐 Authenticate Now" +5. System now correctly authenticates with the **selected** configuration +6. All subsequent API calls use the correct Sigma environment + +### Development Environment Note +**CRITICAL**: This bug was only visible in **development mode** (`npm run dev`). Using `npm start` (production mode) showed cached/pre-built code that didn't reflect changes. Always use development server when debugging authentication issues. + +### Files Modified for This Fix +- `recipes/get-access-token.js` - Accept CONFIG_NAME environment variable +- `components/CodeViewer.tsx` - Pass selectedCredentialSet as CONFIG_NAME + +### Prevention Strategy +- Authentication script now explicitly logs which configuration is being used +- Environment variable mechanism ensures user selection reaches the authentication script +- Development/production mode distinction is clearly documented for future debugging + +This fix completes the authentication configuration switching system, ensuring users can seamlessly switch between different Sigma environments without any race conditions or default configuration fallbacks. \ No newline at end of file diff --git a/recipe-portal/README.md b/recipe-portal/README.md index ce05f86e..8f7f32d7 100644 --- a/recipe-portal/README.md +++ b/recipe-portal/README.md @@ -126,4 +126,4 @@ recipe-portal/ └── get-access-token.js # Authentication helper ``` -For setup instructions and API credential creation, visit the QuickStart: [Sigma REST API Recipes](https://quickstarts.sigmacomputing.com/guide/developers_api_code_samples/index.html?index=..%2F..index#0) \ No newline at end of file +For setup instructions and API credential creation, visit the QuickStart: [Sigma REST API Recipes](https://quickstarts.sigmacomputing.com/guide/developers_quickstarts_api_tookit/index.html?index=..%2F..index#0) \ No newline at end of file diff --git a/recipe-portal/components/AuthRecipeCard.tsx b/recipe-portal/components/AuthRecipeCard.tsx index f4300095..f67fbc14 100644 --- a/recipe-portal/components/AuthRecipeCard.tsx +++ b/recipe-portal/components/AuthRecipeCard.tsx @@ -54,7 +54,7 @@ export function AuthRecipeCard({ recipe, useEnvFile = false, onTokenObtained }: Start Here