Files
Craze-Data-check/api/dropbox-sync.js
T

107 lines
3.3 KiB
JavaScript

import { applyCors, isAllowedOrigin } from './_cors.js';
import { createClient } from '@supabase/supabase-js';
const SUPABASE_URL = process.env.SUPABASE_URL || 'https://hwithddwaapyhnfwcesj.supabase.co';
const SUPABASE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_SERVICE_KEY || 'sb_publishable_fGXkh0bSrAOqSk2jWKAzSg_NJD9YPCv';
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);
function setCors(req, res) {
applyCors(req, res, 'POST, OPTIONS');
}
export default async function handler(req, res) {
setCors(req, res);
if (req.method === 'OPTIONS') {
return res.status(204).end();
}
const origin = req.headers.origin;
if (origin && !isAllowedOrigin(origin)) {
return res.status(403).json({ error: 'Forbidden' });
}
try {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
const { rows } = req.body;
if (!rows || !Array.isArray(rows)) {
return res.status(400).json({ error: 'Missing rows data' });
}
const articleNoIdx = 0;
// Fetch current product rows so we can preserve internal-only columns
// that do not exist in the live Dropbox workbook.
const { data: existingProducts } = await supabase
.from('products')
.select('product_id, data, status');
const existingProductMap = new Map((existingProducts || []).map(p => [p.product_id, p]));
const productsToUpsert = [];
for (const row of rows) {
const productId = String(row[articleNoIdx]);
if (!productId || productId.trim() === '') continue;
const existing = existingProductMap.get(productId);
const dbRowData = existing?.data;
if (dbRowData && Array.isArray(dbRowData)) {
const mergedData = [...row];
while (mergedData.length < dbRowData.length) {
mergedData.push(null);
}
for (let i = 100; i < dbRowData.length; i++) {
const internalValue = dbRowData[i];
if (internalValue !== undefined && internalValue !== null && internalValue !== '') {
mergedData[i] = internalValue;
}
}
productsToUpsert.push({
product_id: productId,
data: mergedData,
status: existing?.status || 'excel',
updated_at: new Date().toISOString()
});
} else {
// Normal excel sync
productsToUpsert.push({
product_id: productId,
data: row,
status: 'excel',
updated_at: new Date().toISOString()
});
}
}
console.log('Upserting/updating', productsToUpsert.length, 'products in Supabase...');
// Chunk upsert updates to avoid payload sizes or API limits
const CHUNK_SIZE = 100;
for (let i = 0; i < productsToUpsert.length; i += CHUNK_SIZE) {
const chunk = productsToUpsert.slice(i, i + CHUNK_SIZE);
const { error } = await supabase
.from('products')
.upsert(chunk, { onConflict: 'product_id' });
if (error) {
console.error('Supabase upsert error in chunk:', error);
return res.status(500).json({ error: error.message, detail: 'Failed to upsert products chunk' });
}
}
return res.json({
success: true,
syncedCount: productsToUpsert.length
});
} catch (err) {
console.error('Handler error:', err);
res.status(500).json({ error: err.message });
}
}