From 3c074f72b45535cb55c4f63cb465ab080bef1e23 Mon Sep 17 00:00:00 2001 From: Jake Bromberg Date: Sat, 21 Feb 2026 09:00:23 -0800 Subject: [PATCH 1/3] fix: add unique constraint on show_djs (show_id, dj_id) The junction table had no uniqueness constraint, allowing a DJ to be inserted into the same show multiple times. Co-authored-by: Cursor --- shared/database/src/schema.ts | 22 ++++++++++++--------- tests/unit/database/schema.show-djs.test.ts | 17 ++++++++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 tests/unit/database/schema.show-djs.test.ts diff --git a/shared/database/src/schema.ts b/shared/database/src/schema.ts index 27cb154b..1b731153 100644 --- a/shared/database/src/schema.ts +++ b/shared/database/src/schema.ts @@ -394,15 +394,19 @@ export const shows = wxyc_schema.table('shows', { export type NewShowDJ = InferInsertModel; export type ShowDJ = InferSelectModel; -export const show_djs = wxyc_schema.table('show_djs', { - show_id: integer('show_id') - .references(() => shows.id) - .notNull(), - dj_id: varchar('dj_id', { length: 255 }) - .references(() => user.id, { onDelete: 'cascade' }) - .notNull(), - active: boolean('active').default(true), -}); +export const show_djs = wxyc_schema.table( + 'show_djs', + { + show_id: integer('show_id') + .references(() => shows.id) + .notNull(), + dj_id: varchar('dj_id', { length: 255 }) + .references(() => user.id, { onDelete: 'cascade' }) + .notNull(), + active: boolean('active').default(true), + }, + (table) => [uniqueIndex('show_djs_show_id_dj_id_unique').on(table.show_id, table.dj_id)] +); //create entry w/ ID 0 for regular shows export type NewSpecialtyShow = InferInsertModel; diff --git a/tests/unit/database/schema.show-djs.test.ts b/tests/unit/database/schema.show-djs.test.ts new file mode 100644 index 00000000..a1ea323b --- /dev/null +++ b/tests/unit/database/schema.show-djs.test.ts @@ -0,0 +1,17 @@ +import { getTableConfig } from 'drizzle-orm/pg-core'; +import { show_djs } from '../../../shared/database/src/schema'; + +describe('show_djs schema', () => { + it('has a unique index on (show_id, dj_id)', () => { + const config = getTableConfig(show_djs); + const uniqueIndexes = config.indexes.filter((idx) => idx.config.unique); + + const showDjIndex = uniqueIndexes.find((idx) => + idx.config.columns.length === 2 && + idx.config.columns.some((col) => 'name' in col && col.name === 'show_id') && + idx.config.columns.some((col) => 'name' in col && col.name === 'dj_id') + ); + + expect(showDjIndex).toBeDefined(); + }); +}); From cbfab610dcf2292eb80b65e5351adee7bea36251 Mon Sep 17 00:00:00 2001 From: Jake Bromberg Date: Fri, 27 Feb 2026 09:48:10 -0800 Subject: [PATCH 2/3] style: format files with Prettier --- tests/unit/database/schema.show-djs.test.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/unit/database/schema.show-djs.test.ts b/tests/unit/database/schema.show-djs.test.ts index a1ea323b..a3bda349 100644 --- a/tests/unit/database/schema.show-djs.test.ts +++ b/tests/unit/database/schema.show-djs.test.ts @@ -6,10 +6,11 @@ describe('show_djs schema', () => { const config = getTableConfig(show_djs); const uniqueIndexes = config.indexes.filter((idx) => idx.config.unique); - const showDjIndex = uniqueIndexes.find((idx) => - idx.config.columns.length === 2 && - idx.config.columns.some((col) => 'name' in col && col.name === 'show_id') && - idx.config.columns.some((col) => 'name' in col && col.name === 'dj_id') + const showDjIndex = uniqueIndexes.find( + (idx) => + idx.config.columns.length === 2 && + idx.config.columns.some((col) => 'name' in col && col.name === 'show_id') && + idx.config.columns.some((col) => 'name' in col && col.name === 'dj_id') ); expect(showDjIndex).toBeDefined(); From 0360e00481f9d320c09c06f4d583c10d44fd0765 Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Mon, 9 Mar 2026 18:11:20 -0400 Subject: [PATCH 3/3] Add `and` and `or` mocks for jest --- tests/__mocks__/drizzle-orm.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/__mocks__/drizzle-orm.ts b/tests/__mocks__/drizzle-orm.ts index f94cc79f..100bc350 100644 --- a/tests/__mocks__/drizzle-orm.ts +++ b/tests/__mocks__/drizzle-orm.ts @@ -1,5 +1,7 @@ // Mock drizzle-orm for unit tests export const eq = jest.fn((a, b) => ({ eq: [a, b] })); +export const and = jest.fn((...conditions: unknown[]) => ({ and: conditions })); +export const or = jest.fn((...conditions: unknown[]) => ({ or: conditions })); export const sql = Object.assign( jest.fn((strings: TemplateStringsArray, ...values: unknown[]) => ({ sql: strings,