Files
thrilltrack-explorer/src-old/lib/entityFormValidation.ts

97 lines
2.8 KiB
TypeScript

/**
* ⚠️ 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<T> = (
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<ParkFormData> {
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<RideFormData> {
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.`
);
}
}
}