mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 09:11:13 -05:00
Fix false positives in change detection
This commit is contained in:
@@ -1,6 +1,18 @@
|
|||||||
import type { SubmissionItemData } from '@/types/submissions';
|
import type { SubmissionItemData } from '@/types/submissions';
|
||||||
|
import type {
|
||||||
|
ParkSubmissionData,
|
||||||
|
RideSubmissionData,
|
||||||
|
CompanySubmissionData,
|
||||||
|
RideModelSubmissionData
|
||||||
|
} from '@/types/submission-data';
|
||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
|
|
||||||
|
type SubmissionDataTypes =
|
||||||
|
| ParkSubmissionData
|
||||||
|
| RideSubmissionData
|
||||||
|
| CompanySubmissionData
|
||||||
|
| RideModelSubmissionData;
|
||||||
|
|
||||||
export interface FieldChange {
|
export interface FieldChange {
|
||||||
field: string;
|
field: string;
|
||||||
oldValue: any;
|
oldValue: any;
|
||||||
@@ -411,30 +423,70 @@ function shouldTrackField(key: string): boolean {
|
|||||||
'review_count',
|
'review_count',
|
||||||
'coaster_count',
|
'coaster_count',
|
||||||
'average_rating',
|
'average_rating',
|
||||||
|
|
||||||
|
// Analytics fields (auto-updated by system)
|
||||||
|
'view_count_7d',
|
||||||
|
'view_count_30d',
|
||||||
|
'view_count_all',
|
||||||
];
|
];
|
||||||
|
|
||||||
return !excludedFields.includes(key);
|
return !excludedFields.includes(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deep equality check for values
|
* Normalizes values for consistent comparison
|
||||||
|
* Handles enum-like strings (snake_case) by ensuring lowercase
|
||||||
|
*/
|
||||||
|
function normalizeForComparison(value: any): any {
|
||||||
|
// Null/undefined pass through
|
||||||
|
if (value == null) return value;
|
||||||
|
|
||||||
|
// Normalize enum-like strings to lowercase for comparison
|
||||||
|
// Matches patterns like: "operating", "Operating", "amusement_park", "Amusement_Park"
|
||||||
|
if (typeof value === 'string' && /^[a-zA-Z_]+$/.test(value)) {
|
||||||
|
return value.toLowerCase().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively normalize arrays
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
return value.map(normalizeForComparison);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively normalize objects (but not Date objects)
|
||||||
|
if (typeof value === 'object' && !(value instanceof Date)) {
|
||||||
|
const normalized: Record<string, any> = {};
|
||||||
|
for (const [key, val] of Object.entries(value)) {
|
||||||
|
normalized[key] = normalizeForComparison(val);
|
||||||
|
}
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deep equality check for values with normalization
|
||||||
*/
|
*/
|
||||||
function isEqual(a: any, b: any): boolean {
|
function isEqual(a: any, b: any): boolean {
|
||||||
if (a === b) return true;
|
// Normalize both values before comparison
|
||||||
if (a == null || b == null) return a === b;
|
const normalizedA = normalizeForComparison(a);
|
||||||
if (typeof a !== typeof b) return false;
|
const normalizedB = normalizeForComparison(b);
|
||||||
|
|
||||||
if (typeof a === 'object') {
|
if (normalizedA === normalizedB) return true;
|
||||||
if (Array.isArray(a) && Array.isArray(b)) {
|
if (normalizedA == null || normalizedB == null) return normalizedA === normalizedB;
|
||||||
if (a.length !== b.length) return false;
|
if (typeof normalizedA !== typeof normalizedB) return false;
|
||||||
return a.every((item, i) => isEqual(item, b[i]));
|
|
||||||
|
if (typeof normalizedA === 'object') {
|
||||||
|
if (Array.isArray(normalizedA) && Array.isArray(normalizedB)) {
|
||||||
|
if (normalizedA.length !== normalizedB.length) return false;
|
||||||
|
return normalizedA.every((item, i) => isEqual(item, normalizedB[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
const keysA = Object.keys(a);
|
const keysA = Object.keys(normalizedA);
|
||||||
const keysB = Object.keys(b);
|
const keysB = Object.keys(normalizedB);
|
||||||
if (keysA.length !== keysB.length) return false;
|
if (keysA.length !== keysB.length) return false;
|
||||||
|
|
||||||
return keysA.every(key => isEqual(a[key], b[key]));
|
return keysA.every(key => isEqual(normalizedA[key], normalizedB[key]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user