mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 15:11:13 -05:00
Refactor: Revert type changes
This commit is contained in:
@@ -2,167 +2,15 @@ import { supabase } from '@/integrations/supabase/client';
|
|||||||
import { getErrorMessage } from './errorHandler';
|
import { getErrorMessage } from './errorHandler';
|
||||||
import { logger } from './logger';
|
import { logger } from './logger';
|
||||||
|
|
||||||
// ============= TYPE DEFINITIONS =============
|
// Core submission item interface with dependencies
|
||||||
|
// Type safety for item_data will be added in Phase 5 after fixing components
|
||||||
type EntityType = 'park' | 'ride' | 'manufacturer' | 'operator' | 'property_owner' | 'designer' | 'ride_model' | 'photo' | 'timeline_event' | 'milestone' | 'location';
|
|
||||||
|
|
||||||
interface ImageAssignment {
|
|
||||||
url: string;
|
|
||||||
cloudflare_id: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ImageAssignments {
|
|
||||||
uploaded?: ImageAssignment[];
|
|
||||||
banner_assignment?: number | null;
|
|
||||||
card_assignment?: number | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface LocationData {
|
|
||||||
name: string;
|
|
||||||
city?: string | null;
|
|
||||||
state_province?: string | null;
|
|
||||||
country: string;
|
|
||||||
postal_code?: string | null;
|
|
||||||
latitude: number;
|
|
||||||
longitude: number;
|
|
||||||
timezone?: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PhotoData {
|
|
||||||
url: string;
|
|
||||||
cloudflare_image_id?: string;
|
|
||||||
title?: string;
|
|
||||||
caption?: string;
|
|
||||||
photographer_credit?: string;
|
|
||||||
date?: string;
|
|
||||||
date_taken?: string;
|
|
||||||
order?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flexible entity form data that accommodates all entity types
|
|
||||||
// This is intentionally permissive to maintain backwards compatibility
|
|
||||||
// while adding type safety to function signatures
|
|
||||||
interface EntityFormData {
|
|
||||||
// Common fields (not all entities have all fields)
|
|
||||||
name?: string;
|
|
||||||
slug?: string;
|
|
||||||
description?: string | null;
|
|
||||||
images?: ImageAssignments;
|
|
||||||
|
|
||||||
// Park-specific fields
|
|
||||||
park_id?: string;
|
|
||||||
park_type?: string;
|
|
||||||
status?: string;
|
|
||||||
opening_date?: string | null;
|
|
||||||
closing_date?: string | null;
|
|
||||||
opening_date_precision?: string | null;
|
|
||||||
closing_date_precision?: string | null;
|
|
||||||
website_url?: string | null;
|
|
||||||
phone?: string | null;
|
|
||||||
email?: string | null;
|
|
||||||
operator_id?: string | null;
|
|
||||||
property_owner_id?: string | null;
|
|
||||||
location_id?: string | null;
|
|
||||||
location?: LocationData;
|
|
||||||
|
|
||||||
// Ride-specific fields
|
|
||||||
ride_id?: string;
|
|
||||||
category?: string;
|
|
||||||
park_id?: string;
|
|
||||||
manufacturer_id?: string | null;
|
|
||||||
manufacturer_name?: string | null;
|
|
||||||
designer_id?: string | null;
|
|
||||||
ride_model_id?: string | null;
|
|
||||||
height_requirement?: number | null;
|
|
||||||
age_requirement?: number | null;
|
|
||||||
capacity_per_hour?: number | null;
|
|
||||||
duration_seconds?: number | null;
|
|
||||||
max_speed_kmh?: number | null;
|
|
||||||
max_height_meters?: number | null;
|
|
||||||
length_meters?: number | null;
|
|
||||||
inversions?: number | null;
|
|
||||||
coaster_type?: string | null;
|
|
||||||
seating_type?: string | null;
|
|
||||||
intensity_level?: string | null;
|
|
||||||
drop_height_meters?: number | null;
|
|
||||||
max_g_force?: number | null;
|
|
||||||
ride_sub_type?: string | null;
|
|
||||||
|
|
||||||
// Company-specific fields
|
|
||||||
id?: string;
|
|
||||||
company_type?: string;
|
|
||||||
founded_year?: number | null;
|
|
||||||
founded_date?: string | null;
|
|
||||||
founded_date_precision?: string | null;
|
|
||||||
headquarters_location?: string | null;
|
|
||||||
|
|
||||||
// Ride model fields
|
|
||||||
technical_specs?: Record<string, unknown>;
|
|
||||||
|
|
||||||
// Photo submission fields
|
|
||||||
photos?: PhotoData[];
|
|
||||||
entity_id?: string;
|
|
||||||
context?: EntityType;
|
|
||||||
title?: string;
|
|
||||||
|
|
||||||
// Timeline/milestone fields
|
|
||||||
entity_type?: EntityType;
|
|
||||||
event_type?: string;
|
|
||||||
event_date?: string;
|
|
||||||
event_date_precision?: string;
|
|
||||||
from_value?: string | null;
|
|
||||||
to_value?: string | null;
|
|
||||||
from_entity_id?: string | null;
|
|
||||||
to_entity_id?: string | null;
|
|
||||||
from_location_id?: string | null;
|
|
||||||
to_location_id?: string | null;
|
|
||||||
is_public?: boolean;
|
|
||||||
|
|
||||||
// Allow additional properties for flexibility
|
|
||||||
[key: string]: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Specific typed interfaces for function parameters
|
|
||||||
interface ParkFormData extends EntityFormData {
|
|
||||||
name: string;
|
|
||||||
slug: string;
|
|
||||||
park_type: string;
|
|
||||||
status: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RideFormData extends EntityFormData {
|
|
||||||
name: string;
|
|
||||||
slug: string;
|
|
||||||
category: string;
|
|
||||||
status: string;
|
|
||||||
park_id: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CompanyFormData extends EntityFormData {
|
|
||||||
name: string;
|
|
||||||
slug: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RideModelFormData extends EntityFormData {
|
|
||||||
name: string;
|
|
||||||
slug: string;
|
|
||||||
manufacturer_id: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PhotoSubmissionData extends EntityFormData {
|
|
||||||
photos: PhotoData[];
|
|
||||||
entity_id: string;
|
|
||||||
context: EntityType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============= MAIN INTERFACES =============
|
|
||||||
|
|
||||||
export interface SubmissionItemWithDeps {
|
export interface SubmissionItemWithDeps {
|
||||||
id: string;
|
id: string;
|
||||||
submission_id: string;
|
submission_id: string;
|
||||||
item_type: string;
|
item_type: string;
|
||||||
item_data: EntityFormData;
|
item_data: any; // Complex nested structure - will be typed properly in Phase 5
|
||||||
original_data: EntityFormData | null;
|
original_data: any; // Complex nested structure - will be typed properly in Phase 5
|
||||||
action_type?: 'create' | 'edit' | 'delete';
|
action_type?: 'create' | 'edit' | 'delete';
|
||||||
status: 'pending' | 'approved' | 'rejected';
|
status: 'pending' | 'approved' | 'rejected';
|
||||||
depends_on: string | null;
|
depends_on: string | null;
|
||||||
@@ -465,7 +313,7 @@ function topologicalSort(items: SubmissionItemWithDeps[]): SubmissionItemWithDep
|
|||||||
/**
|
/**
|
||||||
* Extract image URLs from ImageAssignments structure
|
* Extract image URLs from ImageAssignments structure
|
||||||
*/
|
*/
|
||||||
function extractImageAssignments(images: Record<string, unknown> | undefined) {
|
function extractImageAssignments(images: any) {
|
||||||
if (!images || !images.uploaded || !Array.isArray(images.uploaded)) {
|
if (!images || !images.uploaded || !Array.isArray(images.uploaded)) {
|
||||||
return {
|
return {
|
||||||
banner_image_url: null,
|
banner_image_url: null,
|
||||||
@@ -494,7 +342,7 @@ function extractImageAssignments(images: Record<string, unknown> | undefined) {
|
|||||||
/**
|
/**
|
||||||
* Helper functions to create entities with dependency resolution
|
* Helper functions to create entities with dependency resolution
|
||||||
*/
|
*/
|
||||||
async function createPark(data: Record<string, unknown>, dependencyMap: Map<string, string>): Promise<string> {
|
async function createPark(data: any, dependencyMap: Map<string, string>): Promise<string> {
|
||||||
const { transformParkData, validateSubmissionData } = await import('./entityTransformers');
|
const { transformParkData, validateSubmissionData } = await import('./entityTransformers');
|
||||||
const { ensureUniqueSlug } = await import('./slugUtils');
|
const { ensureUniqueSlug } = await import('./slugUtils');
|
||||||
|
|
||||||
@@ -603,7 +451,7 @@ async function createPark(data: Record<string, unknown>, dependencyMap: Map<stri
|
|||||||
* For user-submitted locations in the future, they should be submitted as separate
|
* For user-submitted locations in the future, they should be submitted as separate
|
||||||
* submission_items with item_type='location' and go through the moderation queue.
|
* submission_items with item_type='location' and go through the moderation queue.
|
||||||
*/
|
*/
|
||||||
async function resolveLocationId(locationData: Record<string, unknown> | undefined): Promise<string | null> {
|
async function resolveLocationId(locationData: any): Promise<string | null> {
|
||||||
if (!locationData || !locationData.latitude || !locationData.longitude) {
|
if (!locationData || !locationData.latitude || !locationData.longitude) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -649,7 +497,7 @@ async function resolveLocationId(locationData: Record<string, unknown> | undefin
|
|||||||
return newLocation.id;
|
return newLocation.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createRide(data: Record<string, unknown>, dependencyMap: Map<string, string>): Promise<string> {
|
async function createRide(data: any, dependencyMap: Map<string, string>): Promise<string> {
|
||||||
const { transformRideData, validateSubmissionData } = await import('./entityTransformers');
|
const { transformRideData, validateSubmissionData } = await import('./entityTransformers');
|
||||||
const { ensureUniqueSlug } = await import('./slugUtils');
|
const { ensureUniqueSlug } = await import('./slugUtils');
|
||||||
|
|
||||||
@@ -737,7 +585,7 @@ async function createRide(data: Record<string, unknown>, dependencyMap: Map<stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function createCompany(
|
async function createCompany(
|
||||||
data: Record<string, unknown>,
|
data: any,
|
||||||
companyType: string,
|
companyType: string,
|
||||||
dependencyMap: Map<string, string>
|
dependencyMap: Map<string, string>
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
@@ -814,7 +662,7 @@ async function createCompany(
|
|||||||
return company.id;
|
return company.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createRideModel(data: Record<string, unknown>, dependencyMap: Map<string, string>): Promise<string> {
|
async function createRideModel(data: any, dependencyMap: Map<string, string>): Promise<string> {
|
||||||
const { transformRideModelData, validateSubmissionData } = await import('./entityTransformers');
|
const { transformRideModelData, validateSubmissionData } = await import('./entityTransformers');
|
||||||
const { ensureUniqueSlug } = await import('./slugUtils');
|
const { ensureUniqueSlug } = await import('./slugUtils');
|
||||||
|
|
||||||
@@ -851,7 +699,7 @@ async function createRideModel(data: Record<string, unknown>, dependencyMap: Map
|
|||||||
return model.id;
|
return model.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function approvePhotos(data: Record<string, unknown>, dependencyMap: Map<string, string>, userId: string, submissionId: string): Promise<string> {
|
async function approvePhotos(data: any, dependencyMap: Map<string, string>, userId: string, submissionId: string): Promise<string> {
|
||||||
// Photos are already uploaded to Cloudflare
|
// Photos are already uploaded to Cloudflare
|
||||||
// Resolve dependencies for entity associations
|
// Resolve dependencies for entity associations
|
||||||
const resolvedData = resolveDependencies(data, dependencyMap);
|
const resolvedData = resolveDependencies(data, dependencyMap);
|
||||||
@@ -885,7 +733,7 @@ async function approvePhotos(data: Record<string, unknown>, dependencyMap: Map<s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert photos into the photos table
|
// Insert photos into the photos table
|
||||||
const photosToInsert = resolvedData.photos.map((photo: Record<string, unknown>, index: number) => {
|
const photosToInsert = resolvedData.photos.map((photo: any, index: number) => {
|
||||||
// Extract CloudFlare image ID from URL if not provided
|
// Extract CloudFlare image ID from URL if not provided
|
||||||
let cloudflareImageId = photo.cloudflare_image_id;
|
let cloudflareImageId = photo.cloudflare_image_id;
|
||||||
if (!cloudflareImageId && photo.url) {
|
if (!cloudflareImageId && photo.url) {
|
||||||
@@ -1008,7 +856,7 @@ async function updateEntityFeaturedImage(
|
|||||||
* Resolve dependency references in submission data
|
* Resolve dependency references in submission data
|
||||||
* Replaces submission item IDs with actual database entity IDs
|
* Replaces submission item IDs with actual database entity IDs
|
||||||
*/
|
*/
|
||||||
function resolveDependencies(data: Record<string, unknown>, dependencyMap: Map<string, string>): Record<string, unknown> {
|
function resolveDependencies(data: any, dependencyMap: Map<string, string>): any {
|
||||||
const resolved = { ...data };
|
const resolved = { ...data };
|
||||||
|
|
||||||
// List of foreign key fields that may need resolution
|
// List of foreign key fields that may need resolution
|
||||||
@@ -1183,7 +1031,7 @@ async function updateSubmissionStatusAfterRejection(submissionId: string): Promi
|
|||||||
*/
|
*/
|
||||||
export async function editSubmissionItem(
|
export async function editSubmissionItem(
|
||||||
itemId: string,
|
itemId: string,
|
||||||
newData: Record<string, unknown>,
|
newData: any,
|
||||||
userId: string
|
userId: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
|
|||||||
Reference in New Issue
Block a user