← back to Watches

thibaut-room-settings-api-example.js

272 lines

/**
 * Thibaut Room Settings API Example
 *
 * Example Express.js routes showing how to use the thibaut_room_settings table
 * to enhance product displays with room setting images.
 */

const { Pool } = require('pg');
const express = require('express');
const router = express.Router();

const pool = new Pool({
  connectionString: (process.env.DATABASE_URL || 'postgresql://dw_admin@127.0.0.1:5432/dw_unified')
});

/**
 * GET /api/thibaut/room-settings/:sku
 *
 * Get all room setting images that feature a specific product SKU
 *
 * Example: GET /api/thibaut/room-settings/T15806
 *
 * Returns: Array of room setting images showing this product
 */
router.get('/api/thibaut/room-settings/:sku', async (req, res) => {
  try {
    const { sku } = req.params;

    const result = await pool.query(`
      SELECT
        ts.id,
        ts.collection_name,
        ts.collection_url,
        ts.image_url,
        ts.image_filename,
        ts.pattern_names,
        ts.mfr_skus,
        ts.sort_order
      FROM thibaut_room_settings ts
      WHERE $1 = ANY(ts.mfr_skus)
      ORDER BY ts.sort_order
    `, [sku]);

    res.json({
      sku: sku,
      count: result.rows.length,
      roomSettings: result.rows
    });

  } catch (err) {
    console.error('Error fetching room settings:', err);
    res.status(500).json({ error: 'Failed to fetch room settings' });
  }
});

/**
 * GET /api/thibaut/collection/:name/room-settings
 *
 * Get all room settings for a specific collection
 *
 * Example: GET /api/thibaut/collection/Islander/room-settings
 *
 * Returns: Array of room setting images in this collection
 */
router.get('/api/thibaut/collection/:name/room-settings', async (req, res) => {
  try {
    const { name } = req.params;
    const { matched_only } = req.query; // Optional: only return matched images

    let query = `
      SELECT
        ts.id,
        ts.collection_name,
        ts.image_url,
        ts.image_filename,
        ts.mfr_skus,
        array_length(ts.mfr_skus, 1) as sku_count,
        ts.sort_order
      FROM thibaut_room_settings ts
      WHERE ts.collection_name ILIKE $1
    `;

    if (matched_only === 'true') {
      query += ` AND ts.mfr_skus IS NOT NULL AND array_length(ts.mfr_skus, 1) > 0`;
    }

    query += ` ORDER BY ts.sort_order`;

    const result = await pool.query(query, [name]);

    res.json({
      collection: name,
      count: result.rows.length,
      roomSettings: result.rows
    });

  } catch (err) {
    console.error('Error fetching collection room settings:', err);
    res.status(500).json({ error: 'Failed to fetch collection room settings' });
  }
});

/**
 * GET /api/thibaut/product/:sku/with-room-settings
 *
 * Get product details with all associated room setting images
 *
 * Example: GET /api/thibaut/product/T15806/with-room-settings
 *
 * Returns: Product info + room settings showing this product
 */
router.get('/api/thibaut/product/:sku/with-room-settings', async (req, res) => {
  try {
    const { sku } = req.params;

    // Get product details
    const product = await pool.query(`
      SELECT
        tc.mfr_sku,
        tc.pattern_name,
        tc.color_name,
        tc.collection,
        tc.width,
        tc.roll_length,
        tc.pattern_repeat,
        tc.image_url as product_image,
        tc.product_url,
        tc.material,
        tc.product_type
      FROM thibaut_catalog tc
      WHERE tc.mfr_sku = $1
    `, [sku]);

    if (product.rows.length === 0) {
      return res.status(404).json({ error: 'Product not found' });
    }

    // Get room settings
    const roomSettings = await pool.query(`
      SELECT
        ts.id,
        ts.collection_name,
        ts.image_url,
        ts.image_filename,
        ts.sort_order
      FROM thibaut_room_settings ts
      WHERE $1 = ANY(ts.mfr_skus)
      ORDER BY ts.sort_order
    `, [sku]);

    res.json({
      product: product.rows[0],
      roomSettings: roomSettings.rows,
      roomSettingsCount: roomSettings.rows.length
    });

  } catch (err) {
    console.error('Error fetching product with room settings:', err);
    res.status(500).json({ error: 'Failed to fetch product data' });
  }
});

/**
 * GET /api/thibaut/room-settings/stats
 *
 * Get statistics about room settings by collection
 *
 * Example: GET /api/thibaut/room-settings/stats
 *
 * Returns: Summary statistics for all collections
 */
router.get('/api/thibaut/room-settings/stats', async (req, res) => {
  try {
    const result = await pool.query(`
      SELECT
        collection_name,
        COUNT(*) as total_images,
        COUNT(CASE WHEN mfr_skus IS NOT NULL AND array_length(mfr_skus, 1) > 0 THEN 1 END) as matched_images,
        ROUND(100.0 * COUNT(CASE WHEN mfr_skus IS NOT NULL AND array_length(mfr_skus, 1) > 0 THEN 1 END) / COUNT(*), 1) as match_percentage
      FROM thibaut_room_settings
      GROUP BY collection_name
      ORDER BY total_images DESC
    `);

    // Get overall stats
    const overall = await pool.query(`
      SELECT
        COUNT(*) as total_images,
        COUNT(CASE WHEN mfr_skus IS NOT NULL AND array_length(mfr_skus, 1) > 0 THEN 1 END) as matched_images,
        ROUND(100.0 * COUNT(CASE WHEN mfr_skus IS NOT NULL AND array_length(mfr_skus, 1) > 0 THEN 1 END) / COUNT(*), 2) as match_percentage
      FROM thibaut_room_settings
    `);

    res.json({
      overall: overall.rows[0],
      byCollection: result.rows
    });

  } catch (err) {
    console.error('Error fetching room settings stats:', err);
    res.status(500).json({ error: 'Failed to fetch statistics' });
  }
});

/**
 * GET /api/thibaut/room-settings/search
 *
 * Search room settings by pattern name
 *
 * Example: GET /api/thibaut/room-settings/search?q=Grasscloth
 *
 * Returns: Room settings matching the search query
 */
router.get('/api/thibaut/room-settings/search', async (req, res) => {
  try {
    const { q } = req.query;

    if (!q || q.length < 3) {
      return res.status(400).json({ error: 'Query must be at least 3 characters' });
    }

    const result = await pool.query(`
      SELECT
        ts.id,
        ts.collection_name,
        ts.image_url,
        ts.image_filename,
        ts.pattern_names,
        ts.mfr_skus,
        array_length(ts.mfr_skus, 1) as sku_count
      FROM thibaut_room_settings ts
      WHERE
        ts.collection_name ILIKE $1
        OR ts.image_filename ILIKE $1
        OR EXISTS (
          SELECT 1 FROM unnest(ts.pattern_names) pn
          WHERE pn ILIKE $1
        )
      ORDER BY ts.collection_name, ts.sort_order
      LIMIT 50
    `, [`%${q}%`]);

    res.json({
      query: q,
      count: result.rows.length,
      results: result.rows
    });

  } catch (err) {
    console.error('Error searching room settings:', err);
    res.status(500).json({ error: 'Failed to search room settings' });
  }
});

module.exports = router;

/**
 * USAGE EXAMPLES:
 *
 * 1. Add to your Express app:
 *    const thibautRoomSettingsRoutes = require('./thibaut-room-settings-api-example');
 *    app.use(thibautRoomSettingsRoutes);
 *
 * 2. Example requests:
 *    - Get room settings for SKU: GET http://localhost:7600/api/thibaut/room-settings/T15806
 *    - Get Islander collection: GET http://localhost:7600/api/thibaut/collection/Islander/room-settings
 *    - Get matched only: GET http://localhost:7600/api/thibaut/collection/Islander/room-settings?matched_only=true
 *    - Get product with rooms: GET http://localhost:7600/api/thibaut/product/T15806/with-room-settings
 *    - Get statistics: GET http://localhost:7600/api/thibaut/room-settings/stats
 *    - Search: GET http://localhost:7600/api/thibaut/room-settings/search?q=Grasscloth
 */