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
48 changes: 48 additions & 0 deletions recipe-portal/.claude/claude.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# 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.
3 changes: 3 additions & 0 deletions recipe-portal/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
35 changes: 35 additions & 0 deletions recipe-portal/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Dependencies
node_modules/
/.pnp
.pnp.js

# Testing
/coverage

# Next.js
/.next/
/out/

# Production
/build

# Misc
.DS_Store
*.tsbuildinfo
next-env.d.ts

# Debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Local env files
.env*.local

# IDE
.vscode/
.idea/

# OS
.DS_Store
Thumbs.db
60 changes: 60 additions & 0 deletions recipe-portal/app/api/code/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { NextResponse } from 'next/server';
import fs from 'fs';
import path from 'path';

export async function GET(request: Request) {
try {
const { searchParams } = new URL(request.url);
const filePath = searchParams.get('path');

if (!filePath) {
return NextResponse.json(
{ error: 'File path is required' },
{ status: 400 }
);
}

// Security check: ensure the file is within the sigma-api-recipes directory
const recipesPath = path.join(process.cwd(), '..', 'sigma-api-recipes');
const resolvedPath = path.resolve(filePath);
const resolvedRecipesPath = path.resolve(recipesPath);

if (!resolvedPath.startsWith(resolvedRecipesPath)) {
return NextResponse.json(
{ error: 'Access denied: File must be within sigma-api-recipes directory' },
{ status: 403 }
);
}

// Check if file exists and is a JavaScript file
if (!fs.existsSync(resolvedPath)) {
return NextResponse.json(
{ error: 'File not found' },
{ status: 404 }
);
}

if (!resolvedPath.endsWith('.js')) {
return NextResponse.json(
{ error: 'Only JavaScript files are allowed' },
{ status: 400 }
);
}

// Read the file content
const content = fs.readFileSync(resolvedPath, 'utf-8');

return NextResponse.json({
content,
filePath: resolvedPath,
timestamp: new Date().toISOString()
});

} catch (error) {
console.error('Error reading file:', error);
return NextResponse.json(
{ error: 'Failed to read file' },
{ status: 500 }
);
}
}
55 changes: 55 additions & 0 deletions recipe-portal/app/api/env/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { NextResponse } from 'next/server';
import fs from 'fs';
import path from 'path';

export async function GET() {
try {
const envFilePath = path.join(process.cwd(), '..', 'sigma-api-recipes', '.env');

if (!fs.existsSync(envFilePath)) {
return NextResponse.json({
values: {},
exists: false,
message: 'Environment file not found'
});
}

const envContent = fs.readFileSync(envFilePath, 'utf-8');
const envValues: Record<string, string> = {};

// Parse the .env file
const lines = envContent.split('\n');
for (const line of lines) {
const trimmed = line.trim();
// Skip comments and empty lines
if (trimmed && !trimmed.startsWith('#')) {
const match = trimmed.match(/^([^=]+)=(.*)$/);
if (match) {
const key = match[1].trim();
const value = match[2].trim();
// Only include non-empty values
if (value && value !== '') {
envValues[key] = value;
}
}
}
}

return NextResponse.json({
values: envValues,
exists: true,
timestamp: new Date().toISOString()
});

} catch (error) {
console.error('Error reading .env file:', error);
return NextResponse.json(
{
error: 'Failed to read environment file',
values: {},
exists: false
},
{ status: 500 }
);
}
}
Loading