mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 17:51:14 -05:00
Fix: Resolve milestone validation errors
This commit is contained in:
@@ -28,35 +28,45 @@ export function validateEntityDataStrict(
|
||||
warnings: []
|
||||
};
|
||||
|
||||
// Common validations (blocking)
|
||||
if (!data.name?.trim()) {
|
||||
result.blockingErrors.push('Name is required');
|
||||
}
|
||||
// Skip name/slug validations for timeline events (they use title instead)
|
||||
const isTimelineEvent = entityType === 'milestone' || entityType === 'timeline_event';
|
||||
|
||||
if (!data.slug?.trim()) {
|
||||
result.blockingErrors.push('Slug is required');
|
||||
}
|
||||
|
||||
if (data.slug && !/^[a-z0-9-]+$/.test(data.slug)) {
|
||||
result.blockingErrors.push('Slug must contain only lowercase letters, numbers, and hyphens');
|
||||
}
|
||||
|
||||
if (data.name && data.name.length > 200) {
|
||||
result.blockingErrors.push('Name must be less than 200 characters');
|
||||
}
|
||||
|
||||
if (data.description && data.description.length > 2000) {
|
||||
result.blockingErrors.push('Description must be less than 2000 characters');
|
||||
}
|
||||
|
||||
// URL validation (warning)
|
||||
if (data.website_url && data.website_url !== '' && !isValidUrl(data.website_url)) {
|
||||
result.warnings.push('Website URL format may be invalid');
|
||||
}
|
||||
|
||||
// Email validation (warning)
|
||||
if (data.email && data.email !== '' && !isValidEmail(data.email)) {
|
||||
result.warnings.push('Email format may be invalid');
|
||||
// Common validations (blocking) - only for entities with name/slug
|
||||
if (!isTimelineEvent) {
|
||||
if (!data.name?.trim()) {
|
||||
result.blockingErrors.push('Name is required');
|
||||
}
|
||||
|
||||
if (!data.slug?.trim()) {
|
||||
result.blockingErrors.push('Slug is required');
|
||||
}
|
||||
|
||||
if (data.slug && !/^[a-z0-9-]+$/.test(data.slug)) {
|
||||
result.blockingErrors.push('Slug must contain only lowercase letters, numbers, and hyphens');
|
||||
}
|
||||
|
||||
if (data.name && data.name.length > 200) {
|
||||
result.blockingErrors.push('Name must be less than 200 characters');
|
||||
}
|
||||
|
||||
if (data.description && data.description.length > 2000) {
|
||||
result.blockingErrors.push('Description must be less than 2000 characters');
|
||||
}
|
||||
|
||||
// URL validation (warning)
|
||||
if (data.website_url && data.website_url !== '' && !isValidUrl(data.website_url)) {
|
||||
result.warnings.push('Website URL format may be invalid');
|
||||
}
|
||||
|
||||
// Email validation (warning)
|
||||
if (data.email && data.email !== '' && !isValidEmail(data.email)) {
|
||||
result.warnings.push('Email format may be invalid');
|
||||
}
|
||||
} else {
|
||||
// Validations specific to timeline events
|
||||
if (data.description && data.description.length > 2000) {
|
||||
result.blockingErrors.push('Description must be less than 2000 characters');
|
||||
}
|
||||
}
|
||||
|
||||
// Entity-specific validations
|
||||
@@ -145,6 +155,28 @@ export function validateEntityDataStrict(
|
||||
result.blockingErrors.push('Caption must be less than 500 characters');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'milestone':
|
||||
case 'timeline_event':
|
||||
if (!data.title?.trim()) {
|
||||
result.blockingErrors.push('Event title is required');
|
||||
}
|
||||
if (data.title && data.title.length > 200) {
|
||||
result.blockingErrors.push('Title must be less than 200 characters');
|
||||
}
|
||||
if (!data.event_type) {
|
||||
result.blockingErrors.push('Event type is required');
|
||||
}
|
||||
if (!data.event_date) {
|
||||
result.blockingErrors.push('Event date is required');
|
||||
}
|
||||
if (!data.entity_type) {
|
||||
result.blockingErrors.push('Entity type is required');
|
||||
}
|
||||
if (!data.entity_id) {
|
||||
result.blockingErrors.push('Entity ID is required');
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
result.valid = result.blockingErrors.length === 0;
|
||||
@@ -171,27 +203,37 @@ function isValidEmail(email: string): boolean {
|
||||
export function validateEntityData(entityType: string, data: any): ValidationResult {
|
||||
const errors: string[] = [];
|
||||
|
||||
// Common validations for all entities
|
||||
if (!data.name || data.name.trim().length === 0) {
|
||||
errors.push('Name is required');
|
||||
}
|
||||
if (!data.slug || data.slug.trim().length === 0) {
|
||||
errors.push('Slug is required');
|
||||
}
|
||||
if (data.slug && !/^[a-z0-9-]+$/.test(data.slug)) {
|
||||
errors.push('Slug must contain only lowercase letters, numbers, and hyphens');
|
||||
}
|
||||
if (data.name && data.name.length > 200) {
|
||||
errors.push('Name must be less than 200 characters');
|
||||
}
|
||||
if (data.description && data.description.length > 2000) {
|
||||
errors.push('Description must be less than 2000 characters');
|
||||
}
|
||||
if (data.website_url && data.website_url !== '' && !data.website_url.startsWith('http')) {
|
||||
errors.push('Website URL must start with http:// or https://');
|
||||
}
|
||||
if (data.email && data.email !== '' && !data.email.includes('@')) {
|
||||
errors.push('Invalid email format');
|
||||
// Skip name/slug validations for timeline events
|
||||
const isTimelineEvent = entityType === 'milestone' || entityType === 'timeline_event';
|
||||
|
||||
// Common validations for entities with name/slug
|
||||
if (!isTimelineEvent) {
|
||||
if (!data.name || data.name.trim().length === 0) {
|
||||
errors.push('Name is required');
|
||||
}
|
||||
if (!data.slug || data.slug.trim().length === 0) {
|
||||
errors.push('Slug is required');
|
||||
}
|
||||
if (data.slug && !/^[a-z0-9-]+$/.test(data.slug)) {
|
||||
errors.push('Slug must contain only lowercase letters, numbers, and hyphens');
|
||||
}
|
||||
if (data.name && data.name.length > 200) {
|
||||
errors.push('Name must be less than 200 characters');
|
||||
}
|
||||
if (data.description && data.description.length > 2000) {
|
||||
errors.push('Description must be less than 2000 characters');
|
||||
}
|
||||
if (data.website_url && data.website_url !== '' && !data.website_url.startsWith('http')) {
|
||||
errors.push('Website URL must start with http:// or https://');
|
||||
}
|
||||
if (data.email && data.email !== '' && !data.email.includes('@')) {
|
||||
errors.push('Invalid email format');
|
||||
}
|
||||
} else {
|
||||
// Validations for timeline events
|
||||
if (data.description && data.description.length > 2000) {
|
||||
errors.push('Description must be less than 2000 characters');
|
||||
}
|
||||
}
|
||||
|
||||
// Entity-specific validations
|
||||
@@ -256,6 +298,20 @@ export function validateEntityData(entityType: string, data: any): ValidationRes
|
||||
errors.push('Caption must be less than 500 characters');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'milestone':
|
||||
case 'timeline_event':
|
||||
if (!data.title || data.title.trim().length === 0) {
|
||||
errors.push('Event title is required');
|
||||
}
|
||||
if (data.title && data.title.length > 200) {
|
||||
errors.push('Title must be less than 200 characters');
|
||||
}
|
||||
if (!data.event_type) errors.push('Event type is required');
|
||||
if (!data.event_date) errors.push('Event date is required');
|
||||
if (!data.entity_type) errors.push('Entity type is required');
|
||||
if (!data.entity_id) errors.push('Entity ID is required');
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user