From 1fc9a1104f37343b06594a2966a34d5c6d0c750a Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Fri, 10 Oct 2025 19:01:15 +0000 Subject: [PATCH] Approve database migration --- src/components/admin/DesignerForm.tsx | 1 + src/components/admin/ManufacturerForm.tsx | 33 +++---- src/components/admin/OperatorForm.tsx | 3 + src/components/admin/ParkForm.tsx | 47 +++++----- src/components/admin/PropertyOwnerForm.tsx | 1 + src/components/admin/RideForm.tsx | 47 +++++----- src/integrations/supabase/types.ts | 60 +++++++++++++ src/lib/entityValidationSchemas.ts | 6 ++ src/types/database.ts | 9 +- src/types/submission-data.ts | 8 +- ...4_375d6c7d-5497-4888-b7c3-267ee1cf31bb.sql | 85 +++++++++++++++++++ 11 files changed, 243 insertions(+), 57 deletions(-) create mode 100644 supabase/migrations/20251010185634_375d6c7d-5497-4888-b7c3-267ee1cf31bb.sql diff --git a/src/components/admin/DesignerForm.tsx b/src/components/admin/DesignerForm.tsx index 5f55a4e5..154bf568 100644 --- a/src/components/admin/DesignerForm.tsx +++ b/src/components/admin/DesignerForm.tsx @@ -14,6 +14,7 @@ import { Combobox } from '@/components/ui/combobox'; import { useCompanyHeadquarters } from '@/hooks/useAutocompleteData'; import { useUserRole } from '@/hooks/useUserRole'; import { EntityMultiImageUploader, ImageAssignments } from '@/components/upload/EntityMultiImageUploader'; +import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-date-input'; type DesignerFormData = z.infer; diff --git a/src/components/admin/ManufacturerForm.tsx b/src/components/admin/ManufacturerForm.tsx index 09134c2e..78c4cf2b 100644 --- a/src/components/admin/ManufacturerForm.tsx +++ b/src/components/admin/ManufacturerForm.tsx @@ -14,6 +14,7 @@ import { Combobox } from '@/components/ui/combobox'; import { useCompanyHeadquarters } from '@/hooks/useAutocompleteData'; import { useUserRole } from '@/hooks/useUserRole'; import { EntityMultiImageUploader, ImageAssignments } from '@/components/upload/EntityMultiImageUploader'; +import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-date-input'; type ManufacturerFormData = z.infer; @@ -24,7 +25,9 @@ type ManufacturerFormInput = { description?: string; person_type: 'company' | 'individual' | 'firm' | 'organization'; website_url?: string; - founded_year?: string; + founded_year?: string; // Legacy support + founded_date?: string; + founded_date_precision?: string; headquarters_location?: string; images?: { uploaded: Array<{ @@ -68,6 +71,8 @@ export function ManufacturerForm({ onSubmit, onCancel, initialData }: Manufactur person_type: initialData?.person_type || 'company', website_url: initialData?.website_url || '', founded_year: initialData?.founded_year ? String(initialData.founded_year) : '', + founded_date: initialData?.founded_date || (initialData?.founded_year ? `${initialData.founded_year}-01-01` : ''), + founded_date_precision: initialData?.founded_date_precision || (initialData?.founded_year ? 'year' : 'day'), headquarters_location: initialData?.headquarters_location || '', images: initialData?.images || { uploaded: [] } } @@ -146,20 +151,18 @@ export function ManufacturerForm({ onSubmit, onCancel, initialData }: Manufactur {/* Additional Details */}
-
- - - {errors.founded_year && ( -

{errors.founded_year.message}

- )} -
+ { + setValue('founded_date', date ? date.toISOString().split('T')[0] : undefined); + setValue('founded_date_precision', precision); + }} + label="Founded Date" + placeholder="Select founded date" + disableFuture={true} + fromYear={1800} + />
diff --git a/src/components/admin/OperatorForm.tsx b/src/components/admin/OperatorForm.tsx index fa2589e8..1c1b419e 100644 --- a/src/components/admin/OperatorForm.tsx +++ b/src/components/admin/OperatorForm.tsx @@ -14,6 +14,7 @@ import { Combobox } from '@/components/ui/combobox'; import { useCompanyHeadquarters } from '@/hooks/useAutocompleteData'; import { useUserRole } from '@/hooks/useUserRole'; import { EntityMultiImageUploader, ImageAssignments } from '@/components/upload/EntityMultiImageUploader'; +import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-date-input'; type OperatorFormData = z.infer; @@ -25,6 +26,8 @@ type OperatorFormInput = { person_type: 'company' | 'individual' | 'firm' | 'organization'; website_url?: string; founded_year?: string; + founded_date?: string; + founded_date_precision?: string; headquarters_location?: string; images?: { uploaded: Array<{ diff --git a/src/components/admin/ParkForm.tsx b/src/components/admin/ParkForm.tsx index cfcf0fda..b56b0d61 100644 --- a/src/components/admin/ParkForm.tsx +++ b/src/components/admin/ParkForm.tsx @@ -12,6 +12,7 @@ import { Label } from '@/components/ui/label'; import { EntityMultiImageUploader, ImageAssignments } from '@/components/upload/EntityMultiImageUploader'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { DatePicker } from '@/components/ui/date-picker'; +import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-date-input'; import { SlugField } from '@/components/ui/slug-field'; import { toast } from '@/hooks/use-toast'; import { MapPin, Save, X, Plus } from 'lucide-react'; @@ -29,7 +30,9 @@ const parkSchema = z.object({ park_type: z.string().min(1, 'Park type is required'), status: z.string().min(1, 'Status is required'), opening_date: z.string().optional(), + opening_date_precision: z.enum(['day', 'month', 'year']).optional(), closing_date: z.string().optional(), + closing_date_precision: z.enum(['day', 'month', 'year']).optional(), location: z.object({ name: z.string(), city: z.string().optional(), @@ -279,27 +282,31 @@ export function ParkForm({ onSubmit, onCancel, initialData, isEditing = false }: {/* Dates */}
-
- - setValue('opening_date', date ? date.toISOString().split('T')[0] : undefined)} - placeholder="Select opening date" - disableFuture={true} - fromYear={1800} - /> -
+ { + setValue('opening_date', date ? date.toISOString().split('T')[0] : undefined); + setValue('opening_date_precision', precision); + }} + label="Opening Date" + placeholder="Select opening date" + disableFuture={true} + fromYear={1800} + /> -
- - setValue('closing_date', date ? date.toISOString().split('T')[0] : undefined)} - placeholder="Select closing date" - disablePast={false} - fromYear={1800} - /> -
+ { + setValue('closing_date', date ? date.toISOString().split('T')[0] : undefined); + setValue('closing_date_precision', precision); + }} + label="Closing Date (if applicable)" + placeholder="Select closing date" + disablePast={false} + fromYear={1800} + />
{/* Location */} diff --git a/src/components/admin/PropertyOwnerForm.tsx b/src/components/admin/PropertyOwnerForm.tsx index 7fd39cca..e1715b52 100644 --- a/src/components/admin/PropertyOwnerForm.tsx +++ b/src/components/admin/PropertyOwnerForm.tsx @@ -13,6 +13,7 @@ import { Combobox } from '@/components/ui/combobox'; import { useCompanyHeadquarters } from '@/hooks/useAutocompleteData'; import { useUserRole } from '@/hooks/useUserRole'; import { EntityMultiImageUploader, ImageAssignments } from '@/components/upload/EntityMultiImageUploader'; +import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-date-input'; const propertyOwnerSchema = z.object({ name: z.string().min(1, 'Name is required'), diff --git a/src/components/admin/RideForm.tsx b/src/components/admin/RideForm.tsx index 75971990..4ea019a4 100644 --- a/src/components/admin/RideForm.tsx +++ b/src/components/admin/RideForm.tsx @@ -13,6 +13,7 @@ import { Badge } from '@/components/ui/badge'; import { EntityMultiImageUploader, ImageAssignments } from '@/components/upload/EntityMultiImageUploader'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { DatePicker } from '@/components/ui/date-picker'; +import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-date-input'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Combobox } from '@/components/ui/combobox'; import { SlugField } from '@/components/ui/slug-field'; @@ -158,7 +159,9 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }: ? STATUS_DB_TO_DISPLAY[initialData.status] || 'Operating' : 'Operating', opening_date: initialData?.opening_date || '', + opening_date_precision: initialData?.opening_date_precision || 'day', closing_date: initialData?.closing_date || '', + closing_date_precision: initialData?.closing_date_precision || 'day', // Convert metric values to user's preferred unit for display height_requirement: initialData?.height_requirement ? convertValueFromMetric(initialData.height_requirement, getDisplayUnit('cm', measurementSystem), 'cm') @@ -486,27 +489,31 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }: {/* Dates */}
-
- - setValue('opening_date', date ? date.toISOString().split('T')[0] : undefined)} - placeholder="Select opening date" - disableFuture={true} - fromYear={1800} - /> -
+ { + setValue('opening_date', date ? date.toISOString().split('T')[0] : undefined); + setValue('opening_date_precision', precision); + }} + label="Opening Date" + placeholder="Select opening date" + disableFuture={true} + fromYear={1800} + /> -
- - setValue('closing_date', date ? date.toISOString().split('T')[0] : undefined)} - placeholder="Select closing date" - disablePast={false} - fromYear={1800} - /> -
+ { + setValue('closing_date', date ? date.toISOString().split('T')[0] : undefined); + setValue('closing_date_precision', precision); + }} + label="Closing Date (if applicable)" + placeholder="Select closing date" + disablePast={false} + fromYear={1800} + />
{/* Requirements */} diff --git a/src/integrations/supabase/types.ts b/src/integrations/supabase/types.ts index 9ffef2ae..5d517af7 100644 --- a/src/integrations/supabase/types.ts +++ b/src/integrations/supabase/types.ts @@ -84,6 +84,8 @@ export type Database = { company_type: string created_at: string description: string | null + founded_date: string | null + founded_date_precision: string | null founded_year: number | null headquarters_location: string | null id: string @@ -107,6 +109,8 @@ export type Database = { company_type: string created_at?: string description?: string | null + founded_date?: string | null + founded_date_precision?: string | null founded_year?: number | null headquarters_location?: string | null id?: string @@ -130,6 +134,8 @@ export type Database = { company_type?: string created_at?: string description?: string | null + founded_date?: string | null + founded_date_precision?: string | null founded_year?: number | null headquarters_location?: string | null id?: string @@ -155,6 +161,8 @@ export type Database = { company_type: string created_at: string description: string | null + founded_date: string | null + founded_date_precision: string | null founded_year: number | null headquarters_location: string | null id: string @@ -174,6 +182,8 @@ export type Database = { company_type: string created_at?: string description?: string | null + founded_date?: string | null + founded_date_precision?: string | null founded_year?: number | null headquarters_location?: string | null id?: string @@ -193,6 +203,8 @@ export type Database = { company_type?: string created_at?: string description?: string | null + founded_date?: string | null + founded_date_precision?: string | null founded_year?: number | null headquarters_location?: string | null id?: string @@ -501,7 +513,9 @@ export type Database = { location_id: string | null name: string operated_from: string | null + operated_from_precision: string | null operated_until: string | null + operated_until_precision: string | null original_park_id: string | null slug: string successor_park_id: string | null @@ -514,7 +528,9 @@ export type Database = { location_id?: string | null name: string operated_from?: string | null + operated_from_precision?: string | null operated_until?: string | null + operated_until_precision?: string | null original_park_id?: string | null slug: string successor_park_id?: string | null @@ -527,7 +543,9 @@ export type Database = { location_id?: string | null name?: string operated_from?: string | null + operated_from_precision?: string | null operated_until?: string | null + operated_until_precision?: string | null original_park_id?: string | null slug?: string successor_park_id?: string | null @@ -563,7 +581,9 @@ export type Database = { id: string name: string operated_from: string | null + operated_from_precision: string | null operated_until: string | null + operated_until_precision: string | null original_ride_id: string | null park_id: string | null relocated_to_park_id: string | null @@ -577,7 +597,9 @@ export type Database = { id?: string name: string operated_from?: string | null + operated_from_precision?: string | null operated_until?: string | null + operated_until_precision?: string | null original_ride_id?: string | null park_id?: string | null relocated_to_park_id?: string | null @@ -591,7 +613,9 @@ export type Database = { id?: string name?: string operated_from?: string | null + operated_from_precision?: string | null operated_until?: string | null + operated_until_precision?: string | null original_ride_id?: string | null park_id?: string | null relocated_to_park_id?: string | null @@ -891,6 +915,7 @@ export type Database = { card_image_id: string | null card_image_url: string | null closing_date: string | null + closing_date_precision: string | null created_at: string description: string | null email: string | null @@ -898,6 +923,7 @@ export type Database = { location_id: string | null name: string opening_date: string | null + opening_date_precision: string | null operator_id: string | null park_type: string phone: string | null @@ -914,6 +940,7 @@ export type Database = { card_image_id?: string | null card_image_url?: string | null closing_date?: string | null + closing_date_precision?: string | null created_at?: string description?: string | null email?: string | null @@ -921,6 +948,7 @@ export type Database = { location_id?: string | null name: string opening_date?: string | null + opening_date_precision?: string | null operator_id?: string | null park_type: string phone?: string | null @@ -937,6 +965,7 @@ export type Database = { card_image_id?: string | null card_image_url?: string | null closing_date?: string | null + closing_date_precision?: string | null created_at?: string description?: string | null email?: string | null @@ -944,6 +973,7 @@ export type Database = { location_id?: string | null name?: string opening_date?: string | null + opening_date_precision?: string | null operator_id?: string | null park_type?: string phone?: string | null @@ -979,6 +1009,7 @@ export type Database = { card_image_id: string | null card_image_url: string | null closing_date: string | null + closing_date_precision: string | null coaster_count: number | null created_at: string description: string | null @@ -987,6 +1018,7 @@ export type Database = { location_id: string | null name: string opening_date: string | null + opening_date_precision: string | null operator_id: string | null park_type: string phone: string | null @@ -1008,6 +1040,7 @@ export type Database = { card_image_id?: string | null card_image_url?: string | null closing_date?: string | null + closing_date_precision?: string | null coaster_count?: number | null created_at?: string description?: string | null @@ -1016,6 +1049,7 @@ export type Database = { location_id?: string | null name: string opening_date?: string | null + opening_date_precision?: string | null operator_id?: string | null park_type: string phone?: string | null @@ -1037,6 +1071,7 @@ export type Database = { card_image_id?: string | null card_image_url?: string | null closing_date?: string | null + closing_date_precision?: string | null coaster_count?: number | null created_at?: string description?: string | null @@ -1045,6 +1080,7 @@ export type Database = { location_id?: string | null name?: string opening_date?: string | null + opening_date_precision?: string | null operator_id?: string | null park_type?: string phone?: string | null @@ -1090,6 +1126,7 @@ export type Database = { cloudflare_image_url: string created_at: string date_taken: string | null + date_taken_precision: string | null file_size: number | null filename: string | null id: string @@ -1104,6 +1141,7 @@ export type Database = { cloudflare_image_url: string created_at?: string date_taken?: string | null + date_taken_precision?: string | null file_size?: number | null filename?: string | null id?: string @@ -1118,6 +1156,7 @@ export type Database = { cloudflare_image_url?: string created_at?: string date_taken?: string | null + date_taken_precision?: string | null file_size?: number | null filename?: string | null id?: string @@ -1186,6 +1225,7 @@ export type Database = { cloudflare_image_url: string created_at: string date_taken: string | null + date_taken_precision: string | null entity_id: string entity_type: string id: string @@ -1205,6 +1245,7 @@ export type Database = { cloudflare_image_url: string created_at?: string date_taken?: string | null + date_taken_precision?: string | null entity_id: string entity_type: string id?: string @@ -1224,6 +1265,7 @@ export type Database = { cloudflare_image_url?: string created_at?: string date_taken?: string | null + date_taken_precision?: string | null entity_id?: string entity_type?: string id?: string @@ -1715,6 +1757,7 @@ export type Database = { Row: { created_at: string date_changed: string | null + date_changed_precision: string | null former_name: string from_year: number | null id: string @@ -1726,6 +1769,7 @@ export type Database = { Insert: { created_at?: string date_changed?: string | null + date_changed_precision?: string | null former_name: string from_year?: number | null id?: string @@ -1737,6 +1781,7 @@ export type Database = { Update: { created_at?: string date_changed?: string | null + date_changed_precision?: string | null former_name?: string from_year?: number | null id?: string @@ -1797,6 +1842,7 @@ export type Database = { Row: { created_at: string date_changed: string | null + date_changed_precision: string | null former_name: string id: string order_index: number | null @@ -1806,6 +1852,7 @@ export type Database = { Insert: { created_at?: string date_changed?: string | null + date_changed_precision?: string | null former_name: string id?: string order_index?: number | null @@ -1815,6 +1862,7 @@ export type Database = { Update: { created_at?: string date_changed?: string | null + date_changed_precision?: string | null former_name?: string id?: string order_index?: number | null @@ -1885,6 +1933,7 @@ export type Database = { card_image_url: string | null category: string closing_date: string | null + closing_date_precision: string | null coaster_type: string | null created_at: string description: string | null @@ -1903,6 +1952,7 @@ export type Database = { max_speed_kmh: number | null name: string opening_date: string | null + opening_date_precision: string | null park_id: string | null ride_model_id: string | null ride_sub_type: string | null @@ -1921,6 +1971,7 @@ export type Database = { card_image_url?: string | null category: string closing_date?: string | null + closing_date_precision?: string | null coaster_type?: string | null created_at?: string description?: string | null @@ -1939,6 +1990,7 @@ export type Database = { max_speed_kmh?: number | null name: string opening_date?: string | null + opening_date_precision?: string | null park_id?: string | null ride_model_id?: string | null ride_sub_type?: string | null @@ -1957,6 +2009,7 @@ export type Database = { card_image_url?: string | null category?: string closing_date?: string | null + closing_date_precision?: string | null coaster_type?: string | null created_at?: string description?: string | null @@ -1975,6 +2028,7 @@ export type Database = { max_speed_kmh?: number | null name?: string opening_date?: string | null + opening_date_precision?: string | null park_id?: string | null ride_model_id?: string | null ride_sub_type?: string | null @@ -2049,6 +2103,7 @@ export type Database = { card_image_url: string | null category: string closing_date: string | null + closing_date_precision: string | null coaster_type: string | null created_at: string description: string | null @@ -2067,6 +2122,7 @@ export type Database = { max_speed_kmh: number | null name: string opening_date: string | null + opening_date_precision: string | null park_id: string review_count: number | null ride_model_id: string | null @@ -2089,6 +2145,7 @@ export type Database = { card_image_url?: string | null category: string closing_date?: string | null + closing_date_precision?: string | null coaster_type?: string | null created_at?: string description?: string | null @@ -2107,6 +2164,7 @@ export type Database = { max_speed_kmh?: number | null name: string opening_date?: string | null + opening_date_precision?: string | null park_id: string review_count?: number | null ride_model_id?: string | null @@ -2129,6 +2187,7 @@ export type Database = { card_image_url?: string | null category?: string closing_date?: string | null + closing_date_precision?: string | null coaster_type?: string | null created_at?: string description?: string | null @@ -2147,6 +2206,7 @@ export type Database = { max_speed_kmh?: number | null name?: string opening_date?: string | null + opening_date_precision?: string | null park_id?: string review_count?: number | null ride_model_id?: string | null diff --git a/src/lib/entityValidationSchemas.ts b/src/lib/entityValidationSchemas.ts index f641e2a8..0c1e2c7d 100644 --- a/src/lib/entityValidationSchemas.ts +++ b/src/lib/entityValidationSchemas.ts @@ -20,7 +20,9 @@ export const parkValidationSchema = z.object({ const date = new Date(val); return date <= new Date(); }, 'Opening date cannot be in the future'), + opening_date_precision: z.enum(['day', 'month', 'year']).optional(), closing_date: z.string().optional(), + closing_date_precision: z.enum(['day', 'month', 'year']).optional(), location_id: z.string().uuid().optional().nullable(), website_url: z.string().optional().refine((val) => { if (!val || val === '') return true; @@ -63,7 +65,9 @@ export const rideValidationSchema = z.object({ park_id: z.string().uuid().optional().nullable(), designer_id: z.string().uuid().optional().nullable(), opening_date: z.string().optional(), + opening_date_precision: z.enum(['day', 'month', 'year']).optional(), closing_date: z.string().optional(), + closing_date_precision: z.enum(['day', 'month', 'year']).optional(), height_requirement: z.number().min(0, 'Height requirement must be positive').max(300, 'Height requirement must be less than 300cm').optional(), age_requirement: z.number().min(0, 'Age requirement must be positive').max(100, 'Age requirement must be less than 100').optional(), capacity_per_hour: z.number().min(0, 'Capacity must be positive').optional(), @@ -98,6 +102,8 @@ export const companyValidationSchema = z.object({ company_type: z.string().min(1, 'Company type is required'), person_type: z.enum(['company', 'individual', 'firm', 'organization']).optional(), founded_year: z.number().min(1800, 'Founded year must be after 1800').max(currentYear, `Founded year cannot be in the future`).optional(), + founded_date: z.string().optional(), + founded_date_precision: z.enum(['day', 'month', 'year']).optional(), headquarters_location: z.string().max(200, 'Location must be less than 200 characters').optional(), website_url: z.string().optional().refine((val) => { if (!val || val === '') return true; diff --git a/src/types/database.ts b/src/types/database.ts index 2bd99178..909a849d 100644 --- a/src/types/database.ts +++ b/src/types/database.ts @@ -18,7 +18,9 @@ export interface Company { company_type: string; // Allow any string from database person_type: string; // 'company', 'individual', 'firm', 'organization' website_url?: string; - founded_year?: number; + founded_year?: number; // Legacy field + founded_date?: string; + founded_date_precision?: string; headquarters_location?: string; logo_url?: string; banner_image_url?: string; @@ -37,7 +39,9 @@ export interface Park { status: string; // Allow any string from database park_type: string; // Allow any string from database opening_date?: string; + opening_date_precision?: string; closing_date?: string; + closing_date_precision?: string; website_url?: string; phone?: string; email?: string; @@ -85,6 +89,7 @@ export interface RideNameHistory { ride_id: string; former_name: string; date_changed?: string; + date_changed_precision?: string; reason?: string; from_year?: number; to_year?: number; @@ -128,7 +133,9 @@ export interface Ride { ride_sub_type?: string; // Sub-category like "Flying Coaster", "Inverted Coaster", etc. status: string; // Allow any string from database opening_date?: string; + opening_date_precision?: string; closing_date?: string; + closing_date_precision?: string; height_requirement?: number; age_requirement?: number; capacity_per_hour?: number; diff --git a/src/types/submission-data.ts b/src/types/submission-data.ts index 5320b1bb..18bcd8b8 100644 --- a/src/types/submission-data.ts +++ b/src/types/submission-data.ts @@ -10,7 +10,9 @@ export interface ParkSubmissionData { park_type: string; status: string; opening_date?: string | null; + opening_date_precision?: string | null; closing_date?: string | null; + closing_date_precision?: string | null; website_url?: string | null; phone?: string | null; email?: string | null; @@ -35,7 +37,9 @@ export interface RideSubmissionData { manufacturer_id?: string | null; designer_id?: string | null; opening_date?: string | null; + opening_date_precision?: string | null; closing_date?: string | null; + closing_date_precision?: string | null; height_requirement?: number | null; age_requirement?: number | null; capacity_per_hour?: number | null; @@ -61,7 +65,9 @@ export interface CompanySubmissionData { slug: string; description?: string | null; person_type?: 'company' | 'individual'; - founded_year?: number | null; + founded_year?: number | null; // Legacy field + founded_date?: string | null; + founded_date_precision?: string | null; headquarters_location?: string | null; website_url?: string | null; logo_url?: string | null; diff --git a/supabase/migrations/20251010185634_375d6c7d-5497-4888-b7c3-267ee1cf31bb.sql b/supabase/migrations/20251010185634_375d6c7d-5497-4888-b7c3-267ee1cf31bb.sql new file mode 100644 index 00000000..38f09ee2 --- /dev/null +++ b/supabase/migrations/20251010185634_375d6c7d-5497-4888-b7c3-267ee1cf31bb.sql @@ -0,0 +1,85 @@ +-- Add date precision columns to all tables with date fields + +-- Parks +ALTER TABLE parks + ADD COLUMN IF NOT EXISTS opening_date_precision TEXT CHECK (opening_date_precision IN ('day', 'month', 'year')), + ADD COLUMN IF NOT EXISTS closing_date_precision TEXT CHECK (closing_date_precision IN ('day', 'month', 'year')); + +ALTER TABLE park_submissions + ADD COLUMN IF NOT EXISTS opening_date_precision TEXT CHECK (opening_date_precision IN ('day', 'month', 'year')), + ADD COLUMN IF NOT EXISTS closing_date_precision TEXT CHECK (closing_date_precision IN ('day', 'month', 'year')); + +-- Rides +ALTER TABLE rides + ADD COLUMN IF NOT EXISTS opening_date_precision TEXT CHECK (opening_date_precision IN ('day', 'month', 'year')), + ADD COLUMN IF NOT EXISTS closing_date_precision TEXT CHECK (closing_date_precision IN ('day', 'month', 'year')); + +ALTER TABLE ride_submissions + ADD COLUMN IF NOT EXISTS opening_date_precision TEXT CHECK (opening_date_precision IN ('day', 'month', 'year')), + ADD COLUMN IF NOT EXISTS closing_date_precision TEXT CHECK (closing_date_precision IN ('day', 'month', 'year')); + +-- Ride name history +ALTER TABLE ride_name_history + ADD COLUMN IF NOT EXISTS date_changed_precision TEXT CHECK (date_changed_precision IN ('day', 'month', 'year')); + +ALTER TABLE ride_submission_name_history + ADD COLUMN IF NOT EXISTS date_changed_precision TEXT CHECK (date_changed_precision IN ('day', 'month', 'year')); + +-- Photos +ALTER TABLE photos + ADD COLUMN IF NOT EXISTS date_taken_precision TEXT CHECK (date_taken_precision IN ('day', 'month', 'year')); + +ALTER TABLE photo_submission_items + ADD COLUMN IF NOT EXISTS date_taken_precision TEXT CHECK (date_taken_precision IN ('day', 'month', 'year')); + +-- Companies: Add founded_date to replace founded_year +ALTER TABLE companies + ADD COLUMN IF NOT EXISTS founded_date DATE, + ADD COLUMN IF NOT EXISTS founded_date_precision TEXT CHECK (founded_date_precision IN ('day', 'month', 'year')); + +-- Migrate existing founded_year data to founded_date +UPDATE companies +SET + founded_date = make_date(founded_year, 1, 1), + founded_date_precision = 'year' +WHERE founded_year IS NOT NULL + AND founded_date IS NULL; + +-- Company submissions +ALTER TABLE company_submissions + ADD COLUMN IF NOT EXISTS founded_date DATE, + ADD COLUMN IF NOT EXISTS founded_date_precision TEXT CHECK (founded_date_precision IN ('day', 'month', 'year')); + +UPDATE company_submissions +SET + founded_date = make_date(founded_year, 1, 1), + founded_date_precision = 'year' +WHERE founded_year IS NOT NULL + AND founded_date IS NULL; + +-- Historical entities +ALTER TABLE historical_parks + ADD COLUMN IF NOT EXISTS operated_from_precision TEXT CHECK (operated_from_precision IN ('day', 'month', 'year')), + ADD COLUMN IF NOT EXISTS operated_until_precision TEXT CHECK (operated_until_precision IN ('day', 'month', 'year')); + +ALTER TABLE historical_rides + ADD COLUMN IF NOT EXISTS operated_from_precision TEXT CHECK (operated_from_precision IN ('day', 'month', 'year')), + ADD COLUMN IF NOT EXISTS operated_until_precision TEXT CHECK (operated_until_precision IN ('day', 'month', 'year')); + +-- Set default precision for existing dates (assume full date precision) +UPDATE parks SET opening_date_precision = 'day' WHERE opening_date IS NOT NULL AND opening_date_precision IS NULL; +UPDATE parks SET closing_date_precision = 'day' WHERE closing_date IS NOT NULL AND closing_date_precision IS NULL; +UPDATE park_submissions SET opening_date_precision = 'day' WHERE opening_date IS NOT NULL AND opening_date_precision IS NULL; +UPDATE park_submissions SET closing_date_precision = 'day' WHERE closing_date IS NOT NULL AND closing_date_precision IS NULL; +UPDATE rides SET opening_date_precision = 'day' WHERE opening_date IS NOT NULL AND opening_date_precision IS NULL; +UPDATE rides SET closing_date_precision = 'day' WHERE closing_date IS NOT NULL AND closing_date_precision IS NULL; +UPDATE ride_submissions SET opening_date_precision = 'day' WHERE opening_date IS NOT NULL AND opening_date_precision IS NULL; +UPDATE ride_submissions SET closing_date_precision = 'day' WHERE closing_date IS NOT NULL AND closing_date_precision IS NULL; +UPDATE ride_name_history SET date_changed_precision = 'day' WHERE date_changed IS NOT NULL AND date_changed_precision IS NULL; +UPDATE ride_submission_name_history SET date_changed_precision = 'day' WHERE date_changed IS NOT NULL AND date_changed_precision IS NULL; +UPDATE photos SET date_taken_precision = 'day' WHERE date_taken IS NOT NULL AND date_taken_precision IS NULL; +UPDATE photo_submission_items SET date_taken_precision = 'day' WHERE date_taken IS NOT NULL AND date_taken_precision IS NULL; +UPDATE historical_parks SET operated_from_precision = 'day' WHERE operated_from IS NOT NULL AND operated_from_precision IS NULL; +UPDATE historical_parks SET operated_until_precision = 'day' WHERE operated_until IS NOT NULL AND operated_until_precision IS NULL; +UPDATE historical_rides SET operated_from_precision = 'day' WHERE operated_from IS NOT NULL AND operated_from_precision IS NULL; +UPDATE historical_rides SET operated_until_precision = 'day' WHERE operated_until IS NOT NULL AND operated_until_precision IS NULL; \ No newline at end of file