/** * ⚠️ CRITICAL SECURITY PATTERN ⚠️ * * These wrappers enforce the submission flow for all entity edits/creations. * DO NOT bypass these - they ensure moderation queue → versioning → live display. * * Flow: User Submit → Moderation Queue → Approval → Versioning → Live * * @see docs/SUBMISSION_FLOW.md */ import { submitParkCreation, submitParkUpdate, submitRideCreation, submitRideUpdate, ParkFormData, RideFormData } from './entitySubmissionHelpers'; import { logger } from './logger'; export type EntitySubmissionHandler = ( data: T, userId: string ) => Promise<{ submitted: boolean; submissionId: string }>; /** * Creates a type-safe submission handler for parks. * Automatically routes to creation or update based on isEditing flag. * * @example * const handleSubmit = enforceParkSubmissionFlow(true, park.id); * await handleSubmit(formData, user.id); */ export function enforceParkSubmissionFlow( isEditing: boolean, existingId?: string ): EntitySubmissionHandler { if (isEditing && !existingId) { throw new Error('existingId is required when isEditing is true'); } return async (data: ParkFormData, userId: string) => { if (isEditing && existingId) { return await submitParkUpdate(existingId, data, userId); } else { return await submitParkCreation(data, userId); } }; } /** * Creates a type-safe submission handler for rides. * Automatically routes to creation or update based on isEditing flag. * * @example * const handleSubmit = enforceRideSubmissionFlow(true, ride.id); * await handleSubmit(formData, user.id); */ export function enforceRideSubmissionFlow( isEditing: boolean, existingId?: string ): EntitySubmissionHandler { if (isEditing && !existingId) { throw new Error('existingId is required when isEditing is true'); } return async (data: RideFormData, userId: string) => { if (isEditing && existingId) { return await submitRideUpdate(existingId, data, userId); } else { return await submitRideCreation(data, userId); } }; } /** * Development-mode validation helper. * Warns if a form's onSubmit handler doesn't use submission helpers. */ export function validateSubmissionHandler( onSubmit: Function, entityType: 'park' | 'ride' ): void { if (process.env.NODE_ENV === 'development') { const funcString = onSubmit.toString(); const expectedPattern = entityType === 'park' ? 'submitPark' : 'submitRide'; if (!funcString.includes(expectedPattern)) { logger.warn( `⚠️ ${entityType}Form: onSubmit should use ${expectedPattern}Creation/${expectedPattern}Update from entitySubmissionHelpers.\n` + `Direct database writes bypass the moderation queue and versioning system.` ); } } }