mirror of
https://github.com/christianvidalwolf-prog/Craze-Data-check.git
synced 2026-08-03 13:25:23 +02:00
- Add bc-proxy and bc-export serverless API handlers - Add businessCentral service with updateCpnpNoInBC and downloadBusinessCentralItemsExcel - Sync cpnpNo to BC on save (CosmeticItemsView and handleSaveAll) - Parallelize handleSaveAll with Promise.all - Fix array index key, a11y click/keyboard handlers, autoFocus - Grant Change History and Pending Validation access to jingying.shi@craze-group.com Co-Authored-By: claude-flow <ruv@ruv.net>
138 lines
4.9 KiB
TypeScript
138 lines
4.9 KiB
TypeScript
import tailwindcss from '@tailwindcss/vite';
|
|
import react from '@vitejs/plugin-react';
|
|
import path from 'path';
|
|
import {defineConfig, loadEnv} from 'vite';
|
|
import { getBcConfig, getBCToken, findItem, patchItemCpnpNo, fetchAllItems, buildWorkbook } from './bc-runtime.js';
|
|
import * as XLSX from 'xlsx';
|
|
|
|
async function readJsonBody(req: any): Promise<any> {
|
|
return await new Promise((resolve, reject) => {
|
|
let raw = '';
|
|
req.on('data', (chunk: Buffer) => { raw += chunk.toString('utf8'); });
|
|
req.on('end', () => {
|
|
if (!raw.trim()) return resolve({});
|
|
try {
|
|
resolve(JSON.parse(raw));
|
|
} catch (err) {
|
|
reject(err);
|
|
}
|
|
});
|
|
req.on('error', reject);
|
|
});
|
|
}
|
|
|
|
export default defineConfig(({mode}) => {
|
|
const env = loadEnv(mode, '.', '');
|
|
return {
|
|
plugins: [
|
|
react(),
|
|
tailwindcss(),
|
|
{
|
|
name: 'bc-local-api',
|
|
configureServer(server) {
|
|
server.middlewares.use(async (req, res, next) => {
|
|
try {
|
|
const url = new URL(req.url || '/', 'http://localhost');
|
|
const config = getBcConfig(env);
|
|
|
|
if (url.pathname === '/api/bc-proxy') {
|
|
if (req.method === 'OPTIONS') {
|
|
res.statusCode = 204;
|
|
res.end();
|
|
return;
|
|
}
|
|
if (req.method !== 'POST') {
|
|
res.statusCode = 405;
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.end(JSON.stringify({ error: 'Method not allowed' }));
|
|
return;
|
|
}
|
|
|
|
const body = await readJsonBody(req);
|
|
const { articleNo, cpnpNo } = body || {};
|
|
if (!articleNo || cpnpNo === undefined) {
|
|
res.statusCode = 400;
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.end(JSON.stringify({ error: 'Missing articleNo or cpnpNo' }));
|
|
return;
|
|
}
|
|
|
|
const token = await getBCToken(config);
|
|
const item = await findItem(config, token, articleNo);
|
|
await patchItemCpnpNo(config, token, item, String(cpnpNo));
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.end(JSON.stringify({ success: true, articleNo, cpnpNo }));
|
|
return;
|
|
}
|
|
|
|
if (url.pathname === '/api/bc-export') {
|
|
if (req.method === 'OPTIONS') {
|
|
res.statusCode = 204;
|
|
res.end();
|
|
return;
|
|
}
|
|
if (req.method !== 'GET') {
|
|
res.statusCode = 405;
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.end(JSON.stringify({ error: 'Method not allowed' }));
|
|
return;
|
|
}
|
|
|
|
const token = await getBCToken(config);
|
|
const items = await fetchAllItems(config, token);
|
|
|
|
if (url.searchParams.get('format') === 'json') {
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.end(JSON.stringify({ success: true, count: items.length, items }));
|
|
return;
|
|
}
|
|
|
|
const workbook = buildWorkbook(items);
|
|
const buffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'buffer' });
|
|
const dateStr = new Date().toISOString().split('T')[0];
|
|
res.statusCode = 200;
|
|
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
|
res.setHeader('Content-Disposition', `attachment; filename="BusinessCentral_Items_${dateStr}.xlsx"`);
|
|
res.setHeader('Cache-Control', 'no-store');
|
|
res.end(buffer);
|
|
return;
|
|
}
|
|
} catch (err: any) {
|
|
const message = err?.message || String(err);
|
|
if ((req.url || '').startsWith('/api/bc-')) {
|
|
res.statusCode = 500;
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.end(JSON.stringify({ success: false, error: message }));
|
|
return;
|
|
}
|
|
console.error('[bc-local-api]', message);
|
|
}
|
|
|
|
next();
|
|
});
|
|
},
|
|
},
|
|
],
|
|
define: {
|
|
'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY),
|
|
},
|
|
resolve: {
|
|
alias: {
|
|
'@': path.resolve(__dirname, '.'),
|
|
},
|
|
},
|
|
server: {
|
|
// HMR is disabled in AI Studio via DISABLE_HMR env var.
|
|
// Do not modify - file watching is disabled to prevent flickering during agent edits.
|
|
hmr: process.env.DISABLE_HMR !== 'true',
|
|
proxy: {
|
|
'/dropbox-file': {
|
|
target: 'https://www.dropbox.com',
|
|
changeOrigin: true,
|
|
rewrite: (path) => path.replace(/^\/dropbox-file/, ''),
|
|
},
|
|
},
|
|
},
|
|
};
|
|
});
|