mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-23 11:11:14 -05:00
208 lines
5.0 KiB
TypeScript
208 lines
5.0 KiB
TypeScript
import { supabase } from '@/integrations/supabase/client';
|
|
import { toast } from '@/hooks/use-toast';
|
|
|
|
export type EntityType = 'park' | 'ride' | 'company' | 'ride_model';
|
|
export type ChangeType = 'created' | 'updated' | 'deleted' | 'restored' | 'archived';
|
|
|
|
/**
|
|
* Get the table name for a given entity type
|
|
*/
|
|
export function getEntityTableName(entityType: EntityType): string {
|
|
const tableMap: Record<EntityType, string> = {
|
|
park: 'parks',
|
|
ride: 'rides',
|
|
company: 'companies',
|
|
ride_model: 'ride_models',
|
|
};
|
|
return tableMap[entityType];
|
|
}
|
|
|
|
/**
|
|
* Capture the current state of an entity
|
|
*/
|
|
export async function captureCurrentState(
|
|
entityType: EntityType,
|
|
entityId: string
|
|
): Promise<Record<string, any> | null> {
|
|
const tableName = getEntityTableName(entityType);
|
|
|
|
const { data, error } = await supabase
|
|
.from(tableName as any)
|
|
.select('*')
|
|
.eq('id', entityId)
|
|
.single();
|
|
|
|
if (error) {
|
|
console.error('Error capturing entity state:', error);
|
|
return null;
|
|
}
|
|
|
|
return data as Record<string, any>;
|
|
}
|
|
|
|
/**
|
|
* Create a new entity version with proper error handling
|
|
*/
|
|
export async function createEntityVersion(params: {
|
|
entityType: EntityType;
|
|
entityId: string;
|
|
versionData: Record<string, any>;
|
|
changedBy: string;
|
|
changeReason?: string;
|
|
submissionId?: string;
|
|
changeType?: ChangeType;
|
|
}): Promise<string | null> {
|
|
const {
|
|
entityType,
|
|
entityId,
|
|
versionData,
|
|
changedBy,
|
|
changeReason,
|
|
submissionId,
|
|
changeType = 'updated',
|
|
} = params;
|
|
|
|
try {
|
|
const { data, error } = await supabase.rpc('create_entity_version', {
|
|
p_entity_type: entityType,
|
|
p_entity_id: entityId,
|
|
p_version_data: versionData,
|
|
p_changed_by: changedBy,
|
|
p_change_reason: changeReason || null,
|
|
p_submission_id: submissionId || null,
|
|
p_change_type: changeType,
|
|
});
|
|
|
|
if (error) {
|
|
console.error('Error creating entity version:', error);
|
|
toast({
|
|
title: 'Version Creation Failed',
|
|
description: error.message,
|
|
variant: 'destructive',
|
|
});
|
|
return null;
|
|
}
|
|
|
|
return data;
|
|
} catch (err) {
|
|
console.error('Unexpected error creating entity version:', err);
|
|
toast({
|
|
title: 'Version Creation Failed',
|
|
description: 'An unexpected error occurred',
|
|
variant: 'destructive',
|
|
});
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create entity version with audit log entry
|
|
*/
|
|
export async function createEntityVersionWithAudit(
|
|
params: {
|
|
entityType: EntityType;
|
|
entityId: string;
|
|
versionData: Record<string, any>;
|
|
changedBy: string;
|
|
changeReason?: string;
|
|
submissionId?: string;
|
|
changeType?: ChangeType;
|
|
},
|
|
auditDetails?: Record<string, any>
|
|
): Promise<string | null> {
|
|
const versionId = await createEntityVersion(params);
|
|
|
|
if (versionId && auditDetails) {
|
|
// Log to admin audit log
|
|
const { error: auditError } = await supabase.rpc('log_admin_action', {
|
|
_admin_user_id: params.changedBy,
|
|
_target_user_id: params.changedBy, // Or entity owner if available
|
|
_action: `version_${params.changeType || 'updated'}`,
|
|
_details: {
|
|
version_id: versionId,
|
|
entity_type: params.entityType,
|
|
entity_id: params.entityId,
|
|
submission_id: params.submissionId,
|
|
...auditDetails,
|
|
},
|
|
});
|
|
|
|
if (auditError) {
|
|
console.warn('Failed to create audit log entry:', auditError);
|
|
}
|
|
}
|
|
|
|
return versionId;
|
|
}
|
|
|
|
/**
|
|
* Rollback an entity to a previous version
|
|
*/
|
|
export async function rollbackToVersion(
|
|
entityType: EntityType,
|
|
entityId: string,
|
|
targetVersionId: string,
|
|
userId: string,
|
|
reason: string
|
|
): Promise<boolean> {
|
|
try {
|
|
const { data, error } = await supabase.rpc('rollback_to_version', {
|
|
p_entity_type: entityType,
|
|
p_entity_id: entityId,
|
|
p_target_version_id: targetVersionId,
|
|
p_changed_by: userId,
|
|
p_reason: reason,
|
|
});
|
|
|
|
if (error) {
|
|
console.error('Error rolling back to version:', error);
|
|
toast({
|
|
title: 'Rollback Failed',
|
|
description: error.message,
|
|
variant: 'destructive',
|
|
});
|
|
return false;
|
|
}
|
|
|
|
toast({
|
|
title: 'Rollback Successful',
|
|
description: 'Entity has been restored to the selected version',
|
|
});
|
|
|
|
return true;
|
|
} catch (err) {
|
|
console.error('Unexpected error during rollback:', err);
|
|
toast({
|
|
title: 'Rollback Failed',
|
|
description: 'An unexpected error occurred',
|
|
variant: 'destructive',
|
|
});
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Compare two versions and get the diff
|
|
*/
|
|
export async function compareVersions(
|
|
fromVersionId: string,
|
|
toVersionId: string
|
|
): Promise<Record<string, any> | null> {
|
|
try {
|
|
const { data, error } = await supabase.rpc('compare_versions', {
|
|
p_from_version_id: fromVersionId,
|
|
p_to_version_id: toVersionId,
|
|
});
|
|
|
|
if (error) {
|
|
console.error('Error comparing versions:', error);
|
|
return null;
|
|
}
|
|
|
|
return data as Record<string, any>;
|
|
} catch (err) {
|
|
console.error('Unexpected error comparing versions:', err);
|
|
return null;
|
|
}
|
|
}
|