mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 12:51:14 -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 {
|
||||
ParkSubmissionData,
|
||||
RideSubmissionData,
|
||||
CompanySubmissionData,
|
||||
RideModelSubmissionData
|
||||
} from '@/types/submission-data';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
|
||||
type SubmissionDataTypes =
|
||||
| ParkSubmissionData
|
||||
| RideSubmissionData
|
||||
| CompanySubmissionData
|
||||
| RideModelSubmissionData;
|
||||
|
||||
export interface FieldChange {
|
||||
field: string;
|
||||
oldValue: any;
|
||||
@@ -411,30 +423,70 @@ function shouldTrackField(key: string): boolean {
|
||||
'review_count',
|
||||
'coaster_count',
|
||||
'average_rating',
|
||||
|
||||
// Analytics fields (auto-updated by system)
|
||||
'view_count_7d',
|
||||
'view_count_30d',
|
||||
'view_count_all',
|
||||
];
|
||||
|
||||
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 {
|
||||
if (a === b) return true;
|
||||
if (a == null || b == null) return a === b;
|
||||
if (typeof a !== typeof b) return false;
|
||||
// Normalize both values before comparison
|
||||
const normalizedA = normalizeForComparison(a);
|
||||
const normalizedB = normalizeForComparison(b);
|
||||
|
||||
if (typeof a === 'object') {
|
||||
if (Array.isArray(a) && Array.isArray(b)) {
|
||||
if (a.length !== b.length) return false;
|
||||
return a.every((item, i) => isEqual(item, b[i]));
|
||||
if (normalizedA === normalizedB) return true;
|
||||
if (normalizedA == null || normalizedB == null) return normalizedA === normalizedB;
|
||||
if (typeof normalizedA !== typeof normalizedB) return false;
|
||||
|
||||
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 keysB = Object.keys(b);
|
||||
const keysA = Object.keys(normalizedA);
|
||||
const keysB = Object.keys(normalizedB);
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user