Fix ride model submissions

Implement rate limiting, ban checks, retry logic, and breadcrumb tracking for ride model creation and update functions. Wrap existing ban checks and database operations in retry logic.
This commit is contained in:
gpt-engineer-app[bot]
2025-11-07 19:59:32 +00:00
parent 2c9358e884
commit 48c1e9cdda

View File

@@ -1755,15 +1755,30 @@ export async function submitRideModelCreation(
data: RideModelFormData,
userId: string
): Promise<{ submitted: boolean; submissionId: string }> {
// Rate limiting check
checkRateLimitOrThrow(userId, 'ride_model_creation');
recordSubmissionAttempt(userId);
// Breadcrumb tracking
breadcrumb.userAction('Start ride model submission', 'submitRideModelCreation', { userId });
// Validate required fields client-side
assertValid(validateRideModelCreateFields(data));
// Check if user is banned
// Ban check with retry logic
const { withRetry } = await import('./retryHelpers');
breadcrumb.apiCall('profiles', 'SELECT');
const profile = await withRetry(
async () => {
const { data: profile } = await supabase
.from('profiles')
.select('banned')
.eq('user_id', userId)
.single();
return profile;
},
{ maxAttempts: 2 }
);
if (profile?.banned) {
throw new Error('Account suspended. Contact support for assistance.');
@@ -1786,6 +1801,10 @@ export async function submitRideModelCreation(
}
}
// Submit with retry logic
breadcrumb.apiCall('content_submissions', 'INSERT');
const result = await withRetry(
async () => {
// Create the main submission record
const { data: submissionData, error: submissionError } = await supabase
.from('content_submissions')
@@ -1868,6 +1887,28 @@ export async function submitRideModelCreation(
}
return { submitted: true, submissionId: submissionData.id };
},
{
maxAttempts: 3,
onRetry: (attempt, error, delay) => {
logger.warn('Retrying ride model submission', { attempt, delay });
window.dispatchEvent(new CustomEvent('submission-retry', {
detail: { attempt, maxAttempts: 3, delay, type: 'ride_model' }
}));
},
shouldRetry: (error) => {
if (error instanceof Error) {
const message = error.message.toLowerCase();
if (message.includes('required')) return false;
if (message.includes('banned')) return false;
if (message.includes('slug')) return false;
}
return isRetryableError(error);
}
}
);
return result;
}
/**
@@ -1881,12 +1922,27 @@ export async function submitRideModelUpdate(
data: RideModelFormData,
userId: string
): Promise<{ submitted: boolean; submissionId: string }> {
// Check if user is banned
// Rate limiting check
checkRateLimitOrThrow(userId, 'ride_model_update');
recordSubmissionAttempt(userId);
// Breadcrumb tracking
breadcrumb.userAction('Start ride model update', 'submitRideModelUpdate', { userId, rideModelId });
// Ban check with retry logic
const { withRetry } = await import('./retryHelpers');
breadcrumb.apiCall('profiles', 'SELECT');
const profile = await withRetry(
async () => {
const { data: profile } = await supabase
.from('profiles')
.select('banned')
.eq('user_id', userId)
.single();
return profile;
},
{ maxAttempts: 2 }
);
if (profile?.banned) {
throw new Error('Account suspended. Contact support for assistance.');
@@ -1909,6 +1965,10 @@ export async function submitRideModelUpdate(
let processedImages = data.images;
// Submit with retry logic
breadcrumb.apiCall('content_submissions', 'INSERT');
const result = await withRetry(
async () => {
// Create the main submission record
const { data: submissionData, error: submissionError } = await supabase
.from('content_submissions')
@@ -1989,6 +2049,28 @@ export async function submitRideModelUpdate(
}
return { submitted: true, submissionId: submissionData.id };
},
{
maxAttempts: 3,
onRetry: (attempt, error, delay) => {
logger.warn('Retrying ride model update', { attempt, delay });
window.dispatchEvent(new CustomEvent('submission-retry', {
detail: { attempt, maxAttempts: 3, delay, type: 'ride_model_update' }
}));
},
shouldRetry: (error) => {
if (error instanceof Error) {
const message = error.message.toLowerCase();
if (message.includes('required')) return false;
if (message.includes('banned')) return false;
if (message.includes('slug')) return false;
}
return isRetryableError(error);
}
}
);
return result;
}
/**