import { pgTable, uuid, text, timestamp, index, primaryKey } from 'drizzle-orm/pg-core'; import { generations } from '../generations/schema'; /** * A named set of images — an afternoon's work, an icon suite, a client. * * `name` is unique, and that is load-bearing rather than tidy: the generation API accepts a * collection by name and creates it when it does not exist, so without the constraint a second * request with the same name would quietly start a second collection and split the batch in two. */ export const collections = pgTable('collections', { id: uuid('id').primaryKey().defaultRandom(), name: text('name').notNull().unique(), description: text('description'), createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(), }); /** * Membership, as a join table rather than a column on `generations`. * * An image belongs to as many collections as it earns: the icon that came out of Tuesday's session is * in "tuesday" and also in "shipped", and removing it from one must not touch the other. A * collection_id column would force a choice at generation time and make re-filing a destructive edit. * * Both sides cascade. Deleting a collection removes its memberships and NOT its images — a collection * is a way of looking at generations, not a container that owns them. Deleting a generation removes * its memberships, since a row pointing at nothing is only a way to crash a join later. */ export const collectionItems = pgTable( 'collection_items', { collectionId: uuid('collection_id') .notNull() .references(() => collections.id, { onDelete: 'cascade' }), generationId: uuid('generation_id') .notNull() .references(() => generations.id, { onDelete: 'cascade' }), addedAt: timestamp('added_at', { withTimezone: true }).notNull().defaultNow(), }, (table) => [ // The composite key is what makes adding an image twice a no-op instead of a duplicate. primaryKey({ columns: [table.collectionId, table.generationId] }), index('collection_items_generation_idx').on(table.generationId), ], );