mirror of
https://github.com/christianvidalwolf-prog/Craze-Data-check.git
synced 2026-08-03 14:05:25 +02:00
fix(history): paginate all records, number oldest=1 newest=N, display newest first
This commit is contained in:
+69
-25
@@ -116,6 +116,28 @@ export interface HistoryEntry {
|
||||
changed_at: string;
|
||||
}
|
||||
|
||||
function normalizeHistoryValue(value: any): any {
|
||||
if (value === undefined || value === null || value === '') return null;
|
||||
return value;
|
||||
}
|
||||
|
||||
function valuesEqual(a: any, b: any): boolean {
|
||||
return normalizeHistoryValue(a) === normalizeHistoryValue(b);
|
||||
}
|
||||
|
||||
function getChangedIndices(oldData: ExcelRow = [], newData: ExcelRow = []): number[] {
|
||||
const maxLen = Math.max(oldData.length, newData.length);
|
||||
const changed: number[] = [];
|
||||
|
||||
for (let i = 0; i < maxLen; i++) {
|
||||
if (!valuesEqual(oldData[i], newData[i])) {
|
||||
changed.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
export async function saveHistoryEntry(
|
||||
productId: string,
|
||||
articleName: string,
|
||||
@@ -160,25 +182,34 @@ export async function saveHistoryEntry(
|
||||
|
||||
export async function getHistory(): Promise<HistoryEntry[]> {
|
||||
try {
|
||||
const response = await safeFetch(
|
||||
`${SUPABASE_URL}/rest/v1/products_history?select=*&order=changed_at.desc&limit=500`,
|
||||
{ cache: 'no-store' }
|
||||
);
|
||||
const PAGE_SIZE = 1000;
|
||||
const allRows: HistoryEntry[] = [];
|
||||
for (let page = 0; page < 20; page++) {
|
||||
const offset = page * PAGE_SIZE;
|
||||
const response = await safeFetch(
|
||||
`${SUPABASE_URL}/rest/v1/products_history?select=*&order=changed_at.asc&limit=${PAGE_SIZE}&offset=${offset}`,
|
||||
{ cache: 'no-store' }
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const errText = await response.text();
|
||||
console.error('[getHistory] Error:', response.status, errText.substring(0, 200));
|
||||
return [{
|
||||
id: 'ERROR',
|
||||
product_id: 'ERROR',
|
||||
article_name: `Failed: ${response.status} ${errText.substring(0, 200)}`,
|
||||
old_data: [],
|
||||
new_data: [],
|
||||
changed_at: new Date().toISOString(),
|
||||
changed_by: 'system'
|
||||
}];
|
||||
if (!response.ok) {
|
||||
const errText = await response.text();
|
||||
console.error('[getHistory] Error:', response.status, errText.substring(0, 200));
|
||||
return [{
|
||||
id: 'ERROR',
|
||||
product_id: 'ERROR',
|
||||
article_name: `Failed: ${response.status} ${errText.substring(0, 200)}`,
|
||||
old_data: [],
|
||||
new_data: [],
|
||||
changed_at: new Date().toISOString(),
|
||||
changed_by: 'system'
|
||||
}];
|
||||
}
|
||||
const batch: HistoryEntry[] = await response.json();
|
||||
allRows.push(...batch);
|
||||
if (batch.length < PAGE_SIZE) break;
|
||||
}
|
||||
return await response.json();
|
||||
// Return oldest-first so index+1 = natural chronological number
|
||||
return allRows;
|
||||
} catch (error: any) {
|
||||
console.error('[getHistory] Exception:', error.message);
|
||||
return [{
|
||||
@@ -196,7 +227,7 @@ export async function getHistory(): Promise<HistoryEntry[]> {
|
||||
export async function getHistoryDataForMerge(): Promise<Record<string, ExcelRow>> {
|
||||
try {
|
||||
const response = await safeFetch(
|
||||
`${SUPABASE_URL}/rest/v1/products_history?select=product_id,new_data&order=changed_at.desc`,
|
||||
`${SUPABASE_URL}/rest/v1/products_history?select=product_id,old_data,new_data,changed_at,id`,
|
||||
{ cache: 'no-store' }
|
||||
);
|
||||
|
||||
@@ -204,17 +235,30 @@ export async function getHistoryDataForMerge(): Promise<Record<string, ExcelRow>
|
||||
console.error('[getHistoryDataForMerge] Error:', response.status);
|
||||
return {};
|
||||
}
|
||||
const entries: Array<{ product_id: string; new_data: ExcelRow }> = await response.json();
|
||||
|
||||
const entries: HistoryEntry[] = await response.json();
|
||||
entries.sort((a, b) => {
|
||||
const timeDelta = new Date(a.changed_at).getTime() - new Date(b.changed_at).getTime();
|
||||
if (timeDelta !== 0) return timeDelta;
|
||||
return String(a.id || '').localeCompare(String(b.id || ''));
|
||||
});
|
||||
|
||||
const result: Record<string, ExcelRow> = {};
|
||||
const seen = new Set<string>();
|
||||
|
||||
for (const entry of entries) {
|
||||
if (seen.has(entry.product_id)) continue;
|
||||
seen.add(entry.product_id);
|
||||
if (entry.new_data && entry.new_data.length > 0) {
|
||||
result[entry.product_id] = entry.new_data;
|
||||
if (!entry.product_id) continue;
|
||||
|
||||
if (!result[entry.product_id]) {
|
||||
result[entry.product_id] = [];
|
||||
}
|
||||
|
||||
const target = result[entry.product_id];
|
||||
const changedIndices = getChangedIndices(entry.old_data || [], entry.new_data || []);
|
||||
|
||||
for (const idx of changedIndices) {
|
||||
target[idx] = entry.new_data?.[idx];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (error: any) {
|
||||
console.error('[getHistoryDataForMerge] Exception:', error.message);
|
||||
|
||||
Reference in New Issue
Block a user