Fix: Resolve milestone validation errors

This commit is contained in:
gpt-engineer-app[bot]
2025-10-17 15:47:40 +00:00
parent 95accde1d1
commit ac151e5445
4 changed files with 111 additions and 52 deletions

View File

@@ -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 {