|
|
|
|
@@ -185,24 +185,25 @@ export async function approveSubmissionItems(
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Create the entity based on type with dependency resolution
|
|
|
|
|
// PASS sortedItems to enable correct index-based resolution
|
|
|
|
|
switch (item.item_type) {
|
|
|
|
|
case 'park':
|
|
|
|
|
entityId = await createPark(item.item_data, dependencyMap);
|
|
|
|
|
entityId = await createPark(item.item_data, dependencyMap, sortedItems);
|
|
|
|
|
break;
|
|
|
|
|
case 'ride':
|
|
|
|
|
entityId = await createRide(item.item_data, dependencyMap);
|
|
|
|
|
entityId = await createRide(item.item_data, dependencyMap, sortedItems);
|
|
|
|
|
break;
|
|
|
|
|
case 'manufacturer':
|
|
|
|
|
case 'operator':
|
|
|
|
|
case 'property_owner':
|
|
|
|
|
case 'designer':
|
|
|
|
|
entityId = await createCompany(item.item_data, item.item_type, dependencyMap);
|
|
|
|
|
entityId = await createCompany(item.item_data, item.item_type, dependencyMap, sortedItems);
|
|
|
|
|
break;
|
|
|
|
|
case 'ride_model':
|
|
|
|
|
entityId = await createRideModel(item.item_data, dependencyMap);
|
|
|
|
|
entityId = await createRideModel(item.item_data, dependencyMap, sortedItems);
|
|
|
|
|
break;
|
|
|
|
|
case 'photo':
|
|
|
|
|
entityId = await approvePhotos(item.item_data, dependencyMap, userId, item.submission_id);
|
|
|
|
|
entityId = await approvePhotos(item.item_data, dependencyMap, userId, item.submission_id, sortedItems);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -343,7 +344,7 @@ function extractImageAssignments(images: any) {
|
|
|
|
|
/**
|
|
|
|
|
* Helper functions to create entities with dependency resolution
|
|
|
|
|
*/
|
|
|
|
|
async function createPark(data: any, dependencyMap: Map<string, string>): Promise<string> {
|
|
|
|
|
async function createPark(data: any, dependencyMap: Map<string, string>, sortedItems: SubmissionItemWithDeps[]): Promise<string> {
|
|
|
|
|
const { transformParkData, validateSubmissionData } = await import('./entityTransformers');
|
|
|
|
|
const { ensureUniqueSlug } = await import('./slugUtils');
|
|
|
|
|
|
|
|
|
|
@@ -352,7 +353,7 @@ async function createPark(data: any, dependencyMap: Map<string, string>): Promis
|
|
|
|
|
|
|
|
|
|
if (isEdit) {
|
|
|
|
|
// Handle park edit
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap);
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap, sortedItems);
|
|
|
|
|
|
|
|
|
|
// Resolve location_id if location data is provided
|
|
|
|
|
let locationId = resolvedData.location_id;
|
|
|
|
|
@@ -401,7 +402,7 @@ async function createPark(data: any, dependencyMap: Map<string, string>): Promis
|
|
|
|
|
|
|
|
|
|
// Handle park creation
|
|
|
|
|
validateSubmissionData(data, 'Park');
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap);
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap, sortedItems);
|
|
|
|
|
|
|
|
|
|
// Resolve location_id if location data is provided
|
|
|
|
|
let locationId = resolvedData.location_id;
|
|
|
|
|
@@ -498,7 +499,7 @@ async function resolveLocationId(locationData: any): Promise<string | null> {
|
|
|
|
|
return newLocation.id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function createRide(data: any, dependencyMap: Map<string, string>): Promise<string> {
|
|
|
|
|
async function createRide(data: any, dependencyMap: Map<string, string>, sortedItems: SubmissionItemWithDeps[]): Promise<string> {
|
|
|
|
|
const { transformRideData, validateSubmissionData } = await import('./entityTransformers');
|
|
|
|
|
const { ensureUniqueSlug } = await import('./slugUtils');
|
|
|
|
|
|
|
|
|
|
@@ -507,7 +508,7 @@ async function createRide(data: any, dependencyMap: Map<string, string>): Promis
|
|
|
|
|
|
|
|
|
|
if (isEdit) {
|
|
|
|
|
// Handle ride edit
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap);
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap, sortedItems);
|
|
|
|
|
|
|
|
|
|
// Extract image assignments from ImageAssignments structure
|
|
|
|
|
const imageData = extractImageAssignments(resolvedData.images);
|
|
|
|
|
@@ -556,7 +557,7 @@ async function createRide(data: any, dependencyMap: Map<string, string>): Promis
|
|
|
|
|
|
|
|
|
|
// Handle ride creation
|
|
|
|
|
validateSubmissionData(data, 'Ride');
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap);
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap, sortedItems);
|
|
|
|
|
|
|
|
|
|
if (!resolvedData.park_id) {
|
|
|
|
|
throw new Error('Ride must be associated with a park');
|
|
|
|
|
@@ -588,7 +589,8 @@ async function createRide(data: any, dependencyMap: Map<string, string>): Promis
|
|
|
|
|
async function createCompany(
|
|
|
|
|
data: any,
|
|
|
|
|
companyType: string,
|
|
|
|
|
dependencyMap: Map<string, string>
|
|
|
|
|
dependencyMap: Map<string, string>,
|
|
|
|
|
sortedItems: SubmissionItemWithDeps[]
|
|
|
|
|
): Promise<string> {
|
|
|
|
|
const { transformCompanyData, validateSubmissionData } = await import('./entityTransformers');
|
|
|
|
|
const { ensureUniqueSlug } = await import('./slugUtils');
|
|
|
|
|
@@ -598,7 +600,7 @@ async function createCompany(
|
|
|
|
|
|
|
|
|
|
if (isEdit) {
|
|
|
|
|
// Handle company edit
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap);
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap, sortedItems);
|
|
|
|
|
|
|
|
|
|
// Extract image assignments from ImageAssignments structure
|
|
|
|
|
const imageData = extractImageAssignments(resolvedData.images);
|
|
|
|
|
@@ -630,7 +632,7 @@ async function createCompany(
|
|
|
|
|
|
|
|
|
|
// Handle company creation
|
|
|
|
|
validateSubmissionData(data, 'Company');
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap);
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap, sortedItems);
|
|
|
|
|
|
|
|
|
|
const uniqueSlug = await ensureUniqueSlug(resolvedData.slug, 'companies');
|
|
|
|
|
resolvedData.slug = uniqueSlug;
|
|
|
|
|
@@ -663,7 +665,7 @@ async function createCompany(
|
|
|
|
|
return company.id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function createRideModel(data: any, dependencyMap: Map<string, string>): Promise<string> {
|
|
|
|
|
async function createRideModel(data: any, dependencyMap: Map<string, string>, sortedItems: SubmissionItemWithDeps[]): Promise<string> {
|
|
|
|
|
const { transformRideModelData, validateSubmissionData } = await import('./entityTransformers');
|
|
|
|
|
const { ensureUniqueSlug } = await import('./slugUtils');
|
|
|
|
|
|
|
|
|
|
@@ -672,7 +674,7 @@ async function createRideModel(data: any, dependencyMap: Map<string, string>): P
|
|
|
|
|
|
|
|
|
|
if (isEdit) {
|
|
|
|
|
// Handle ride model edit
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap);
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap, sortedItems);
|
|
|
|
|
|
|
|
|
|
// Extract image assignments from ImageAssignments structure
|
|
|
|
|
const imageData = extractImageAssignments(resolvedData.images);
|
|
|
|
|
@@ -704,7 +706,7 @@ async function createRideModel(data: any, dependencyMap: Map<string, string>): P
|
|
|
|
|
|
|
|
|
|
// Handle ride model creation
|
|
|
|
|
validateSubmissionData(data, 'Ride Model');
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap);
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap, sortedItems);
|
|
|
|
|
|
|
|
|
|
// Validate manufacturer_id is present (required for ride models)
|
|
|
|
|
if (!resolvedData.manufacturer_id) {
|
|
|
|
|
@@ -739,10 +741,10 @@ async function createRideModel(data: any, dependencyMap: Map<string, string>): P
|
|
|
|
|
return model.id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function approvePhotos(data: any, dependencyMap: Map<string, string>, userId: string, submissionId: string): Promise<string> {
|
|
|
|
|
async function approvePhotos(data: any, dependencyMap: Map<string, string>, userId: string, submissionId: string, sortedItems: SubmissionItemWithDeps[]): Promise<string> {
|
|
|
|
|
// Photos are already uploaded to Cloudflare
|
|
|
|
|
// Resolve dependencies for entity associations
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap);
|
|
|
|
|
const resolvedData = resolveDependencies(data, dependencyMap, sortedItems);
|
|
|
|
|
|
|
|
|
|
if (!resolvedData.photos || !Array.isArray(resolvedData.photos) || resolvedData.photos.length === 0) {
|
|
|
|
|
throw new Error('No photos found in submission');
|
|
|
|
|
@@ -900,8 +902,11 @@ async function updateEntityFeaturedImage(
|
|
|
|
|
/**
|
|
|
|
|
* Resolve dependency references in item_data by looking up approved entity IDs
|
|
|
|
|
* Replaces temporary references (_temp_*_ref) with actual database entity IDs
|
|
|
|
|
*
|
|
|
|
|
* FIXED: Now uses sortedItems array for stable index-based resolution
|
|
|
|
|
* instead of unreliable Array.from(dependencyMap.keys())[refIndex]
|
|
|
|
|
*/
|
|
|
|
|
function resolveDependencies(data: any, dependencyMap: Map<string, string>): any {
|
|
|
|
|
function resolveDependencies(data: any, dependencyMap: Map<string, string>, sortedItems: SubmissionItemWithDeps[]): any {
|
|
|
|
|
const resolved = { ...data };
|
|
|
|
|
|
|
|
|
|
// List of foreign key fields that may need resolution
|
|
|
|
|
@@ -915,43 +920,62 @@ function resolveDependencies(data: any, dependencyMap: Map<string, string>): any
|
|
|
|
|
'location_id',
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Resolve temporary references first
|
|
|
|
|
// Resolve temporary references using sortedItems array (FIXED)
|
|
|
|
|
if (resolved._temp_manufacturer_ref !== undefined) {
|
|
|
|
|
const refIndex = resolved._temp_manufacturer_ref;
|
|
|
|
|
const refItemId = Array.from(dependencyMap.keys())[refIndex];
|
|
|
|
|
if (refItemId && dependencyMap.has(refItemId)) {
|
|
|
|
|
resolved.manufacturer_id = dependencyMap.get(refItemId);
|
|
|
|
|
if (refIndex >= 0 && refIndex < sortedItems.length) {
|
|
|
|
|
const refItemId = sortedItems[refIndex].id;
|
|
|
|
|
if (dependencyMap.has(refItemId)) {
|
|
|
|
|
resolved.manufacturer_id = dependencyMap.get(refItemId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delete resolved._temp_manufacturer_ref;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (resolved._temp_operator_ref !== undefined) {
|
|
|
|
|
const refIndex = resolved._temp_operator_ref;
|
|
|
|
|
const refItemId = Array.from(dependencyMap.keys())[refIndex];
|
|
|
|
|
if (refItemId && dependencyMap.has(refItemId)) {
|
|
|
|
|
resolved.operator_id = dependencyMap.get(refItemId);
|
|
|
|
|
if (refIndex >= 0 && refIndex < sortedItems.length) {
|
|
|
|
|
const refItemId = sortedItems[refIndex].id;
|
|
|
|
|
if (dependencyMap.has(refItemId)) {
|
|
|
|
|
resolved.operator_id = dependencyMap.get(refItemId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delete resolved._temp_operator_ref;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (resolved._temp_property_owner_ref !== undefined) {
|
|
|
|
|
const refIndex = resolved._temp_property_owner_ref;
|
|
|
|
|
const refItemId = Array.from(dependencyMap.keys())[refIndex];
|
|
|
|
|
if (refItemId && dependencyMap.has(refItemId)) {
|
|
|
|
|
resolved.property_owner_id = dependencyMap.get(refItemId);
|
|
|
|
|
if (refIndex >= 0 && refIndex < sortedItems.length) {
|
|
|
|
|
const refItemId = sortedItems[refIndex].id;
|
|
|
|
|
if (dependencyMap.has(refItemId)) {
|
|
|
|
|
resolved.property_owner_id = dependencyMap.get(refItemId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delete resolved._temp_property_owner_ref;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (resolved._temp_ride_model_ref !== undefined) {
|
|
|
|
|
const refIndex = resolved._temp_ride_model_ref;
|
|
|
|
|
const refItemId = Array.from(dependencyMap.keys())[refIndex];
|
|
|
|
|
if (refItemId && dependencyMap.has(refItemId)) {
|
|
|
|
|
resolved.ride_model_id = dependencyMap.get(refItemId);
|
|
|
|
|
if (refIndex >= 0 && refIndex < sortedItems.length) {
|
|
|
|
|
const refItemId = sortedItems[refIndex].id;
|
|
|
|
|
if (dependencyMap.has(refItemId)) {
|
|
|
|
|
resolved.ride_model_id = dependencyMap.get(refItemId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delete resolved._temp_ride_model_ref;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (resolved._temp_designer_ref !== undefined) {
|
|
|
|
|
const refIndex = resolved._temp_designer_ref;
|
|
|
|
|
if (refIndex >= 0 && refIndex < sortedItems.length) {
|
|
|
|
|
const refItemId = sortedItems[refIndex].id;
|
|
|
|
|
if (dependencyMap.has(refItemId)) {
|
|
|
|
|
resolved.designer_id = dependencyMap.get(refItemId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delete resolved._temp_designer_ref;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Resolve each foreign key if it's a submission item ID
|
|
|
|
|
for (const key of foreignKeys) {
|
|
|
|
|
if (resolved[key] && dependencyMap.has(resolved[key])) {
|
|
|
|
|
|