Add human-readable event URL slugs with legacy redirect support.
Store unique slugs on events, backfill existing records, redirect old UUID and alias URLs to canonical slug pages, and expose slug editing plus alias management in the admin event modal. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -62,6 +62,7 @@ export const sqliteInvoices = sqliteTable('invoices', {
|
||||
|
||||
export const sqliteEvents = sqliteTable('events', {
|
||||
id: text('id').primaryKey(),
|
||||
slug: text('slug').unique(),
|
||||
title: text('title').notNull(),
|
||||
titleEs: text('title_es'),
|
||||
description: text('description').notNull(),
|
||||
@@ -83,6 +84,13 @@ export const sqliteEvents = sqliteTable('events', {
|
||||
updatedAt: text('updated_at').notNull(),
|
||||
});
|
||||
|
||||
// Historical slugs that still resolve (and redirect) to an event's canonical slug
|
||||
export const sqliteEventSlugAliases = sqliteTable('event_slug_aliases', {
|
||||
slug: text('slug').primaryKey(),
|
||||
eventId: text('event_id').notNull().references(() => sqliteEvents.id),
|
||||
createdAt: text('created_at').notNull(),
|
||||
});
|
||||
|
||||
export const sqliteTickets = sqliteTable('tickets', {
|
||||
id: text('id').primaryKey(),
|
||||
bookingId: text('booking_id'), // Groups multiple tickets from same booking
|
||||
@@ -387,6 +395,7 @@ export const pgInvoices = pgTable('invoices', {
|
||||
|
||||
export const pgEvents = pgTable('events', {
|
||||
id: uuid('id').primaryKey(),
|
||||
slug: varchar('slug', { length: 255 }).unique(),
|
||||
title: varchar('title', { length: 255 }).notNull(),
|
||||
titleEs: varchar('title_es', { length: 255 }),
|
||||
description: pgText('description').notNull(),
|
||||
@@ -408,6 +417,13 @@ export const pgEvents = pgTable('events', {
|
||||
updatedAt: timestamp('updated_at').notNull(),
|
||||
});
|
||||
|
||||
// Historical slugs that still resolve (and redirect) to an event's canonical slug
|
||||
export const pgEventSlugAliases = pgTable('event_slug_aliases', {
|
||||
slug: varchar('slug', { length: 255 }).primaryKey(),
|
||||
eventId: uuid('event_id').notNull().references(() => pgEvents.id),
|
||||
createdAt: timestamp('created_at').notNull(),
|
||||
});
|
||||
|
||||
export const pgTickets = pgTable('tickets', {
|
||||
id: uuid('id').primaryKey(),
|
||||
bookingId: uuid('booking_id'), // Groups multiple tickets from same booking
|
||||
@@ -649,6 +665,7 @@ export const pgSiteSettings = pgTable('site_settings', {
|
||||
// Export the appropriate schema based on DB_TYPE
|
||||
export const users = dbType === 'postgres' ? pgUsers : sqliteUsers;
|
||||
export const events = dbType === 'postgres' ? pgEvents : sqliteEvents;
|
||||
export const eventSlugAliases = dbType === 'postgres' ? pgEventSlugAliases : sqliteEventSlugAliases;
|
||||
export const tickets = dbType === 'postgres' ? pgTickets : sqliteTickets;
|
||||
export const payments = dbType === 'postgres' ? pgPayments : sqlitePayments;
|
||||
export const contacts = dbType === 'postgres' ? pgContacts : sqliteContacts;
|
||||
|
||||
Reference in New Issue
Block a user