Просмотр исходного кода

feat: add PATCH /api/shops/:id/qdrant endpoint to enable/disable Qdrant

Implemented the missing endpoint that the frontend calls to enable or
disable Qdrant vector search for a shop.

Changes:
- Added PATCH /api/shops/:id/qdrant endpoint to ShopsEndpoint
- Implemented updateQdrantStatus() handler method
- Added setQdrantEnabled() method to ShopDatabase class
- Added qdrant_enabled field to shop detail response
- Supports both internal ID and custom ID for shop lookup

This resolves the 404 error when trying to toggle Qdrant from the UI.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Fszontagh 8 месяцев назад
Родитель
Сommit
3a6fa7e969
2 измененных файлов с 102 добавлено и 0 удалено
  1. 84 0
      src/api/components/ShopsEndpoint.ts
  2. 18 0
      src/database/Database.ts

+ 84 - 0
src/api/components/ShopsEndpoint.ts

@@ -272,6 +272,55 @@ export class ShopsEndpoint extends BaseEndpointComponent {
           requiresAuth: true
         }
       ),
+      this.createEndpoint(
+        'PATCH',
+        '/api/shops/:id/qdrant',
+        this.updateQdrantStatus.bind(this),
+        {
+          summary: 'Enable or disable Qdrant vector search',
+          description: 'Updates the Qdrant integration status for a shop',
+          tags: ['Shops'],
+          parameters: [
+            {
+              name: 'id',
+              in: 'path',
+              type: 'string',
+              required: true,
+              description: 'Shop ID (internal UUID or custom UUID)'
+            }
+          ],
+          requestBody: {
+            required: true,
+            schema: {
+              type: 'object',
+              properties: {
+                enabled: {
+                  type: 'boolean',
+                  description: 'Whether to enable or disable Qdrant integration'
+                }
+              },
+              required: ['enabled']
+            }
+          },
+          responses: {
+            '200': {
+              description: 'Qdrant status updated',
+              schema: {
+                type: 'object',
+                properties: {
+                  shop_id: { type: 'string' },
+                  qdrant_enabled: { type: 'boolean' },
+                  message: { type: 'string' }
+                }
+              }
+            },
+            '404': {
+              description: 'Shop not found'
+            }
+          },
+          requiresAuth: true
+        }
+      ),
       this.createEndpoint(
         'DELETE',
         '/api/shops/:id',
@@ -391,6 +440,7 @@ export class ShopsEndpoint extends BaseEndpointComponent {
           url: shop.url,
           sitemap_url: shop.sitemap_url,
           webshop_type: shop.webshop_type,
+          qdrant_enabled: shop.qdrant_enabled,
           created_at: shop.created_at,
           updated_at: shop.updated_at
         },
@@ -595,6 +645,40 @@ export class ShopsEndpoint extends BaseEndpointComponent {
     }
   }
 
+  private async updateQdrantStatus(req: Request, res: Response): Promise<void> {
+    try {
+      if (!this.db) {
+        res.status(503).json({ error: 'Database not available' });
+        return;
+      }
+
+      const { id } = req.params;
+      const { enabled } = req.body;
+
+      if (typeof enabled !== 'boolean') {
+        res.status(400).json({ error: 'enabled field must be a boolean' });
+        return;
+      }
+
+      const shop = this.db.getShopByAnyId(id);
+      if (!shop) {
+        res.status(404).json({ error: 'Shop not found' });
+        return;
+      }
+
+      this.db.setQdrantEnabled(shop.id, enabled);
+
+      res.json({
+        shop_id: shop.id,
+        qdrant_enabled: enabled,
+        message: `Qdrant ${enabled ? 'enabled' : 'disabled'} successfully`
+      });
+    } catch (error) {
+      logger.error('Error updating Qdrant status', error);
+      res.status(500).json({ error: 'Internal server error' });
+    }
+  }
+
   private async deleteShop(req: Request, res: Response): Promise<void> {
     try {
       if (!this.db) {

+ 18 - 0
src/database/Database.ts

@@ -494,6 +494,24 @@ export class ShopDatabase {
     return true;
   }
 
+  setQdrantEnabled(identifier: string, enabled: boolean): boolean {
+    const shop = this.getShopByAnyId(identifier);
+    if (!shop) {
+      logger.warn(`Attempted to set Qdrant status for non-existent shop: ${identifier}`);
+      return false;
+    }
+
+    const now = new Date().toISOString();
+    this.db.prepare(`
+      UPDATE shops
+      SET qdrant_enabled = ?, updated_at = ?
+      WHERE id = ?
+    `).run(enabled ? 1 : 0, now, shop.id);
+
+    logger.info(`Set Qdrant ${enabled ? 'enabled' : 'disabled'} for shop ${shop.id}`);
+    return true;
+  }
+
   deleteShop(identifier: string): void {
     // Find the shop first to get the internal ID for logging
     const shop = this.getShopByAnyId(identifier);