Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 218 additions & 0 deletions recipe-portal/.claude/claude.md
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 1 addition & 1 deletion recipe-portal/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
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)
2 changes: 1 addition & 1 deletion recipe-portal/components/AuthRecipeCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export function AuthRecipeCard({ recipe, useEnvFile = false, onTokenObtained }:
Start Here
</span>
<a
href="https://quickstarts.sigmacomputing.com/guide/developers_api_code_samples/index.html#0"
href="https://quickstarts.sigmacomputing.com/guide/developers_quickstarts_api_tookit/index.html?index=..%2F..index#0"
target="_blank"
rel="noopener noreferrer"
className="text-blue-600 hover:text-blue-800 underline"
Expand Down
4 changes: 2 additions & 2 deletions recipe-portal/components/CodeViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ export function CodeViewer({ isOpen, onClose, filePath, fileName, envVariables =
Start Here
</span>
<a
href="https://quickstarts.sigmacomputing.com/guide/developers_api_code_samples/index.html#0"
href="https://quickstarts.sigmacomputing.com/guide/developers_quickstarts_api_tookit/index.html?index=..%2F..index#0"
target="_blank"
rel="noopener noreferrer"
className="text-blue-600 hover:text-blue-800 underline"
Expand Down Expand Up @@ -1088,7 +1088,7 @@ export function CodeViewer({ isOpen, onClose, filePath, fileName, envVariables =
</p>
</div>
<a
href="https://quickstarts.sigmacomputing.com/guide/developers_api_code_samples/index.html#0"
href="https://quickstarts.sigmacomputing.com/guide/developers_quickstarts_api_tookit/index.html?index=..%2F..index#0"
target="_blank"
rel="noopener noreferrer"
className="px-3 py-1.5 border border-blue-300 text-blue-700 rounded-lg text-xs font-medium hover:bg-blue-50 transition-colors flex items-center"
Expand Down