Browse Source

feat: Implement real data integration for AI Config UI #25

- Replace mock data with real store data from API
- Add URL query parameter support for shop selection (?shop=<shop_id>)
- Load and display actual store information (name, platform, status, sync stats)
- Implement AI config persistence in store's alt_data field
- Add PUT endpoint /api/stores/:id/ai-config for saving AI configuration
- Add loading states and empty state handling
- Update knowledge base cards to show real sync statistics
- Deploy updated API Edge Function to Supabase

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Claude 5 months ago
parent
commit
caa89f327c
2 changed files with 340 additions and 80 deletions
  1. 284 80
      shopcall.ai-main/src/components/AIConfigContent.tsx
  2. 56 0
      supabase/functions/api/index.ts

+ 284 - 80
shopcall.ai-main/src/components/AIConfigContent.tsx

@@ -7,38 +7,212 @@ import { Textarea } from "@/components/ui/textarea";
 import { Switch } from "@/components/ui/switch";
 import { Switch } from "@/components/ui/switch";
 import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
 import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
 import { Badge } from "@/components/ui/badge";
 import { Badge } from "@/components/ui/badge";
-import { Mic, MessageSquare, Brain, Zap, Store, ChevronDown } from "lucide-react";
-import { useState } from "react";
-
-const webshops = [
-  {
-    id: 1,
-    name: "Fashion Forward",
-    platform: "Shopify",
-    country: "United States",
-    phoneNumber: "+1 (555) 123-4567",
-    status: "Active"
-  },
-  {
-    id: 2,
-    name: "Tech Gadgets Pro",
-    platform: "WooCommerce",
-    country: "United States", 
-    phoneNumber: "+1 (555) 987-6543",
-    status: "Active"
-  },
-  {
-    id: 3,
-    name: "Home & Garden UK",
-    platform: "Shopify",
-    country: "United Kingdom",
-    phoneNumber: "+44 20 7946 0958",
-    status: "Active"
-  }
-];
+import { Mic, MessageSquare, Brain, Zap, Store, ChevronDown, Loader2 } from "lucide-react";
+import { useState, useEffect } from "react";
+import { API_URL } from "@/lib/config";
+import { useToast } from "@/hooks/use-toast";
+
+interface StoreData {
+  id: string;
+  store_name: string | null;
+  platform_name: string;
+  store_url: string | null;
+  phone_number: string | null;
+  is_active: boolean | null;
+  alt_data?: {
+    [key: string]: any;
+  };
+}
+
+interface AIConfig {
+  voice_type: string;
+  speaking_speed: string;
+  accent_language: string;
+  greeting_message: string;
+  business_hours_mode: boolean;
+  local_currency_support: boolean;
+  escalation_policy: string;
+}
 
 
 export function AIConfigContent() {
 export function AIConfigContent() {
-  const [selectedWebshop, setSelectedWebshop] = useState(webshops[0]);
+  const { toast } = useToast();
+  const [stores, setStores] = useState<StoreData[]>([]);
+  const [selectedStore, setSelectedStore] = useState<StoreData | null>(null);
+  const [loading, setLoading] = useState(true);
+  const [saving, setSaving] = useState(false);
+  const [aiConfig, setAiConfig] = useState<AIConfig>({
+    voice_type: "sarah",
+    speaking_speed: "normal",
+    accent_language: "us-english",
+    greeting_message: "",
+    business_hours_mode: true,
+    local_currency_support: true,
+    escalation_policy: "medium"
+  });
+
+  // Get shop parameter from URL
+  useEffect(() => {
+    const params = new URLSearchParams(window.location.search);
+    const shopId = params.get('shop');
+
+    const fetchStores = async () => {
+      try {
+        const sessionData = localStorage.getItem('session_data');
+        if (!sessionData) {
+          throw new Error('No session data found');
+        }
+
+        const session = JSON.parse(sessionData);
+        const response = await fetch(`${API_URL}/api/stores`, {
+          headers: {
+            'Authorization': `Bearer ${session.session.access_token}`,
+            'Content-Type': 'application/json'
+          }
+        });
+
+        if (!response.ok) {
+          throw new Error('Failed to fetch stores');
+        }
+
+        const data = await response.json();
+        if (data.success) {
+          const storesList = data.stores || [];
+          setStores(storesList);
+
+          // Select the store from URL parameter or first store
+          if (shopId) {
+            const store = storesList.find((s: StoreData) => s.id === shopId);
+            if (store) {
+              setSelectedStore(store);
+              loadAIConfig(store);
+            } else if (storesList.length > 0) {
+              setSelectedStore(storesList[0]);
+              loadAIConfig(storesList[0]);
+            }
+          } else if (storesList.length > 0) {
+            setSelectedStore(storesList[0]);
+            loadAIConfig(storesList[0]);
+          }
+        }
+      } catch (error) {
+        console.error('Error fetching stores:', error);
+        toast({
+          title: "Error",
+          description: "Failed to load stores. Please try again.",
+          variant: "destructive"
+        });
+      } finally {
+        setLoading(false);
+      }
+    };
+
+    fetchStores();
+  }, [toast]);
+
+  const loadAIConfig = (store: StoreData) => {
+    // Load AI config from store's alt_data or use defaults
+    const config = store.alt_data?.ai_config || {};
+
+    setAiConfig({
+      voice_type: config.voice_type || "sarah",
+      speaking_speed: config.speaking_speed || "normal",
+      accent_language: config.accent_language || "us-english",
+      greeting_message: config.greeting_message || `Hello! Thank you for calling ${store.store_name || 'our store'}. I'm your AI assistant, and I'm here to help you with any questions about your order or our products. How can I assist you today?`,
+      business_hours_mode: config.business_hours_mode !== undefined ? config.business_hours_mode : true,
+      local_currency_support: config.local_currency_support !== undefined ? config.local_currency_support : true,
+      escalation_policy: config.escalation_policy || "medium"
+    });
+  };
+
+  const handleStoreChange = (storeId: string) => {
+    const store = stores.find(s => s.id === storeId);
+    if (store) {
+      setSelectedStore(store);
+      loadAIConfig(store);
+      // Update URL
+      window.history.replaceState({}, '', `/ai-config?shop=${storeId}`);
+    }
+  };
+
+  const handleSaveConfig = async () => {
+    if (!selectedStore) return;
+
+    setSaving(true);
+    try {
+      const sessionData = localStorage.getItem('session_data');
+      if (!sessionData) {
+        throw new Error('No session data found');
+      }
+
+      const session = JSON.parse(sessionData);
+
+      // Update store's alt_data with AI config
+      const response = await fetch(`${API_URL}/api/stores/${selectedStore.id}/ai-config`, {
+        method: 'PUT',
+        headers: {
+          'Authorization': `Bearer ${session.session.access_token}`,
+          'Content-Type': 'application/json'
+        },
+        body: JSON.stringify({ ai_config: aiConfig })
+      });
+
+      if (!response.ok) {
+        throw new Error('Failed to save configuration');
+      }
+
+      toast({
+        title: "Success",
+        description: "AI configuration saved successfully.",
+      });
+    } catch (error) {
+      console.error('Error saving config:', error);
+      toast({
+        title: "Error",
+        description: "Failed to save configuration. Please try again.",
+        variant: "destructive"
+      });
+    } finally {
+      setSaving(false);
+    }
+  };
+
+  if (loading) {
+    return (
+      <div className="flex-1 flex items-center justify-center min-h-screen bg-slate-900">
+        <Loader2 className="w-8 h-8 text-cyan-500 animate-spin" />
+      </div>
+    );
+  }
+
+  if (stores.length === 0) {
+    return (
+      <div className="flex-1 space-y-6 p-8 bg-slate-900">
+        <div className="flex items-center justify-center min-h-[60vh]">
+          <div className="text-center">
+            <Store className="w-16 h-16 text-slate-600 mx-auto mb-4" />
+            <h3 className="text-lg font-semibold text-white mb-2">No Stores Connected</h3>
+            <p className="text-slate-400 mb-6">
+              Please connect a store first before configuring AI settings.
+            </p>
+            <Button
+              className="bg-cyan-500 hover:bg-cyan-600 text-white"
+              onClick={() => window.location.href = '/webshops'}
+            >
+              Go to Webshops
+            </Button>
+          </div>
+        </div>
+      </div>
+    );
+  }
+
+  if (!selectedStore) {
+    return (
+      <div className="flex-1 flex items-center justify-center min-h-screen bg-slate-900">
+        <p className="text-slate-400">No store selected</p>
+      </div>
+    );
+  }
 
 
   return (
   return (
     <div className="flex-1 space-y-6 p-8 bg-slate-900">
     <div className="flex-1 space-y-6 p-8 bg-slate-900">
@@ -48,11 +222,19 @@ export function AIConfigContent() {
           <p className="text-slate-400">Configure AI behavior and responses per webshop</p>
           <p className="text-slate-400">Configure AI behavior and responses per webshop</p>
         </div>
         </div>
         <div className="flex gap-3">
         <div className="flex gap-3">
-          <Button variant="outline" className="text-cyan-500 border-cyan-500 hover:bg-cyan-500/10">
-            Copy from Another Shop
-          </Button>
-          <Button className="bg-cyan-500 hover:bg-cyan-600 text-white">
-            Save Configuration
+          <Button
+            className="bg-cyan-500 hover:bg-cyan-600 text-white"
+            onClick={handleSaveConfig}
+            disabled={saving}
+          >
+            {saving ? (
+              <>
+                <Loader2 className="w-4 h-4 mr-2 animate-spin" />
+                Saving...
+              </>
+            ) : (
+              "Save Configuration"
+            )}
           </Button>
           </Button>
         </div>
         </div>
       </div>
       </div>
@@ -67,36 +249,40 @@ export function AIConfigContent() {
           <p className="text-slate-400">Choose which webshop to configure</p>
           <p className="text-slate-400">Choose which webshop to configure</p>
         </CardHeader>
         </CardHeader>
         <CardContent>
         <CardContent>
-          <Select value={selectedWebshop.id.toString()} onValueChange={(value) => {
-            const shop = webshops.find(s => s.id === parseInt(value));
-            if (shop) setSelectedWebshop(shop);
-          }}>
+          <Select value={selectedStore.id} onValueChange={handleStoreChange}>
             <SelectTrigger className="bg-slate-700 border-slate-600 text-white">
             <SelectTrigger className="bg-slate-700 border-slate-600 text-white">
               <SelectValue />
               <SelectValue />
             </SelectTrigger>
             </SelectTrigger>
             <SelectContent className="bg-slate-700 border-slate-600">
             <SelectContent className="bg-slate-700 border-slate-600">
-              {webshops.map((shop) => (
-                <SelectItem key={shop.id} value={shop.id.toString()}>
+              {stores.map((store) => (
+                <SelectItem key={store.id} value={store.id}>
                   <div className="flex items-center gap-3">
                   <div className="flex items-center gap-3">
                     <div>
                     <div>
-                      <div className="text-white font-medium">{shop.name}</div>
-                      <div className="text-slate-400 text-sm">{shop.platform} • {shop.country}</div>
+                      <div className="text-white font-medium">{store.store_name || 'Unnamed Store'}</div>
+                      <div className="text-slate-400 text-sm capitalize">{store.platform_name}</div>
                     </div>
                     </div>
                   </div>
                   </div>
                 </SelectItem>
                 </SelectItem>
               ))}
               ))}
             </SelectContent>
             </SelectContent>
           </Select>
           </Select>
-          
+
           {/* Current Shop Info */}
           {/* Current Shop Info */}
           <div className="mt-4 p-4 bg-slate-700/50 rounded-lg">
           <div className="mt-4 p-4 bg-slate-700/50 rounded-lg">
             <div className="flex items-center justify-between">
             <div className="flex items-center justify-between">
               <div>
               <div>
-                <h4 className="text-white font-medium">{selectedWebshop.name}</h4>
-                <p className="text-slate-400 text-sm">{selectedWebshop.platform} • {selectedWebshop.country}</p>
-                <p className="text-slate-300 text-sm font-mono">{selectedWebshop.phoneNumber}</p>
+                <h4 className="text-white font-medium">{selectedStore.store_name || 'Unnamed Store'}</h4>
+                <p className="text-slate-400 text-sm capitalize">{selectedStore.platform_name}</p>
+                {selectedStore.store_url && (
+                  <p className="text-slate-500 text-xs mt-1">{selectedStore.store_url}</p>
+                )}
+                {selectedStore.phone_number && (
+                  <p className="text-slate-300 text-sm font-mono mt-1">{selectedStore.phone_number}</p>
+                )}
               </div>
               </div>
-              <Badge className="bg-green-500 text-white">{selectedWebshop.status}</Badge>
+              <Badge className={`${selectedStore.is_active ? "bg-green-500" : "bg-red-500"} text-white`}>
+                {selectedStore.is_active ? "Active" : "Inactive"}
+              </Badge>
             </div>
             </div>
           </div>
           </div>
         </CardContent>
         </CardContent>
@@ -109,13 +295,13 @@ export function AIConfigContent() {
               <Mic className="w-6 h-6 text-cyan-500" />
               <Mic className="w-6 h-6 text-cyan-500" />
               <CardTitle className="text-white">Voice & Speech Settings</CardTitle>
               <CardTitle className="text-white">Voice & Speech Settings</CardTitle>
             </div>
             </div>
-            <p className="text-slate-400">Configure voice characteristics for {selectedWebshop.name}</p>
+            <p className="text-slate-400">Configure voice characteristics for {selectedStore.store_name || 'your store'}</p>
           </CardHeader>
           </CardHeader>
           <CardContent className="space-y-6">
           <CardContent className="space-y-6">
             <div className="grid gap-6 md:grid-cols-2">
             <div className="grid gap-6 md:grid-cols-2">
               <div className="space-y-2">
               <div className="space-y-2">
                 <Label className="text-slate-300">Voice Type</Label>
                 <Label className="text-slate-300">Voice Type</Label>
-                <Select defaultValue="sarah">
+                <Select value={aiConfig.voice_type} onValueChange={(value) => setAiConfig({ ...aiConfig, voice_type: value })}>
                   <SelectTrigger className="bg-slate-700 border-slate-600 text-white">
                   <SelectTrigger className="bg-slate-700 border-slate-600 text-white">
                     <SelectValue />
                     <SelectValue />
                   </SelectTrigger>
                   </SelectTrigger>
@@ -128,7 +314,7 @@ export function AIConfigContent() {
               </div>
               </div>
               <div className="space-y-2">
               <div className="space-y-2">
                 <Label className="text-slate-300">Speaking Speed</Label>
                 <Label className="text-slate-300">Speaking Speed</Label>
-                <Select defaultValue="normal">
+                <Select value={aiConfig.speaking_speed} onValueChange={(value) => setAiConfig({ ...aiConfig, speaking_speed: value })}>
                   <SelectTrigger className="bg-slate-700 border-slate-600 text-white">
                   <SelectTrigger className="bg-slate-700 border-slate-600 text-white">
                     <SelectValue />
                     <SelectValue />
                   </SelectTrigger>
                   </SelectTrigger>
@@ -142,7 +328,7 @@ export function AIConfigContent() {
             </div>
             </div>
             <div className="space-y-2">
             <div className="space-y-2">
               <Label className="text-slate-300">Accent & Language</Label>
               <Label className="text-slate-300">Accent & Language</Label>
-              <Select defaultValue={selectedWebshop.country === "United Kingdom" ? "uk-english" : "us-english"}>
+              <Select value={aiConfig.accent_language} onValueChange={(value) => setAiConfig({ ...aiConfig, accent_language: value })}>
                 <SelectTrigger className="bg-slate-700 border-slate-600 text-white">
                 <SelectTrigger className="bg-slate-700 border-slate-600 text-white">
                   <SelectValue />
                   <SelectValue />
                 </SelectTrigger>
                 </SelectTrigger>
@@ -162,37 +348,46 @@ export function AIConfigContent() {
               <MessageSquare className="w-6 h-6 text-cyan-500" />
               <MessageSquare className="w-6 h-6 text-cyan-500" />
               <CardTitle className="text-white">Conversation Behavior</CardTitle>
               <CardTitle className="text-white">Conversation Behavior</CardTitle>
             </div>
             </div>
-            <p className="text-slate-400">Define how the AI interacts with {selectedWebshop.name} customers</p>
+            <p className="text-slate-400">Define how the AI interacts with {selectedStore.store_name || 'your store'} customers</p>
           </CardHeader>
           </CardHeader>
           <CardContent className="space-y-6">
           <CardContent className="space-y-6">
             <div className="space-y-2">
             <div className="space-y-2">
               <Label className="text-slate-300">Greeting Message</Label>
               <Label className="text-slate-300">Greeting Message</Label>
-              <Textarea 
+              <Textarea
                 className="bg-slate-700 border-slate-600 text-white min-h-[100px]"
                 className="bg-slate-700 border-slate-600 text-white min-h-[100px]"
-                defaultValue={`Hello! Thank you for calling ${selectedWebshop.name}. I'm your AI assistant, and I'm here to help you with any questions about your order or our products. How can I assist you today?`}
+                value={aiConfig.greeting_message}
+                onChange={(e) => setAiConfig({ ...aiConfig, greeting_message: e.target.value })}
               />
               />
             </div>
             </div>
-            
+
             <div className="grid gap-6 md:grid-cols-2">
             <div className="grid gap-6 md:grid-cols-2">
               <div className="flex items-center justify-between">
               <div className="flex items-center justify-between">
                 <div className="space-y-1">
                 <div className="space-y-1">
                   <Label className="text-slate-300">Business Hours Mode</Label>
                   <Label className="text-slate-300">Business Hours Mode</Label>
                   <p className="text-sm text-slate-400">Adjust behavior based on store hours</p>
                   <p className="text-sm text-slate-400">Adjust behavior based on store hours</p>
                 </div>
                 </div>
-                <Switch defaultChecked className="data-[state=checked]:bg-cyan-500" />
+                <Switch
+                  checked={aiConfig.business_hours_mode}
+                  onCheckedChange={(checked) => setAiConfig({ ...aiConfig, business_hours_mode: checked })}
+                  className="data-[state=checked]:bg-cyan-500"
+                />
               </div>
               </div>
               <div className="flex items-center justify-between">
               <div className="flex items-center justify-between">
                 <div className="space-y-1">
                 <div className="space-y-1">
                   <Label className="text-slate-300">Local Currency Support</Label>
                   <Label className="text-slate-300">Local Currency Support</Label>
                   <p className="text-sm text-slate-400">Auto-detect customer location</p>
                   <p className="text-sm text-slate-400">Auto-detect customer location</p>
                 </div>
                 </div>
-                <Switch defaultChecked className="data-[state=checked]:bg-cyan-500" />
+                <Switch
+                  checked={aiConfig.local_currency_support}
+                  onCheckedChange={(checked) => setAiConfig({ ...aiConfig, local_currency_support: checked })}
+                  className="data-[state=checked]:bg-cyan-500"
+                />
               </div>
               </div>
             </div>
             </div>
 
 
             <div className="space-y-2">
             <div className="space-y-2">
               <Label className="text-slate-300">Escalation Policy</Label>
               <Label className="text-slate-300">Escalation Policy</Label>
-              <Select defaultValue="medium">
+              <Select value={aiConfig.escalation_policy} onValueChange={(value) => setAiConfig({ ...aiConfig, escalation_policy: value })}>
                 <SelectTrigger className="bg-slate-700 border-slate-600 text-white">
                 <SelectTrigger className="bg-slate-700 border-slate-600 text-white">
                   <SelectValue />
                   <SelectValue />
                 </SelectTrigger>
                 </SelectTrigger>
@@ -212,45 +407,54 @@ export function AIConfigContent() {
               <Brain className="w-6 h-6 text-cyan-500" />
               <Brain className="w-6 h-6 text-cyan-500" />
               <CardTitle className="text-white">Knowledge Base</CardTitle>
               <CardTitle className="text-white">Knowledge Base</CardTitle>
             </div>
             </div>
-            <p className="text-slate-400">Training data specific to {selectedWebshop.name}</p>
+            <p className="text-slate-400">Training data specific to {selectedStore.store_name || 'your store'}</p>
           </CardHeader>
           </CardHeader>
           <CardContent className="space-y-6">
           <CardContent className="space-y-6">
             <div className="grid gap-4 md:grid-cols-3">
             <div className="grid gap-4 md:grid-cols-3">
               <div className="p-4 bg-slate-700/50 rounded-lg">
               <div className="p-4 bg-slate-700/50 rounded-lg">
                 <div className="flex items-center justify-between mb-2">
                 <div className="flex items-center justify-between mb-2">
                   <h4 className="text-white font-medium">Product Catalog</h4>
                   <h4 className="text-white font-medium">Product Catalog</h4>
-                  <Badge className="bg-green-500 text-white">Synced</Badge>
+                  <Badge className={`${selectedStore.sync_status === 'completed' ? 'bg-green-500' : 'bg-slate-500'} text-white`}>
+                    {selectedStore.sync_status === 'completed' ? 'Synced' : 'Not Synced'}
+                  </Badge>
                 </div>
                 </div>
-                <p className="text-slate-400 text-sm">1,247 products</p>
-                <p className="text-slate-500 text-xs">Auto-sync from {selectedWebshop.platform}</p>
+                <p className="text-slate-400 text-sm">
+                  {selectedStore.alt_data?.last_sync_stats?.products?.synced || 0} products
+                </p>
+                <p className="text-slate-500 text-xs capitalize">Auto-sync from {selectedStore.platform_name}</p>
               </div>
               </div>
               <div className="p-4 bg-slate-700/50 rounded-lg">
               <div className="p-4 bg-slate-700/50 rounded-lg">
                 <div className="flex items-center justify-between mb-2">
                 <div className="flex items-center justify-between mb-2">
-                  <h4 className="text-white font-medium">Store Policies</h4>
-                  <Badge className="bg-green-500 text-white">Updated</Badge>
+                  <h4 className="text-white font-medium">Orders</h4>
+                  <Badge className={`${selectedStore.sync_status === 'completed' ? 'bg-green-500' : 'bg-slate-500'} text-white`}>
+                    {selectedStore.sync_status === 'completed' ? 'Synced' : 'Not Synced'}
+                  </Badge>
                 </div>
                 </div>
-                <p className="text-slate-400 text-sm">Return, shipping, etc.</p>
-                <p className="text-slate-500 text-xs">Country-specific policies</p>
+                <p className="text-slate-400 text-sm">
+                  {selectedStore.alt_data?.last_sync_stats?.orders?.synced || 0} orders
+                </p>
+                <p className="text-slate-500 text-xs">Order history</p>
               </div>
               </div>
               <div className="p-4 bg-slate-700/50 rounded-lg">
               <div className="p-4 bg-slate-700/50 rounded-lg">
                 <div className="flex items-center justify-between mb-2">
                 <div className="flex items-center justify-between mb-2">
-                  <h4 className="text-white font-medium">FAQ Database</h4>
-                  <Badge className="bg-yellow-500 text-white">Needs Review</Badge>
+                  <h4 className="text-white font-medium">Customers</h4>
+                  <Badge className={`${selectedStore.sync_status === 'completed' ? 'bg-green-500' : 'bg-slate-500'} text-white`}>
+                    {selectedStore.sync_status === 'completed' ? 'Synced' : 'Not Synced'}
+                  </Badge>
                 </div>
                 </div>
-                <p className="text-slate-400 text-sm">89 Q&As</p>
-                <p className="text-slate-500 text-xs">Regional customization needed</p>
+                <p className="text-slate-400 text-sm">
+                  {selectedStore.alt_data?.last_sync_stats?.customers?.synced || 0} customers
+                </p>
+                <p className="text-slate-500 text-xs">Customer database</p>
               </div>
               </div>
             </div>
             </div>
-            
+
             <div className="flex gap-3">
             <div className="flex gap-3">
-              <Button className="bg-cyan-500 hover:bg-cyan-600 text-white">
-                Sync Store Data
-              </Button>
-              <Button variant="outline" className="text-cyan-500 border-cyan-500 hover:bg-cyan-500/10">
-                Upload Custom Knowledge
-              </Button>
-              <Button variant="outline" className="text-cyan-500 border-cyan-500 hover:bg-cyan-500/10">
-                Test Configuration
+              <Button
+                className="bg-cyan-500 hover:bg-cyan-600 text-white"
+                onClick={() => window.location.href = '/webshops'}
+              >
+                Manage Store Data
               </Button>
               </Button>
             </div>
             </div>
           </CardContent>
           </CardContent>

+ 56 - 0
supabase/functions/api/index.ts

@@ -261,6 +261,62 @@ serve(async (req) => {
       )
       )
     }
     }
 
 
+    // PUT /api/stores/:id/ai-config - Update AI configuration for a store
+    if (path.match(/^stores\/[^\/]+\/ai-config$/) && req.method === 'PUT') {
+      const storeId = path.split('/')[1]
+      const { ai_config } = await req.json()
+
+      if (!ai_config) {
+        return new Response(
+          JSON.stringify({ error: 'ai_config is required' }),
+          { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
+        )
+      }
+
+      // Verify store ownership
+      const { data: store, error: storeError } = await supabase
+        .from('stores')
+        .select('id, alt_data')
+        .eq('id', storeId)
+        .eq('user_id', user.id)
+        .single()
+
+      if (storeError || !store) {
+        return new Response(
+          JSON.stringify({ error: 'Store not found or access denied' }),
+          { status: 404, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
+        )
+      }
+
+      // Update store's alt_data with AI config
+      const updatedAltData = {
+        ...(store.alt_data || {}),
+        ai_config
+      }
+
+      const { error: updateError } = await supabase
+        .from('stores')
+        .update({ alt_data: updatedAltData })
+        .eq('id', storeId)
+        .eq('user_id', user.id)
+
+      if (updateError) {
+        console.error('Error updating AI config:', updateError)
+        return new Response(
+          JSON.stringify({ error: 'Failed to update AI configuration' }),
+          { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
+        )
+      }
+
+      return new Response(
+        JSON.stringify({
+          success: true,
+          message: 'AI configuration updated successfully'
+        }),
+        { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
+      )
+    }
+
     // DELETE /api/stores/{id} - Delete a store
     // DELETE /api/stores/{id} - Delete a store
     if (path.startsWith('stores/') && req.method === 'DELETE') {
     if (path.startsWith('stores/') && req.method === 'DELETE') {
       const storeId = path.replace('stores/', '')
       const storeId = path.replace('stores/', '')