From 2ff325a1326446da239ea933c54af180a2b5bc27 Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 21 Sep 2025 23:47:05 -0400 Subject: [PATCH] Fix time periods on financial overview, remove some logging --- .../dashboard/acot-server/package-lock.json | 10 + .../dashboard/acot-server/package.json | 5 +- .../dashboard/acot-server/routes/events.js | 186 +++++-- .../dashboard/acot-server/utils/timeUtils.js | 473 ++++++++++-------- .../dashboard/AnalyticsDashboard.jsx | 1 - .../dashboard/FinancialOverview.tsx | 1 - .../components/dashboard/GorgiasOverview.jsx | 15 - .../components/dashboard/MiniStatCards.jsx | 18 +- .../src/components/dashboard/StatCards.jsx | 19 - .../dashboard/UserBehaviorDashboard.jsx | 13 +- .../components/overview/ForecastMetrics.tsx | 2 - .../components/overview/PurchaseMetrics.tsx | 2 - .../overview/ReplenishmentMetrics.tsx | 2 - .../src/components/overview/StockMetrics.tsx | 2 - .../MatchColumnsStep/MatchColumnsStep.tsx | 16 - .../SelectHeaderStep/SelectHeaderStep.tsx | 17 - .../components/ValidationContainer.tsx | 40 +- inventory/vite.config.ts | 49 +- 18 files changed, 426 insertions(+), 445 deletions(-) diff --git a/inventory-server/dashboard/acot-server/package-lock.json b/inventory-server/dashboard/acot-server/package-lock.json index 3d571f9..5c99fcc 100644 --- a/inventory-server/dashboard/acot-server/package-lock.json +++ b/inventory-server/dashboard/acot-server/package-lock.json @@ -12,6 +12,7 @@ "cors": "^2.8.5", "dotenv": "^16.3.1", "express": "^4.18.2", + "luxon": "^3.5.0", "morgan": "^1.10.0", "mysql2": "^3.6.5", "ssh2": "^1.14.0" @@ -826,6 +827,15 @@ "url": "https://github.com/sponsors/wellwelwel" } }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", diff --git a/inventory-server/dashboard/acot-server/package.json b/inventory-server/dashboard/acot-server/package.json index 7e3a008..ca8eda2 100644 --- a/inventory-server/dashboard/acot-server/package.json +++ b/inventory-server/dashboard/acot-server/package.json @@ -14,9 +14,10 @@ "morgan": "^1.10.0", "ssh2": "^1.14.0", "mysql2": "^3.6.5", - "compression": "^1.7.4" + "compression": "^1.7.4", + "luxon": "^3.5.0" }, "devDependencies": { "nodemon": "^3.0.1" } -} \ No newline at end of file +} diff --git a/inventory-server/dashboard/acot-server/routes/events.js b/inventory-server/dashboard/acot-server/routes/events.js index 5cdb84b..5d03ba9 100644 --- a/inventory-server/dashboard/acot-server/routes/events.js +++ b/inventory-server/dashboard/acot-server/routes/events.js @@ -1,7 +1,17 @@ const express = require('express'); +const { DateTime } = require('luxon'); + const router = express.Router(); const { getDbConnection, getPoolStatus } = require('../db/connection'); -const { getTimeRangeConditions, formatBusinessDate, getBusinessDayBounds } = require('../utils/timeUtils'); +const { + getTimeRangeConditions, + formatBusinessDate, + getBusinessDayBounds, + _internal: timeHelpers +} = require('../utils/timeUtils'); + +const TIMEZONE = 'America/New_York'; +const BUSINESS_DAY_START_HOUR = timeHelpers?.BUSINESS_DAY_START_HOUR ?? 1; // Image URL generation utility const getImageUrls = (pid, iid = 1) => { @@ -421,6 +431,24 @@ router.get('/financials', async (req, res) => { const { whereClause, params, dateRange } = getTimeRangeConditions(timeRange, startDate, endDate); const financialWhere = whereClause.replace(/date_placed/g, 'date_change'); + const formatDebugBound = (value) => { + if (!value) return 'n/a'; + const parsed = DateTime.fromSQL(value, { zone: 'UTC-05:00' }); + if (!parsed.isValid) { + return `invalid(${value})`; + } + return parsed.setZone(TIMEZONE).toISO(); + }; + + console.log('[FINANCIALS] request params', { + timeRange: timeRange || 'default', + startDate, + endDate, + whereClause: financialWhere, + params, + boundsEastern: Array.isArray(params) ? params.map(formatDebugBound) : [], + }); + const [totalsRows] = await connection.execute( buildFinancialTotalsQuery(financialWhere), params @@ -428,6 +456,11 @@ router.get('/financials', async (req, res) => { const totals = normalizeFinancialTotals(totalsRows[0]); + console.log('[FINANCIALS] totals query result', { + rows: totalsRows.length, + totals, + }); + const [trendRows] = await connection.execute( buildFinancialTrendQuery(financialWhere), params @@ -435,11 +468,25 @@ router.get('/financials', async (req, res) => { const trend = trendRows.map(normalizeFinancialTrendRow); + console.log('[FINANCIALS] trend query result', { + rows: trendRows.length, + first: trend[0] || null, + last: trend[trend.length - 1] || null, + }); + let previousTotals = null; let comparison = null; const previousRange = getPreviousPeriodRange(timeRange, startDate, endDate); if (previousRange) { + console.log('[FINANCIALS] previous range params', { + timeRange: timeRange || 'default', + prevWhere: previousRange.whereClause.replace(/date_placed/g, 'date_change'), + params: previousRange.params, + boundsEastern: Array.isArray(previousRange.params) + ? previousRange.params.map(formatDebugBound) + : [], + }); const prevWhere = previousRange.whereClause.replace(/date_placed/g, 'date_change'); const [previousRows] = await connection.execute( buildFinancialTotalsQuery(prevWhere), @@ -458,12 +505,37 @@ router.get('/financials', async (req, res) => { }; } + const trendDebugSample = trend.slice(-3).map((item) => ({ + date: item.date, + timestamp: item.timestamp, + income: item.income, + grossSales: item.grossSales, + })); + + const debugInfo = { + serverTimeUtc: new Date().toISOString(), + timeRange: timeRange || 'default', + params, + boundsEastern: Array.isArray(params) ? params.map(formatDebugBound) : [], + trendCount: trend.length, + trendSample: trendDebugSample, + previousRange: previousRange + ? { + params: previousRange.params, + boundsEastern: Array.isArray(previousRange.params) + ? previousRange.params.map(formatDebugBound) + : [], + } + : null, + }; + res.json({ dateRange, totals, previousTotals, comparison, trend, + debug: debugInfo, }); } catch (error) { console.error('Error in /financials:', error); @@ -662,44 +734,35 @@ function processShippingData(shippingResult, totalShipped) { } function calculatePeriodProgress(timeRange) { - const now = new Date(); - const easternTime = new Date(now.getTime() - (5 * 60 * 60 * 1000)); // UTC-5 - - switch (timeRange) { - case 'today': { - const { start } = getBusinessDayBounds('today'); - const businessStart = new Date(start); - const businessEnd = new Date(businessStart); - businessEnd.setDate(businessEnd.getDate() + 1); - businessEnd.setHours(0, 59, 59, 999); // 12:59 AM next day - - const elapsed = easternTime.getTime() - businessStart.getTime(); - const total = businessEnd.getTime() - businessStart.getTime(); - return Math.min(100, Math.max(0, (elapsed / total) * 100)); - } - case 'thisWeek': { - const startOfWeek = new Date(easternTime); - startOfWeek.setDate(easternTime.getDate() - easternTime.getDay()); // Sunday - startOfWeek.setHours(1, 0, 0, 0); // 1 AM business day start - - const endOfWeek = new Date(startOfWeek); - endOfWeek.setDate(endOfWeek.getDate() + 7); - - const elapsed = easternTime.getTime() - startOfWeek.getTime(); - const total = endOfWeek.getTime() - startOfWeek.getTime(); - return Math.min(100, Math.max(0, (elapsed / total) * 100)); - } - case 'thisMonth': { - const startOfMonth = new Date(easternTime.getFullYear(), easternTime.getMonth(), 1, 1, 0, 0, 0); - const endOfMonth = new Date(easternTime.getFullYear(), easternTime.getMonth() + 1, 1, 0, 59, 59, 999); - - const elapsed = easternTime.getTime() - startOfMonth.getTime(); - const total = endOfMonth.getTime() - startOfMonth.getTime(); - return Math.min(100, Math.max(0, (elapsed / total) * 100)); - } - default: - return 100; + if (!['today', 'thisWeek', 'thisMonth'].includes(timeRange)) { + return 100; } + + const now = DateTime.now().setZone(TIMEZONE); + + let range; + try { + range = timeHelpers.getRangeForTimeRange(timeRange, now); + } catch (error) { + console.error(`[STATS] Failed to derive range for ${timeRange}:`, error); + return 100; + } + + if (!range?.start || !range?.end) { + return 100; + } + + const total = range.end.toMillis() - range.start.toMillis(); + if (total <= 0) { + return 100; + } + + const elapsed = Math.min( + Math.max(now.toMillis() - range.start.toMillis(), 0), + total + ); + + return Math.min(100, Math.max(0, (elapsed / total) * 100)); } function buildFinancialTotalsQuery(whereClause) { @@ -718,9 +781,13 @@ function buildFinancialTotalsQuery(whereClause) { } function buildFinancialTrendQuery(whereClause) { + const businessDayOffset = BUSINESS_DAY_START_HOUR; return ` SELECT - DATE(date_change) as date, + DATE_FORMAT( + DATE_SUB(date_change, INTERVAL ${businessDayOffset} HOUR), + '%Y-%m-%d' + ) as businessDate, SUM(sale_amount) as grossSales, SUM(refund_amount) as refunds, SUM(shipping_collected_amount + small_order_fee_amount + rush_fee_amount) as shippingFees, @@ -730,8 +797,8 @@ function buildFinancialTrendQuery(whereClause) { FROM report_sales_data WHERE ${whereClause} AND action IN (1, 2, 3) - GROUP BY DATE(date_change) - ORDER BY date ASC + GROUP BY businessDate + ORDER BY businessDate ASC `; } @@ -772,15 +839,48 @@ function normalizeFinancialTrendRow(row = {}) { const profit = income - cogs; const margin = income !== 0 ? (profit / income) * 100 : 0; let timestamp = null; + let dateValue = row.businessDate || row.date || null; - if (row.date instanceof Date) { + const resolveBusinessDayStart = (value) => { + if (!value) { + return null; + } + + let dt; + if (value instanceof Date) { + dt = DateTime.fromJSDate(value, { zone: TIMEZONE }); + } else if (typeof value === 'string') { + dt = DateTime.fromISO(value, { zone: TIMEZONE }); + if (!dt.isValid) { + dt = DateTime.fromSQL(value, { zone: TIMEZONE }); + } + } + + if (!dt || !dt.isValid) { + return null; + } + + const hour = BUSINESS_DAY_START_HOUR; + return dt.set({ + hour, + minute: 0, + second: 0, + millisecond: 0, + }); + }; + + const businessDayStart = resolveBusinessDayStart(dateValue); + if (businessDayStart) { + timestamp = businessDayStart.toUTC().toISO(); + dateValue = businessDayStart.toISO(); + } else if (row.date instanceof Date) { timestamp = new Date(row.date.getTime()).toISOString(); } else if (typeof row.date === 'string') { timestamp = new Date(`${row.date}T00:00:00Z`).toISOString(); } return { - date: row.date, + date: dateValue, grossSales, refunds, shippingFees, diff --git a/inventory-server/dashboard/acot-server/utils/timeUtils.js b/inventory-server/dashboard/acot-server/utils/timeUtils.js index 58bd5cc..29fdfae 100644 --- a/inventory-server/dashboard/acot-server/utils/timeUtils.js +++ b/inventory-server/dashboard/acot-server/utils/timeUtils.js @@ -1,217 +1,219 @@ -// Time utilities for handling business day logic and time ranges -// Business day is 1am-12:59am Eastern time (UTC-5) +const { DateTime } = require('luxon'); + +const TIMEZONE = 'America/New_York'; +const DB_TIMEZONE = 'UTC-05:00'; +const BUSINESS_DAY_START_HOUR = 1; // 1 AM Eastern +const WEEK_START_DAY = 7; // Sunday (Luxon uses 1 = Monday, 7 = Sunday) +const DB_DATETIME_FORMAT = 'yyyy-LL-dd HH:mm:ss'; + +const isDateTime = (value) => DateTime.isDateTime(value); + +const ensureDateTime = (value, { zone = TIMEZONE } = {}) => { + if (!value) return null; + + if (isDateTime(value)) { + return value.setZone(zone); + } + + if (value instanceof Date) { + return DateTime.fromJSDate(value, { zone }); + } + + if (typeof value === 'number') { + return DateTime.fromMillis(value, { zone }); + } + + if (typeof value === 'string') { + let dt = DateTime.fromISO(value, { zone, setZone: true }); + if (!dt.isValid) { + dt = DateTime.fromSQL(value, { zone }); + } + return dt.isValid ? dt : null; + } + + return null; +}; + +const getNow = () => DateTime.now().setZone(TIMEZONE); + +const getDayStart = (input = getNow()) => { + const dt = ensureDateTime(input); + if (!dt || !dt.isValid) { + const fallback = getNow(); + return fallback.set({ + hour: BUSINESS_DAY_START_HOUR, + minute: 0, + second: 0, + millisecond: 0 + }); + } + + const sameDayStart = dt.set({ + hour: BUSINESS_DAY_START_HOUR, + minute: 0, + second: 0, + millisecond: 0 + }); + + return dt.hour < BUSINESS_DAY_START_HOUR + ? sameDayStart.minus({ days: 1 }) + : sameDayStart; +}; + +const getDayEnd = (input = getNow()) => { + return getDayStart(input).plus({ days: 1 }).minus({ milliseconds: 1 }); +}; + +const getWeekStart = (input = getNow()) => { + const dt = ensureDateTime(input); + if (!dt || !dt.isValid) { + return getDayStart(); + } + + const startOfWeek = dt.set({ weekday: WEEK_START_DAY }).startOf('day'); + const normalized = startOfWeek > dt ? startOfWeek.minus({ weeks: 1 }) : startOfWeek; + return normalized.set({ + hour: BUSINESS_DAY_START_HOUR, + minute: 0, + second: 0, + millisecond: 0 + }); +}; + +const getRangeForTimeRange = (timeRange = 'today', now = getNow()) => { + const current = ensureDateTime(now); + if (!current || !current.isValid) { + throw new Error('Invalid reference time for range calculation'); + } -const getBusinessDayBounds = (timeRange) => { - const now = new Date(); - const easternTime = new Date(now.getTime() - (5 * 60 * 60 * 1000)); // UTC-5 - switch (timeRange) { case 'today': { - const start = new Date(easternTime); - start.setHours(1, 0, 0, 0); // 1 AM start of business day - - const end = new Date(start); - end.setDate(end.getDate() + 1); - end.setHours(0, 59, 59, 999); // 12:59 AM next day - - return { start, end }; + return { + start: getDayStart(current), + end: getDayEnd(current) + }; } - case 'yesterday': { - const start = new Date(easternTime); - start.setDate(start.getDate() - 1); - start.setHours(1, 0, 0, 0); - - const end = new Date(start); - end.setDate(end.getDate() + 1); - end.setHours(0, 59, 59, 999); - - return { start, end }; + const target = current.minus({ days: 1 }); + return { + start: getDayStart(target), + end: getDayEnd(target) + }; } - - case 'thisWeek': { - const start = new Date(easternTime); - start.setDate(easternTime.getDate() - easternTime.getDay()); // Sunday - start.setHours(1, 0, 0, 0); - - const end = new Date(easternTime); - end.setDate(end.getDate() + 1); - end.setHours(0, 59, 59, 999); - - return { start, end }; - } - - case 'lastWeek': { - const start = new Date(easternTime); - start.setDate(easternTime.getDate() - easternTime.getDay() - 7); // Previous Sunday - start.setHours(1, 0, 0, 0); - - const end = new Date(start); - end.setDate(end.getDate() + 7); - end.setHours(0, 59, 59, 999); - - return { start, end }; - } - - case 'thisMonth': { - const start = new Date(easternTime.getFullYear(), easternTime.getMonth(), 1, 1, 0, 0, 0); - const end = new Date(easternTime); - end.setDate(end.getDate() + 1); - end.setHours(0, 59, 59, 999); - - return { start, end }; - } - - case 'lastMonth': { - const start = new Date(easternTime.getFullYear(), easternTime.getMonth() - 1, 1, 1, 0, 0, 0); - const end = new Date(easternTime.getFullYear(), easternTime.getMonth(), 1, 0, 59, 59, 999); - - return { start, end }; - } - - case 'last7days': { - const end = new Date(easternTime); - end.setHours(0, 59, 59, 999); - - const start = new Date(end); - start.setDate(start.getDate() - 7); - start.setHours(1, 0, 0, 0); - - return { start, end }; - } - - case 'last30days': { - const end = new Date(easternTime); - end.setHours(0, 59, 59, 999); - - const start = new Date(end); - start.setDate(start.getDate() - 30); - start.setHours(1, 0, 0, 0); - - return { start, end }; - } - - case 'last90days': { - const end = new Date(easternTime); - end.setHours(0, 59, 59, 999); - - const start = new Date(end); - start.setDate(start.getDate() - 90); - start.setHours(1, 0, 0, 0); - - return { start, end }; - } - - case 'previous7days': { - const end = new Date(easternTime); - end.setDate(end.getDate() - 1); - end.setHours(0, 59, 59, 999); - - const start = new Date(end); - start.setDate(start.getDate() - 6); - start.setHours(1, 0, 0, 0); - - return { start, end }; - } - - case 'previous30days': { - const end = new Date(easternTime); - end.setDate(end.getDate() - 1); - end.setHours(0, 59, 59, 999); - - const start = new Date(end); - start.setDate(start.getDate() - 29); - start.setHours(1, 0, 0, 0); - - return { start, end }; - } - - case 'previous90days': { - const end = new Date(easternTime); - end.setDate(end.getDate() - 1); - end.setHours(0, 59, 59, 999); - - const start = new Date(end); - start.setDate(start.getDate() - 89); - start.setHours(1, 0, 0, 0); - - return { start, end }; - } - case 'twoDaysAgo': { - const start = new Date(easternTime); - start.setDate(start.getDate() - 2); - start.setHours(1, 0, 0, 0); - - const end = new Date(start); - end.setDate(end.getDate() + 1); - end.setHours(0, 59, 59, 999); - - return { start, end }; + const target = current.minus({ days: 2 }); + return { + start: getDayStart(target), + end: getDayEnd(target) + }; + } + case 'thisWeek': { + return { + start: getWeekStart(current), + end: getDayEnd(current) + }; + } + case 'lastWeek': { + const lastWeek = current.minus({ weeks: 1 }); + const weekStart = getWeekStart(lastWeek); + const weekEnd = weekStart.plus({ days: 6 }); + return { + start: weekStart, + end: getDayEnd(weekEnd) + }; + } + case 'thisMonth': { + const dayStart = getDayStart(current); + const monthStart = dayStart.startOf('month').set({ hour: BUSINESS_DAY_START_HOUR }); + return { + start: monthStart, + end: getDayEnd(current) + }; + } + case 'lastMonth': { + const lastMonth = current.minus({ months: 1 }); + const monthStart = lastMonth + .startOf('month') + .set({ hour: BUSINESS_DAY_START_HOUR, minute: 0, second: 0, millisecond: 0 }); + const monthEnd = monthStart.plus({ months: 1 }).minus({ days: 1 }); + return { + start: monthStart, + end: getDayEnd(monthEnd) + }; + } + case 'last7days': { + const dayStart = getDayStart(current); + return { + start: dayStart.minus({ days: 6 }), + end: getDayEnd(current) + }; + } + case 'last30days': { + const dayStart = getDayStart(current); + return { + start: dayStart.minus({ days: 29 }), + end: getDayEnd(current) + }; + } + case 'last90days': { + const dayStart = getDayStart(current); + return { + start: dayStart.minus({ days: 89 }), + end: getDayEnd(current) + }; + } + case 'previous7days': { + const currentPeriodStart = getDayStart(current).minus({ days: 6 }); + const previousEndDay = currentPeriodStart.minus({ days: 1 }); + const previousStartDay = previousEndDay.minus({ days: 6 }); + return { + start: getDayStart(previousStartDay), + end: getDayEnd(previousEndDay) + }; + } + case 'previous30days': { + const currentPeriodStart = getDayStart(current).minus({ days: 29 }); + const previousEndDay = currentPeriodStart.minus({ days: 1 }); + const previousStartDay = previousEndDay.minus({ days: 29 }); + return { + start: getDayStart(previousStartDay), + end: getDayEnd(previousEndDay) + }; + } + case 'previous90days': { + const currentPeriodStart = getDayStart(current).minus({ days: 89 }); + const previousEndDay = currentPeriodStart.minus({ days: 1 }); + const previousStartDay = previousEndDay.minus({ days: 89 }); + return { + start: getDayStart(previousStartDay), + end: getDayEnd(previousEndDay) + }; } - default: throw new Error(`Unknown time range: ${timeRange}`); } }; -const getTimeRangeConditions = (timeRange, startDate, endDate) => { - if (timeRange === 'custom' && startDate && endDate) { - // Custom date range - const start = new Date(startDate); - const end = new Date(endDate); - - // Convert to UTC-5 (Eastern time) - const startUTC5 = new Date(start.getTime() - (5 * 60 * 60 * 1000)); - const endUTC5 = new Date(end.getTime() - (5 * 60 * 60 * 1000)); - - return { - whereClause: 'date_placed >= ? AND date_placed <= ?', - params: [ - startUTC5.toISOString().slice(0, 19).replace('T', ' '), - endUTC5.toISOString().slice(0, 19).replace('T', ' ') - ], - dateRange: { - start: startDate, - end: endDate, - label: `${formatBusinessDate(start)} - ${formatBusinessDate(end)}` - } - }; +const toDatabaseSqlString = (dt) => { + const normalized = ensureDateTime(dt); + if (!normalized || !normalized.isValid) { + throw new Error('Invalid datetime provided for SQL conversion'); } - - if (!timeRange) { - timeRange = 'today'; - } - - const { start, end } = getBusinessDayBounds(timeRange); - - // Convert to MySQL datetime format (UTC-5) - const startStr = start.toISOString().slice(0, 19).replace('T', ' '); - const endStr = end.toISOString().slice(0, 19).replace('T', ' '); - - return { - whereClause: 'date_placed >= ? AND date_placed <= ?', - params: [startStr, endStr], - dateRange: { - start: start.toISOString(), - end: end.toISOString(), - label: getTimeRangeLabel(timeRange) - } - }; + const dbTime = normalized.setZone(DB_TIMEZONE, { keepLocalTime: true }); + return dbTime.toFormat(DB_DATETIME_FORMAT); }; -const formatBusinessDate = (date) => { - return date.toLocaleDateString('en-US', { - month: 'short', - day: 'numeric', - year: 'numeric' - }); +const formatBusinessDate = (input) => { + const dt = ensureDateTime(input); + if (!dt || !dt.isValid) return ''; + return dt.setZone(TIMEZONE).toFormat('LLL d, yyyy'); }; const getTimeRangeLabel = (timeRange) => { const labels = { today: 'Today', yesterday: 'Yesterday', + twoDaysAgo: 'Two Days Ago', thisWeek: 'This Week', lastWeek: 'Last Week', thisMonth: 'This Month', @@ -221,32 +223,75 @@ const getTimeRangeLabel = (timeRange) => { last90days: 'Last 90 Days', previous7days: 'Previous 7 Days', previous30days: 'Previous 30 Days', - previous90days: 'Previous 90 Days', - twoDaysAgo: 'Two Days Ago' + previous90days: 'Previous 90 Days' }; - + return labels[timeRange] || timeRange; }; -// Helper to convert MySQL datetime to JavaScript Date +const getTimeRangeConditions = (timeRange, startDate, endDate) => { + if (timeRange === 'custom' && startDate && endDate) { + const start = ensureDateTime(startDate); + const end = ensureDateTime(endDate); + + if (!start || !start.isValid || !end || !end.isValid) { + throw new Error('Invalid custom date range provided'); + } + + return { + whereClause: 'date_placed >= ? AND date_placed <= ?', + params: [toDatabaseSqlString(start), toDatabaseSqlString(end)], + dateRange: { + start: start.toUTC().toISO(), + end: end.toUTC().toISO(), + label: `${formatBusinessDate(start)} - ${formatBusinessDate(end)}` + } + }; + } + + const normalizedRange = timeRange || 'today'; + const range = getRangeForTimeRange(normalizedRange); + + return { + whereClause: 'date_placed >= ? AND date_placed <= ?', + params: [toDatabaseSqlString(range.start), toDatabaseSqlString(range.end)], + dateRange: { + start: range.start.toUTC().toISO(), + end: range.end.toUTC().toISO(), + label: getTimeRangeLabel(normalizedRange) + } + }; +}; + +const getBusinessDayBounds = (timeRange) => { + const range = getRangeForTimeRange(timeRange); + return { + start: range.start.toJSDate(), + end: range.end.toJSDate() + }; +}; + const parseBusinessDate = (mysqlDatetime) => { if (!mysqlDatetime || mysqlDatetime === '0000-00-00 00:00:00') { return null; } - - // MySQL datetime is stored in UTC-5, so we need to add 5 hours to get UTC - const date = new Date(mysqlDatetime + ' UTC'); - date.setHours(date.getHours() + 5); - return date; + + const dt = DateTime.fromSQL(mysqlDatetime, { zone: DB_TIMEZONE }); + if (!dt.isValid) { + console.error('[timeUtils] Failed to parse MySQL datetime:', mysqlDatetime, dt.invalidExplanation); + return null; + } + + return dt.toUTC().toJSDate(); }; -// Helper to format date for MySQL queries -const formatMySQLDate = (date) => { - if (!date) return null; - - // Convert to UTC-5 for storage - const utc5Date = new Date(date.getTime() - (5 * 60 * 60 * 1000)); - return utc5Date.toISOString().slice(0, 19).replace('T', ' '); +const formatMySQLDate = (input) => { + if (!input) return null; + + const dt = ensureDateTime(input, { zone: 'utc' }); + if (!dt || !dt.isValid) return null; + + return dt.setZone(DB_TIMEZONE).toFormat(DB_DATETIME_FORMAT); }; module.exports = { @@ -255,5 +300,13 @@ module.exports = { formatBusinessDate, getTimeRangeLabel, parseBusinessDate, - formatMySQLDate -}; \ No newline at end of file + formatMySQLDate, + // Expose helpers for tests or advanced consumers + _internal: { + getDayStart, + getDayEnd, + getWeekStart, + getRangeForTimeRange, + BUSINESS_DAY_START_HOUR + } +}; diff --git a/inventory/src/components/dashboard/AnalyticsDashboard.jsx b/inventory/src/components/dashboard/AnalyticsDashboard.jsx index 6c17b73..cafaf4c 100644 --- a/inventory/src/components/dashboard/AnalyticsDashboard.jsx +++ b/inventory/src/components/dashboard/AnalyticsDashboard.jsx @@ -186,7 +186,6 @@ export const AnalyticsDashboard = () => { const result = await response.json(); if (!result?.data?.rows) { - console.log("No result data received"); return; } diff --git a/inventory/src/components/dashboard/FinancialOverview.tsx b/inventory/src/components/dashboard/FinancialOverview.tsx index 73a1cbb..0bfc0fa 100644 --- a/inventory/src/components/dashboard/FinancialOverview.tsx +++ b/inventory/src/components/dashboard/FinancialOverview.tsx @@ -761,7 +761,6 @@ const FinancialOverview = () => { } const grossSalesValue = toNumber((point as { grossSales?: number }).grossSales); - const refundsValue = toNumber((point as { refunds?: number }).refunds); const shippingFeesValue = toNumber((point as { shippingFees?: number }).shippingFees); const taxCollectedValue = toNumber((point as { taxCollected?: number }).taxCollected); const discountsValue = toNumber((point as { discounts?: number }).discounts); diff --git a/inventory/src/components/dashboard/GorgiasOverview.jsx b/inventory/src/components/dashboard/GorgiasOverview.jsx index 482b193..eb0d375 100644 --- a/inventory/src/components/dashboard/GorgiasOverview.jsx +++ b/inventory/src/components/dashboard/GorgiasOverview.jsx @@ -225,13 +225,6 @@ const GorgiasOverview = () => { .then(res => res.data?.data?.data?.data || []), ]); - console.log('Raw API responses:', { - overview, - channelStats, - agentStats, - satisfaction, - }); - setData({ overview, channels: channelStats, @@ -270,8 +263,6 @@ const GorgiasOverview = () => { return acc; }, {}); - console.log('Processed stats:', stats); - // Process satisfaction data const satisfactionStats = (data.satisfaction || []).reduce((acc, item) => { if (item.name !== 'response_distribution') { @@ -285,8 +276,6 @@ const GorgiasOverview = () => { return acc; }, {}); - console.log('Processed satisfaction stats:', satisfactionStats); - // Process channel data const channels = data.channels?.map(line => ({ name: line[0]?.value || '', @@ -295,8 +284,6 @@ const GorgiasOverview = () => { delta: line[3]?.value || 0 })) || []; - console.log('Processed channels:', channels); - // Process agent data const agents = data.agents?.map(line => ({ name: line[0]?.value || '', @@ -306,8 +293,6 @@ const GorgiasOverview = () => { delta: line[4]?.value || 0 })) || []; - console.log('Processed agents:', agents); - if (error) { return ( diff --git a/inventory/src/components/dashboard/MiniStatCards.jsx b/inventory/src/components/dashboard/MiniStatCards.jsx index 5d07270..b9771e0 100644 --- a/inventory/src/components/dashboard/MiniStatCards.jsx +++ b/inventory/src/components/dashboard/MiniStatCards.jsx @@ -256,29 +256,13 @@ const MiniStatCards = ({ : stats.revenue; const prevRevenue = stats.prevPeriodRevenue; // Previous period's total revenue - console.log('[MiniStatCards RevenueTrend Debug]', { - periodProgress: stats.periodProgress, - currentRevenue, - smartProjection: projection?.projectedRevenue, - simpleProjection: stats.projectedRevenue, - actualRevenue: stats.revenue, - prevRevenue, - isProjected: stats.periodProgress < 100 - }); - if (!currentRevenue || !prevRevenue) return null; // Calculate absolute difference percentage const trend = currentRevenue >= prevRevenue ? "up" : "down"; const diff = Math.abs(currentRevenue - prevRevenue); const percentage = (diff / prevRevenue) * 100; - - console.log('[MiniStatCards RevenueTrend Result]', { - trend, - percentage, - calculation: `(|${currentRevenue} - ${prevRevenue}| / ${prevRevenue}) * 100 = ${percentage}%` - }); - + return { trend, value: percentage, diff --git a/inventory/src/components/dashboard/StatCards.jsx b/inventory/src/components/dashboard/StatCards.jsx index 12fe5cc..d4b810b 100644 --- a/inventory/src/components/dashboard/StatCards.jsx +++ b/inventory/src/components/dashboard/StatCards.jsx @@ -1397,12 +1397,10 @@ const StatCards = ({ const cachedData = getCacheData(detailTimeRange, metric); if (cachedData) { - console.log(`Using cached data for ${metric}`); setDetailData((prev) => ({ ...prev, [metric]: cachedData })); return cachedData; } - console.log(`Fetching detail data for ${metric}`); setDetailDataLoading((prev) => ({ ...prev, [metric]: true })); try { @@ -1481,7 +1479,6 @@ const StatCards = ({ eventType: "PLACED_ORDER", }); const data = response.stats; - console.log("Fetched order range data:", data); setCacheData(detailTimeRange, metric, data); setDetailData((prev) => ({ ...prev, [metric]: data })); setError(null); @@ -1570,16 +1567,6 @@ const StatCards = ({ : stats.revenue; const prevRevenue = stats.prevPeriodRevenue; // Previous period's total revenue - console.log('[RevenueTrend Debug]', { - periodProgress: stats.periodProgress, - currentRevenue, - smartProjection: projection?.projectedRevenue, - simpleProjection: stats.projectedRevenue, - actualRevenue: stats.revenue, - prevRevenue, - isProjected: stats.periodProgress < 100 - }); - if (!currentRevenue || !prevRevenue) return null; // Calculate absolute difference percentage @@ -1587,12 +1574,6 @@ const StatCards = ({ const diff = Math.abs(currentRevenue - prevRevenue); const percentage = (diff / prevRevenue) * 100; - console.log('[RevenueTrend Result]', { - trend, - percentage, - calculation: `(|${currentRevenue} - ${prevRevenue}| / ${prevRevenue}) * 100 = ${percentage}%` - }); - return { trend, value: percentage, diff --git a/inventory/src/components/dashboard/UserBehaviorDashboard.jsx b/inventory/src/components/dashboard/UserBehaviorDashboard.jsx index 3f2e991..d21d5d5 100644 --- a/inventory/src/components/dashboard/UserBehaviorDashboard.jsx +++ b/inventory/src/components/dashboard/UserBehaviorDashboard.jsx @@ -86,7 +86,6 @@ export const UserBehaviorDashboard = () => { const processPageData = (data) => { if (!data?.rows) { - console.log("No rows in page data"); return []; } @@ -101,7 +100,6 @@ export const UserBehaviorDashboard = () => { const processDeviceData = (data) => { if (!data?.rows) { - console.log("No rows in device data"); return []; } @@ -123,7 +121,6 @@ export const UserBehaviorDashboard = () => { const processSourceData = (data) => { if (!data?.rows) { - console.log("No rows in source data"); return []; } @@ -150,7 +147,6 @@ export const UserBehaviorDashboard = () => { } const result = await response.json(); - console.log("Raw user behavior response:", result); if (!result?.success) { throw new Error("Invalid response structure"); @@ -164,12 +160,6 @@ export const UserBehaviorDashboard = () => { const deviceResponse = rawData?.deviceResponse || rawData?.reports?.[1]; const sourceResponse = rawData?.sourceResponse || rawData?.reports?.[2]; - console.log("Extracted responses:", { - pageResponse, - deviceResponse, - sourceResponse, - }); - const processed = { success: true, data: { @@ -180,8 +170,7 @@ export const UserBehaviorDashboard = () => { sourceData: processSourceData(sourceResponse), }, }; - - console.log("Final processed data:", processed); + setData(processed); } catch (error) { console.error("Failed to fetch behavior data:", error); diff --git a/inventory/src/components/overview/ForecastMetrics.tsx b/inventory/src/components/overview/ForecastMetrics.tsx index 3455230..afadb5a 100644 --- a/inventory/src/components/overview/ForecastMetrics.tsx +++ b/inventory/src/components/overview/ForecastMetrics.tsx @@ -40,14 +40,12 @@ export function ForecastMetrics() { startDate: dateRange.from?.toISOString() || "", endDate: dateRange.to?.toISOString() || "", }); - console.log('Fetching forecast metrics with params:', params.toString()); const response = await fetch(`${config.apiUrl}/dashboard/forecast/metrics?${params}`) if (!response.ok) { const text = await response.text(); throw new Error(`Failed to fetch forecast metrics: ${text}`); } const data = await response.json(); - console.log('Forecast metrics response:', data); return data; }, }) diff --git a/inventory/src/components/overview/PurchaseMetrics.tsx b/inventory/src/components/overview/PurchaseMetrics.tsx index 4235277..e07e3c7 100644 --- a/inventory/src/components/overview/PurchaseMetrics.tsx +++ b/inventory/src/components/overview/PurchaseMetrics.tsx @@ -103,7 +103,6 @@ export function PurchaseMetrics() { const { data, error, isLoading } = useQuery({ queryKey: ["purchase-metrics"], queryFn: async () => { - console.log('Fetching from:', `${config.apiUrl}/dashboard/purchase/metrics`); const response = await fetch(`${config.apiUrl}/dashboard/purchase/metrics`) if (!response.ok) { const text = await response.text(); @@ -111,7 +110,6 @@ export function PurchaseMetrics() { throw new Error(`Failed to fetch purchase metrics: ${response.status} ${response.statusText}`); } const data = await response.json(); - console.log('API Response:', data); return data; }, }) diff --git a/inventory/src/components/overview/ReplenishmentMetrics.tsx b/inventory/src/components/overview/ReplenishmentMetrics.tsx index f94487f..3950376 100644 --- a/inventory/src/components/overview/ReplenishmentMetrics.tsx +++ b/inventory/src/components/overview/ReplenishmentMetrics.tsx @@ -25,7 +25,6 @@ export function ReplenishmentMetrics() { const { data, error, isLoading } = useQuery({ queryKey: ["replenishment-metrics"], queryFn: async () => { - console.log('Fetching from:', `${config.apiUrl}/dashboard/replenishment/metrics`); const response = await fetch(`${config.apiUrl}/dashboard/replenishment/metrics`) if (!response.ok) { const text = await response.text(); @@ -33,7 +32,6 @@ export function ReplenishmentMetrics() { throw new Error(`Failed to fetch replenishment metrics: ${response.status} ${response.statusText} - ${text}`) } const data = await response.json(); - console.log('API Response:', data); return data; }, }) diff --git a/inventory/src/components/overview/StockMetrics.tsx b/inventory/src/components/overview/StockMetrics.tsx index 04dc18e..06c9339 100644 --- a/inventory/src/components/overview/StockMetrics.tsx +++ b/inventory/src/components/overview/StockMetrics.tsx @@ -103,7 +103,6 @@ export function StockMetrics() { const { data, error, isLoading } = useQuery({ queryKey: ["stock-metrics"], queryFn: async () => { - console.log('Fetching from:', `${config.apiUrl}/dashboard/stock/metrics`); const response = await fetch(`${config.apiUrl}/dashboard/stock/metrics`); if (!response.ok) { const text = await response.text(); @@ -111,7 +110,6 @@ export function StockMetrics() { throw new Error(`Failed to fetch stock metrics: ${response.status} ${response.statusText}`); } const data = await response.json(); - console.log('API Response:', data); return data; }, }); diff --git a/inventory/src/components/product-import/steps/MatchColumnsStep/MatchColumnsStep.tsx b/inventory/src/components/product-import/steps/MatchColumnsStep/MatchColumnsStep.tsx index 1213f6b..d332c29 100644 --- a/inventory/src/components/product-import/steps/MatchColumnsStep/MatchColumnsStep.tsx +++ b/inventory/src/components/product-import/steps/MatchColumnsStep/MatchColumnsStep.tsx @@ -1029,7 +1029,6 @@ export const MatchColumnsStep = React.memo(({ ); if (matchingOption) { - console.log(`Auto-matched "${entryValue}" to "${matchingOption.label}" (${matchingOption.value})`); return { ...option, value: matchingOption.value @@ -1094,7 +1093,6 @@ export const MatchColumnsStep = React.memo(({ ); if (matchingOption) { - console.log(`Auto-matched "${entryValue}" to "${matchingOption.label}" (${matchingOption.value})`); return { ...option, value: matchingOption.value @@ -1159,18 +1157,6 @@ export const MatchColumnsStep = React.memo(({ // Convert the fields to the expected type const fieldsArray = Array.isArray(fields) ? fields : [fields]; - // Log the fields for debugging - console.log("All fields:", fieldsArray); - - // Log validation rules for each field - fieldsArray.forEach(field => { - if (field.validations && Array.isArray(field.validations)) { - console.log(`Field ${field.key} validations:`, field.validations.map((v: any) => v.rule)); - } else { - console.log(`Field ${field.key} has no validations`); - } - }); - // Check for required fields based on validations const required = fieldsArray.filter(field => { // Check if the field has validations @@ -1183,12 +1169,10 @@ export const MatchColumnsStep = React.memo(({ (v: any) => v.rule === 'required' || v.required === true ); - console.log(`Field ${field.key} required:`, isRequired, field.validations); return isRequired; }); - console.log("Required fields:", required); return required; }, [fields]); diff --git a/inventory/src/components/product-import/steps/SelectHeaderStep/SelectHeaderStep.tsx b/inventory/src/components/product-import/steps/SelectHeaderStep/SelectHeaderStep.tsx index dfce26b..8b05e85 100644 --- a/inventory/src/components/product-import/steps/SelectHeaderStep/SelectHeaderStep.tsx +++ b/inventory/src/components/product-import/steps/SelectHeaderStep/SelectHeaderStep.tsx @@ -62,14 +62,8 @@ export const SelectHeaderStep = ({ data, onContinue, onBack }: SelectHeaderProps const [selectedRowIndex] = selectedRows; const selectedHeaderRow = localData[selectedRowIndex]; - // Debug: Log the selected header row - console.log("Selected header row:", selectedHeaderRow); - const normalizedHeaderRow = normalizeRowForComparison(selectedHeaderRow); - // Debug: Log the normalized header row - console.log("Normalized header row:", normalizedHeaderRow); - const selectedHeaderStr = JSON.stringify(Object.entries(normalizedHeaderRow).sort()); // Filter out empty rows, rows with single values (if we have multi-value rows), @@ -97,11 +91,6 @@ export const SelectHeaderStep = ({ data, onContinue, onBack }: SelectHeaderProps // Check if it's a duplicate (case-insensitive) const normalizedRow = normalizeRowForComparison(row); - // Debug: If this row might be a duplicate of the header, log it - if (index < 5 || index === selectedRowIndex + 1 || index === selectedRowIndex - 1) { - console.log(`Row ${index} normalized:`, normalizedRow); - } - const rowStr = JSON.stringify(Object.entries(normalizedRow).sort()); if (seen.has(rowStr)) { @@ -117,9 +106,6 @@ export const SelectHeaderStep = ({ data, onContinue, onBack }: SelectHeaderProps return true; }); - // Debug: Log removed rows - console.log("Removed rows:", removedRows); - // Only update if we actually removed any rows if (filteredRows.length < localData.length) { // Adjust the selected row index if needed @@ -127,9 +113,6 @@ export const SelectHeaderStep = ({ data, onContinue, onBack }: SelectHeaderProps JSON.stringify(Object.entries(normalizeRowForComparison(row)).sort()) === selectedHeaderStr ); - // Debug: Log the new selected index - console.log("New selected index:", newSelectedIndex); - setLocalData(filteredRows); setSelectedRows(new Set([newSelectedIndex])); diff --git a/inventory/src/components/product-import/steps/ValidationStepNew/components/ValidationContainer.tsx b/inventory/src/components/product-import/steps/ValidationStepNew/components/ValidationContainer.tsx index 110cdcd..750ac51 100644 --- a/inventory/src/components/product-import/steps/ValidationStepNew/components/ValidationContainer.tsx +++ b/inventory/src/components/product-import/steps/ValidationStepNew/components/ValidationContainer.tsx @@ -184,11 +184,9 @@ const ValidationContainer = ({ const fetchFieldOptions = useCallback(async () => { try { const response = await axios.get('/api/import/field-options'); - console.log('Field options from API:', response.data); // Check if suppliers are included in the response if (response.data && response.data.suppliers) { - console.log('Suppliers available:', response.data.suppliers.length); } else { console.warn('No suppliers found in field options response'); } @@ -282,24 +280,6 @@ const ValidationContainer = ({ try { const options = await fetchFieldOptions(); if (options && options.suppliers) { - console.log(`Loaded ${options.suppliers.length} suppliers for template form`); - - // Log if we can find a match for our supplier - if (templateData.supplier !== undefined) { - // Need to compare numeric values since supplier options have numeric values - const supplierMatch = options.suppliers.find((s: { value: string | number }) => - s.value === templateData.supplier || - Number(s.value) === Number(templateData.supplier) - ); - - console.log('Found supplier match:', supplierMatch ? 'Yes' : 'No', - 'For supplier value:', templateData.supplier, - 'Type:', typeof templateData.supplier); - - if (supplierMatch) { - console.log('Matched supplier:', supplierMatch.label); - } - } setIsTemplateFormOpen(true); } else { @@ -343,8 +323,7 @@ const ValidationContainer = ({ const selectedKeys = Object.entries(rowSelection) .filter(([_, selected]) => selected === true) .map(([key, _]) => key); - - console.log('Selected row keys for deletion:', selectedKeys); + if (selectedKeys.length === 0) { toast.error("No rows selected"); @@ -361,7 +340,6 @@ const ValidationContainer = ({ return index; }).filter(index => index !== -1); // Filter out any not found - console.log('Mapped row indices for deletion:', selectedIndices); if (selectedIndices.length === 0) { toast.error('Could not find selected rows'); @@ -567,7 +545,6 @@ const ValidationContainer = ({ const upcValue = (data[rowIndex] as any)?.upc || (data[rowIndex] as any)?.barcode; if (upcValue) { - console.log(`Validating UPC: rowIndex=${rowIndex}, supplier=${value}, upc=${upcValue}`); // Mark the item_number cell as being validated const cellKey = `${rowIndex}-item_number`; @@ -581,7 +558,6 @@ const ValidationContainer = ({ upcValidation.validateUpc(rowIndex, value.toString(), upcValue.toString()) .then(result => { if (result.success) { - console.log(`UPC validation successful for row ${rowIndex}`); upcValidation.applyItemNumbersToData(); // Mark for revalidation after item numbers are updated @@ -606,14 +582,12 @@ const ValidationContainer = ({ // Handle line change - clear subline and fetch sublines if (key === 'line' && value) { - console.log(`Line changed to ${value} for row ${rowIndex}, updating sublines`); // Clear any existing subline value setData(prevData => { const newData = [...prevData]; const idx = newData.findIndex(item => item.__index === rowId); if (idx >= 0) { - console.log(`Clearing subline values for row with ID ${rowId}`); newData[idx] = { ...newData[idx], subline: undefined @@ -628,9 +602,6 @@ const ValidationContainer = ({ if (rowId && value !== undefined) { const lineId = value.toString(); - // Force immediate fetch for better UX - console.log(`Immediately fetching sublines for line ${lineId} for row ${rowId}`); - // Set loading state first setValidatingCells(prev => { const newSet = new Set(prev); @@ -639,8 +610,7 @@ const ValidationContainer = ({ }); fetchSublines(rowId, lineId) - .then(sublines => { - console.log(`Successfully loaded ${sublines.length} sublines for line ${lineId}`); + .then(() => { }) .catch(err => { console.error(`Error fetching sublines for line ${lineId}:`, err); @@ -664,7 +634,6 @@ const ValidationContainer = ({ const supplier = (data[rowIndex] as any)?.supplier; if (supplier) { - console.log(`Validating UPC from UPC change: rowIndex=${rowIndex}, supplier=${supplier}, upc=${value}`); // Mark the item_number cell as being validated const cellKey = `${rowIndex}-item_number`; @@ -678,7 +647,6 @@ const ValidationContainer = ({ upcValidation.validateUpc(rowIndex, supplier.toString(), value.toString()) .then(result => { if (result.success) { - console.log(`UPC validation successful for row ${rowIndex}`); upcValidation.applyItemNumbersToData(); // Mark for revalidation after item numbers are updated @@ -818,7 +786,6 @@ const ValidationContainer = ({ // Run validations in parallel but limit the batch size if (validationsToRun.length > 0) { - console.log(`Running ${validationsToRun.length} UPC validations for copyDown`); // Mark all cells as validating validationsToRun.forEach(({ rowIndex }) => { @@ -877,7 +844,6 @@ const ValidationContainer = ({ // Add a small delay between batches to prevent UI freezing setTimeout(() => processBatch(endIdx), 100); } else { - console.log(`Completed all ${validationsToRun.length} UPC validations`); // Final application of all item numbers if not done by individual batches upcValidation.applyItemNumbersToData(updatedRowIds => { // Mark these rows for revalidation after a delay @@ -1112,8 +1078,6 @@ const ValidationContainer = ({ size="sm" className="h-8 shadow-xs" onClick={() => { - console.log('Delete/Discard button clicked'); - console.log('Row selection state:', rowSelection); deleteSelectedRows(); }} > diff --git a/inventory/vite.config.ts b/inventory/vite.config.ts index 06936c0..3cb22f3 100644 --- a/inventory/vite.config.ts +++ b/inventory/vite.config.ts @@ -23,7 +23,6 @@ export default defineConfig(({ mode }) => { await fs.ensureDir(path.dirname(targetPath)); await fs.remove(targetPath); await fs.copy(sourcePath, targetPath); - console.log('Build files copied successfully to server directory!'); } catch (error) { console.error('Error copying build files:', error); process.exit(1); @@ -105,7 +104,7 @@ export default defineConfig(({ mode }) => { rewrite: (path) => path.replace(/^\/api/, "/api"), configure: (proxy, _options) => { proxy.on("error", (err, req, res) => { - console.log("API proxy error:", err) + console.error("API proxy error:", err) res.writeHead(500, { "Content-Type": "application/json", }) @@ -113,20 +112,6 @@ export default defineConfig(({ mode }) => { JSON.stringify({ error: "Proxy Error", message: err.message }) ) }) - proxy.on("proxyReq", (proxyReq, req, _res) => { - console.log("Outgoing request to API:", { - method: req.method, - url: req.url, - headers: proxyReq.getHeaders(), - }) - }) - proxy.on("proxyRes", (proxyRes, req, _res) => { - console.log("API Proxy response:", { - statusCode: proxyRes.statusCode, - url: req.url, - headers: proxyRes.headers, - }) - }) }, }, "/dashboard-auth": { @@ -153,7 +138,7 @@ export default defineConfig(({ mode }) => { rewrite: (path) => path.replace(/^\/auth-inv/, "/auth-inv"), configure: (proxy, _options) => { proxy.on("error", (err, req, res) => { - console.log("Auth proxy error:", err) + console.error("Auth proxy error:", err) res.writeHead(500, { "Content-Type": "application/json", }) @@ -161,20 +146,6 @@ export default defineConfig(({ mode }) => { JSON.stringify({ error: "Proxy Error", message: err.message }) ) }) - proxy.on("proxyReq", (proxyReq, req, _res) => { - console.log("Outgoing request to Auth:", { - method: req.method, - url: req.url, - headers: proxyReq.getHeaders(), - }) - }) - proxy.on("proxyRes", (proxyRes, req, _res) => { - console.log("Auth Proxy response:", { - statusCode: proxyRes.statusCode, - url: req.url, - headers: proxyRes.headers, - }) - }) }, }, "/chat-api": { @@ -188,7 +159,7 @@ export default defineConfig(({ mode }) => { rewrite: (path) => path, configure: (proxy, _options) => { proxy.on("error", (err, req, res) => { - console.log("Chat API proxy error:", err) + console.error("Chat API proxy error:", err) res.writeHead(500, { "Content-Type": "application/json", }) @@ -196,20 +167,6 @@ export default defineConfig(({ mode }) => { JSON.stringify({ error: "Proxy Error", message: err.message }) ) }) - proxy.on("proxyReq", (proxyReq, req, _res) => { - console.log("Outgoing request to Chat API:", { - method: req.method, - url: req.url, - headers: proxyReq.getHeaders(), - }) - }) - proxy.on("proxyRes", (proxyRes, req, _res) => { - console.log("Chat API Proxy response:", { - statusCode: proxyRes.statusCode, - url: req.url, - headers: proxyRes.headers, - }) - }) }, }, "/uploads": {