Migrate date precision to exact

Batch update all date precision handling to use expanded DatePrecision, replace hardcoded day defaults, and adjust related validation, UI, and helpers. Includes wrapper migration across Phase 1-3 functions, updates to logs, displays, and formatting utilities to align frontend with new precision values ('exact', 'month', 'year', 'decade', 'century', 'approximate').
This commit is contained in:
gpt-engineer-app[bot]
2025-11-11 22:05:29 +00:00
parent 9ee84b31ff
commit d0c613031e
15 changed files with 189 additions and 43 deletions

View File

@@ -57,7 +57,7 @@ export function ManufacturerForm({ onSubmit, onCancel, initialData }: Manufactur
website_url: initialData?.website_url || '', website_url: initialData?.website_url || '',
founded_year: initialData?.founded_year ? String(initialData.founded_year) : '', founded_year: initialData?.founded_year ? String(initialData.founded_year) : '',
founded_date: initialData?.founded_date || (initialData?.founded_year ? `${initialData.founded_year}-01-01` : undefined), founded_date: initialData?.founded_date || (initialData?.founded_year ? `${initialData.founded_year}-01-01` : undefined),
founded_date_precision: initialData?.founded_date_precision || (initialData?.founded_year ? ('year' as const) : ('day' as const)), founded_date_precision: initialData?.founded_date_precision || (initialData?.founded_year ? ('year' as const) : ('exact' as const)),
headquarters_location: initialData?.headquarters_location || '', headquarters_location: initialData?.headquarters_location || '',
source_url: initialData?.source_url || '', source_url: initialData?.source_url || '',
submission_notes: initialData?.submission_notes || '', submission_notes: initialData?.submission_notes || '',

View File

@@ -38,9 +38,9 @@ const parkSchema = z.object({
park_type: z.string().min(1, 'Park type is required'), park_type: z.string().min(1, 'Park type is required'),
status: z.string().min(1, 'Status is required'), status: z.string().min(1, 'Status is required'),
opening_date: z.string().optional().transform(val => val || undefined), opening_date: z.string().optional().transform(val => val || undefined),
opening_date_precision: z.enum(['day', 'month', 'year']).optional(), opening_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).optional(),
closing_date: z.string().optional().transform(val => val || undefined), closing_date: z.string().optional().transform(val => val || undefined),
closing_date_precision: z.enum(['day', 'month', 'year']).optional(), closing_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).optional(),
location: z.object({ location: z.object({
name: z.string(), name: z.string(),
street_address: z.string().optional(), street_address: z.string().optional(),

View File

@@ -227,9 +227,9 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
ride_sub_type: initialData?.ride_sub_type || '', ride_sub_type: initialData?.ride_sub_type || '',
status: initialData?.status || 'operating' as const, // Store DB value directly status: initialData?.status || 'operating' as const, // Store DB value directly
opening_date: initialData?.opening_date || undefined, opening_date: initialData?.opening_date || undefined,
opening_date_precision: initialData?.opening_date_precision || 'day', opening_date_precision: initialData?.opening_date_precision || 'exact',
closing_date: initialData?.closing_date || undefined, closing_date: initialData?.closing_date || undefined,
closing_date_precision: initialData?.closing_date_precision || 'day', closing_date_precision: initialData?.closing_date_precision || 'exact',
// Convert metric values to user's preferred unit for display // Convert metric values to user's preferred unit for display
height_requirement: initialData?.height_requirement height_requirement: initialData?.height_requirement
? convertValueFromMetric(initialData.height_requirement, getDisplayUnit('cm', measurementSystem), 'cm') ? convertValueFromMetric(initialData.height_requirement, getDisplayUnit('cm', measurementSystem), 'cm')

View File

@@ -102,11 +102,11 @@ export function TimeZoneIndependentDateRangePicker({
if (!fromDate && !toDate) return null; if (!fromDate && !toDate) return null;
if (fromDate && toDate) { if (fromDate && toDate) {
return `${formatDateDisplay(fromDate, 'day')} - ${formatDateDisplay(toDate, 'day')}`; return `${formatDateDisplay(fromDate, 'exact')} - ${formatDateDisplay(toDate, 'exact')}`;
} else if (fromDate) { } else if (fromDate) {
return `From ${formatDateDisplay(fromDate, 'day')}`; return `From ${formatDateDisplay(fromDate, 'exact')}`;
} else if (toDate) { } else if (toDate) {
return `Until ${formatDateDisplay(toDate, 'day')}`; return `Until ${formatDateDisplay(toDate, 'exact')}`;
} }
return null; return null;

View File

@@ -5,8 +5,10 @@ import { ArrowRight } from 'lucide-react';
import { ArrayFieldDiff } from './ArrayFieldDiff'; import { ArrayFieldDiff } from './ArrayFieldDiff';
import { SpecialFieldDisplay } from './SpecialFieldDisplay'; import { SpecialFieldDisplay } from './SpecialFieldDisplay';
import type { DatePrecision } from '@/components/ui/flexible-date-input';
// Helper to format compact values (truncate long strings) // Helper to format compact values (truncate long strings)
function formatCompactValue(value: unknown, precision?: 'day' | 'month' | 'year', maxLength = 30): string { function formatCompactValue(value: unknown, precision?: DatePrecision, maxLength = 30): string {
const formatted = formatFieldValue(value, precision); const formatted = formatFieldValue(value, precision);
if (formatted.length > maxLength) { if (formatted.length > maxLength) {
return formatted.substring(0, maxLength) + '...'; return formatted.substring(0, maxLength) + '...';

View File

@@ -211,7 +211,13 @@ function DateFieldDisplay({ change, compact }: { change: FieldChange; compact: b
{formatFieldName(change.field)} {formatFieldName(change.field)}
{precision && ( {precision && (
<Badge variant="outline" className="text-xs ml-2"> <Badge variant="outline" className="text-xs ml-2">
{precision === 'year' ? 'Year Only' : precision === 'month' ? 'Month & Year' : 'Full Date'} {precision === 'exact' ? 'Exact Day' :
precision === 'month' ? 'Month & Year' :
precision === 'year' ? 'Year Only' :
precision === 'decade' ? 'Decade' :
precision === 'century' ? 'Century' :
precision === 'approximate' ? 'Approximate' :
'Full Date'}
</Badge> </Badge>
)} )}
</div> </div>

View File

@@ -72,7 +72,7 @@ const timelineEventSchema = z.object({
event_date: z.date({ event_date: z.date({
message: 'Event date is required', message: 'Event date is required',
}), }),
event_date_precision: z.enum(['day', 'month', 'year']).default('day'), event_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).default('exact'),
title: z.string().min(1, 'Title is required').max(200, 'Title is too long'), title: z.string().min(1, 'Title is required').max(200, 'Title is too long'),
description: z.string().max(1000, 'Description is too long').optional(), description: z.string().max(1000, 'Description is too long').optional(),
@@ -133,7 +133,7 @@ export function TimelineEventEditorDialog({
} : { } : {
event_type: 'milestone', event_type: 'milestone',
event_date: new Date(), event_date: new Date(),
event_date_precision: 'day', event_date_precision: 'exact',
title: '', title: '',
description: '', description: '',
}, },
@@ -319,9 +319,12 @@ export function TimelineEventEditorDialog({
</SelectTrigger> </SelectTrigger>
</FormControl> </FormControl>
<SelectContent> <SelectContent>
<SelectItem value="day">Exact Day</SelectItem> <SelectItem value="exact">Exact Day</SelectItem>
<SelectItem value="month">Month Only</SelectItem> <SelectItem value="month">Month Only</SelectItem>
<SelectItem value="year">Year Only</SelectItem> <SelectItem value="year">Year Only</SelectItem>
<SelectItem value="decade">Decade</SelectItem>
<SelectItem value="century">Century</SelectItem>
<SelectItem value="approximate">Approximate</SelectItem>
</SelectContent> </SelectContent>
</Select> </Select>
<FormMessage /> <FormMessage />

View File

@@ -11,7 +11,7 @@ interface FlexibleDateDisplayProps {
export function FlexibleDateDisplay({ export function FlexibleDateDisplay({
date, date,
precision = 'day', precision = 'exact',
fallback = 'Unknown', fallback = 'Unknown',
className className
}: FlexibleDateDisplayProps) { }: FlexibleDateDisplayProps) {
@@ -36,7 +36,16 @@ export function FlexibleDateDisplay({
case 'month': case 'month':
formatted = format(dateObj, 'MMMM yyyy'); formatted = format(dateObj, 'MMMM yyyy');
break; break;
case 'day': case 'decade':
formatted = `${Math.floor(dateObj.getFullYear() / 10) * 10}s`;
break;
case 'century':
formatted = `${Math.ceil(dateObj.getFullYear() / 100)}th century`;
break;
case 'approximate':
formatted = `circa ${format(dateObj, 'yyyy')}`;
break;
case 'exact':
default: default:
formatted = format(dateObj, 'PPP'); formatted = format(dateObj, 'PPP');
break; break;

View File

@@ -16,7 +16,7 @@ import {
} from "@/components/ui/select"; } from "@/components/ui/select";
import { toDateOnly, toDateWithPrecision } from "@/lib/dateUtils"; import { toDateOnly, toDateWithPrecision } from "@/lib/dateUtils";
export type DatePrecision = 'day' | 'month' | 'year'; export type DatePrecision = 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate';
interface FlexibleDateInputProps { interface FlexibleDateInputProps {
value?: Date; value?: Date;
@@ -34,7 +34,7 @@ interface FlexibleDateInputProps {
export function FlexibleDateInput({ export function FlexibleDateInput({
value, value,
precision = 'day', precision = 'exact',
onChange, onChange,
placeholder = "Select date", placeholder = "Select date",
disabled = false, disabled = false,
@@ -71,13 +71,16 @@ export function FlexibleDateInput({
let newDate: Date; let newDate: Date;
switch (newPrecision) { switch (newPrecision) {
case 'year': case 'year':
case 'decade':
case 'century':
case 'approximate':
newDate = new Date(year, 0, 1); // January 1st (local timezone) newDate = new Date(year, 0, 1); // January 1st (local timezone)
setYearValue(year.toString()); setYearValue(year.toString());
break; break;
case 'month': case 'month':
newDate = new Date(year, month, 1); // 1st of month (local timezone) newDate = new Date(year, month, 1); // 1st of month (local timezone)
break; break;
case 'day': case 'exact':
default: default:
newDate = value; // Keep existing date newDate = value; // Keep existing date
break; break;
@@ -104,10 +107,13 @@ export function FlexibleDateInput({
const getPlaceholderText = () => { const getPlaceholderText = () => {
switch (localPrecision) { switch (localPrecision) {
case 'year': case 'year':
case 'decade':
case 'century':
case 'approximate':
return 'Enter year (e.g., 2005)'; return 'Enter year (e.g., 2005)';
case 'month': case 'month':
return 'Select month and year'; return 'Select month and year';
case 'day': case 'exact':
default: default:
return placeholder; return placeholder;
} }
@@ -119,10 +125,10 @@ export function FlexibleDateInput({
<div className="flex gap-2"> <div className="flex gap-2">
<div className="flex-1"> <div className="flex-1">
{localPrecision === 'day' && ( {(localPrecision === 'exact') && (
<DatePicker <DatePicker
date={value} date={value}
onSelect={(date) => onChange(date, 'day')} onSelect={(date) => onChange(date, 'exact')}
placeholder={getPlaceholderText()} placeholder={getPlaceholderText()}
disabled={disabled} disabled={disabled}
disableFuture={disableFuture} disableFuture={disableFuture}
@@ -143,7 +149,7 @@ export function FlexibleDateInput({
/> />
)} )}
{localPrecision === 'year' && ( {(localPrecision === 'year' || localPrecision === 'decade' || localPrecision === 'century' || localPrecision === 'approximate') && (
<Input <Input
type="number" type="number"
value={yearValue} value={yearValue}
@@ -166,9 +172,12 @@ export function FlexibleDateInput({
<SelectValue /> <SelectValue />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem value="day">Use Full Date</SelectItem> <SelectItem value="exact">Exact Day</SelectItem>
<SelectItem value="month">Use Month/Year</SelectItem> <SelectItem value="month">Month & Year</SelectItem>
<SelectItem value="year">Use Year Only</SelectItem> <SelectItem value="year">Year Only</SelectItem>
<SelectItem value="decade">Decade</SelectItem>
<SelectItem value="century">Century</SelectItem>
<SelectItem value="approximate">Approximate</SelectItem>
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>

View File

@@ -72,7 +72,7 @@ export function getCurrentDateLocal(): string {
*/ */
export function formatDateDisplay( export function formatDateDisplay(
dateString: string | null | undefined, dateString: string | null | undefined,
precision: 'day' | 'month' | 'year' = 'day' precision: 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate' = 'exact'
): string { ): string {
if (!dateString) return ''; if (!dateString) return '';
@@ -83,7 +83,13 @@ export function formatDateDisplay(
return date.getFullYear().toString(); return date.getFullYear().toString();
case 'month': case 'month':
return date.toLocaleDateString('en-US', { year: 'numeric', month: 'long' }); return date.toLocaleDateString('en-US', { year: 'numeric', month: 'long' });
case 'day': case 'decade':
return `${Math.floor(date.getFullYear() / 10) * 10}s`;
case 'century':
return `${Math.ceil(date.getFullYear() / 100)}th century`;
case 'approximate':
return `circa ${date.getFullYear()}`;
case 'exact':
default: default:
return date.toLocaleDateString('en-US', { return date.toLocaleDateString('en-US', {
year: 'numeric', year: 'numeric',
@@ -182,7 +188,7 @@ export function parseDateForDisplay(date: string | Date): Date {
*/ */
export function toDateWithPrecision( export function toDateWithPrecision(
date: Date, date: Date,
precision: 'day' | 'month' | 'year' precision: 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate'
): string { ): string {
const year = date.getFullYear(); const year = date.getFullYear();
const month = date.getMonth() + 1; const month = date.getMonth() + 1;
@@ -193,7 +199,13 @@ export function toDateWithPrecision(
return `${year}-01-01`; return `${year}-01-01`;
case 'month': case 'month':
return `${year}-${String(month).padStart(2, '0')}-01`; return `${year}-${String(month).padStart(2, '0')}-01`;
case 'day': case 'decade':
return `${Math.floor(year / 10) * 10}-01-01`;
case 'century':
return `${Math.floor((year - 1) / 100) * 100 + 1}-01-01`;
case 'approximate':
return `${year}-01-01`;
case 'exact':
default: default:
return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`; return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
} }

View File

@@ -51,9 +51,9 @@ export const parkValidationSchema = z.object({
const date = new Date(val); const date = new Date(val);
return date <= new Date(); return date <= new Date();
}, 'Opening date cannot be in the future'), }, 'Opening date cannot be in the future'),
opening_date_precision: z.enum(['day', 'month', 'year']).nullable().optional(), opening_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).nullable().optional(),
closing_date: z.string().nullish().transform(val => val ?? undefined), closing_date: z.string().nullish().transform(val => val ?? undefined),
closing_date_precision: z.enum(['day', 'month', 'year']).nullable().optional(), closing_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).nullable().optional(),
location_id: z.string().uuid().optional().nullable(), location_id: z.string().uuid().optional().nullable(),
location: z.object({ location: z.object({
name: z.string(), name: z.string(),
@@ -139,9 +139,9 @@ export const rideValidationSchema = z.object({
.optional() .optional()
.nullable(), .nullable(),
opening_date: z.string().nullish().transform(val => val ?? undefined), opening_date: z.string().nullish().transform(val => val ?? undefined),
opening_date_precision: z.enum(['day', 'month', 'year']).nullable().optional(), opening_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).nullable().optional(),
closing_date: z.string().nullish().transform(val => val ?? undefined), closing_date: z.string().nullish().transform(val => val ?? undefined),
closing_date_precision: z.enum(['day', 'month', 'year']).nullable().optional(), closing_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).nullable().optional(),
height_requirement: z.preprocess( height_requirement: z.preprocess(
(val) => val === '' || val === null || val === undefined ? undefined : Number(val), (val) => val === '' || val === null || val === undefined ? undefined : Number(val),
z.number().int().min(0, 'Height requirement must be positive').max(300, 'Height requirement must be less than 300cm').optional() z.number().int().min(0, 'Height requirement must be positive').max(300, 'Height requirement must be less than 300cm').optional()
@@ -322,7 +322,7 @@ export const companyValidationSchema = z.object({
description: z.string().trim().max(2000, 'Description must be less than 2000 characters').nullish().transform(val => val ?? undefined), description: z.string().trim().max(2000, 'Description must be less than 2000 characters').nullish().transform(val => val ?? undefined),
person_type: z.enum(['company', 'individual', 'firm', 'organization']), person_type: z.enum(['company', 'individual', 'firm', 'organization']),
founded_date: z.string().nullish().transform(val => val ?? undefined), founded_date: z.string().nullish().transform(val => val ?? undefined),
founded_date_precision: z.enum(['day', 'month', 'year']).nullable().optional(), founded_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).nullable().optional(),
founded_year: z.preprocess( founded_year: z.preprocess(
(val) => val === '' || val === null || val === undefined ? undefined : Number(val), (val) => val === '' || val === null || val === undefined ? undefined : Number(val),
z.number().int().min(1800, 'Founded year must be after 1800').max(currentYear, `Founded year cannot be after ${currentYear}`).optional() z.number().int().min(1800, 'Founded year must be after 1800').max(currentYear, `Founded year cannot be after ${currentYear}`).optional()
@@ -401,7 +401,7 @@ export const milestoneValidationSchema = z.object({
fiveYearsFromNow.setFullYear(fiveYearsFromNow.getFullYear() + 5); fiveYearsFromNow.setFullYear(fiveYearsFromNow.getFullYear() + 5);
return date <= fiveYearsFromNow; return date <= fiveYearsFromNow;
}, 'Event date cannot be more than 5 years in the future'), }, 'Event date cannot be more than 5 years in the future'),
event_date_precision: z.enum(['day', 'month', 'year']).optional().default('day'), event_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).optional().default('exact'),
entity_type: z.string().min(1, 'Entity type is required'), entity_type: z.string().min(1, 'Entity type is required'),
entity_id: z.string().uuid('Invalid entity ID'), entity_id: z.string().uuid('Invalid entity ID'),
is_public: z.boolean().optional(), is_public: z.boolean().optional(),

View File

@@ -21,9 +21,9 @@ export interface FieldChange {
changeType: 'added' | 'removed' | 'modified'; changeType: 'added' | 'removed' | 'modified';
metadata?: { metadata?: {
isCreatingNewLocation?: boolean; isCreatingNewLocation?: boolean;
precision?: 'day' | 'month' | 'year'; precision?: 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate';
oldPrecision?: 'day' | 'month' | 'year'; oldPrecision?: 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate';
newPrecision?: 'day' | 'month' | 'year'; newPrecision?: 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate';
}; };
} }
@@ -803,7 +803,7 @@ function formatEntityType(entityType: string): string {
/** /**
* Format field value for display * Format field value for display
*/ */
export function formatFieldValue(value: any, precision?: 'day' | 'month' | 'year'): string { export function formatFieldValue(value: any, precision?: 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate'): string {
if (value === null || value === undefined) return 'None'; if (value === null || value === undefined) return 'None';
if (typeof value === 'boolean') return value ? 'Yes' : 'No'; if (typeof value === 'boolean') return value ? 'Yes' : 'No';
@@ -817,9 +817,15 @@ export function formatFieldValue(value: any, precision?: 'day' | 'month' | 'year
return date.getFullYear().toString(); return date.getFullYear().toString();
} else if (precision === 'month') { } else if (precision === 'month') {
return date.toLocaleDateString('en-US', { year: 'numeric', month: 'long' }); return date.toLocaleDateString('en-US', { year: 'numeric', month: 'long' });
} else if (precision === 'decade') {
return `${Math.floor(date.getFullYear() / 10) * 10}s`;
} else if (precision === 'century') {
return `${Math.ceil(date.getFullYear() / 100)}th century`;
} else if (precision === 'approximate') {
return `circa ${date.getFullYear()}`;
} }
// Default: full date // Default: full date (exact)
return date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); return date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
} catch { } catch {
return String(value); return String(value);

View File

@@ -659,9 +659,9 @@ export default function ParkDetail() {
park_type: park?.park_type, park_type: park?.park_type,
status: park?.status, status: park?.status,
opening_date: park?.opening_date ?? undefined, opening_date: park?.opening_date ?? undefined,
opening_date_precision: (park?.opening_date_precision as 'day' | 'month' | 'year') ?? undefined, opening_date_precision: (park?.opening_date_precision as 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate') ?? undefined,
closing_date: park?.closing_date ?? undefined, closing_date: park?.closing_date ?? undefined,
closing_date_precision: (park?.closing_date_precision as 'day' | 'month' | 'year') ?? undefined, closing_date_precision: (park?.closing_date_precision as 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate') ?? undefined,
location_id: park?.location?.id, location_id: park?.location?.id,
location: park?.location ? { location: park?.location ? {
name: park.location.name || '', name: park.location.name || '',

View File

@@ -22,7 +22,7 @@ export type TimelineEventType =
export type EntityType = 'park' | 'ride' | 'company' | 'ride_model'; export type EntityType = 'park' | 'ride' | 'company' | 'ride_model';
export type DatePrecision = 'day' | 'month' | 'year'; export type DatePrecision = 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate';
/** /**
* Timeline event stored in database after approval * Timeline event stored in database after approval

View File

@@ -0,0 +1,99 @@
-- Phase 3: Migrate 'day' precision to 'exact' across all tables
-- This fixes the check constraint violations and aligns with the new precision system
-- Parks
UPDATE parks
SET opening_date_precision = 'exact'
WHERE opening_date_precision = 'day';
UPDATE parks
SET closing_date_precision = 'exact'
WHERE closing_date_precision = 'day';
-- Park Submissions
UPDATE park_submissions
SET opening_date_precision = 'exact'
WHERE opening_date_precision = 'day';
UPDATE park_submissions
SET closing_date_precision = 'exact'
WHERE closing_date_precision = 'day';
-- Park Versions
UPDATE park_versions
SET opening_date_precision = 'exact'
WHERE opening_date_precision = 'day';
UPDATE park_versions
SET closing_date_precision = 'exact'
WHERE closing_date_precision = 'day';
-- Rides
UPDATE rides
SET opening_date_precision = 'exact'
WHERE opening_date_precision = 'day';
UPDATE rides
SET closing_date_precision = 'exact'
WHERE closing_date_precision = 'day';
-- Ride Submissions
UPDATE ride_submissions
SET opening_date_precision = 'exact'
WHERE opening_date_precision = 'day';
UPDATE ride_submissions
SET closing_date_precision = 'exact'
WHERE closing_date_precision = 'day';
-- Ride Versions
UPDATE ride_versions
SET opening_date_precision = 'exact'
WHERE opening_date_precision = 'day';
UPDATE ride_versions
SET closing_date_precision = 'exact'
WHERE closing_date_precision = 'day';
-- Companies
UPDATE companies
SET founded_date_precision = 'exact'
WHERE founded_date_precision = 'day';
-- Company Submissions
UPDATE company_submissions
SET founded_date_precision = 'exact'
WHERE founded_date_precision = 'day';
-- Company Versions
UPDATE company_versions
SET founded_date_precision = 'exact'
WHERE founded_date_precision = 'day';
-- Entity Timeline Events
UPDATE entity_timeline_events
SET event_date_precision = 'exact'
WHERE event_date_precision = 'day';
-- Timeline Event Submissions
UPDATE timeline_event_submissions
SET event_date_precision = 'exact'
WHERE event_date_precision = 'day';
-- Historical Parks
UPDATE historical_parks
SET opening_date_precision = 'exact'
WHERE opening_date_precision = 'day';
UPDATE historical_parks
SET closing_date_precision = 'exact'
WHERE closing_date_precision = 'day';
-- Historical Rides
UPDATE historical_rides
SET opening_date_precision = 'exact'
WHERE opening_date_precision = 'day';
UPDATE historical_rides
SET closing_date_precision = 'exact'
WHERE closing_date_precision = 'day';