diff --git a/apps/backend/drizzle/0002_fat_ted_forrester.sql b/apps/backend/drizzle/0002_fat_ted_forrester.sql new file mode 100644 index 000000000..aed6916cd --- /dev/null +++ b/apps/backend/drizzle/0002_fat_ted_forrester.sql @@ -0,0 +1,7 @@ +ALTER TABLE "users" DROP CONSTRAINT "users_current_schedule_id_schedules_id_fk"; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "users" ADD CONSTRAINT "users_current_schedule_id_schedules_id_fk" FOREIGN KEY ("current_schedule_id") REFERENCES "public"."schedules"("id") ON DELETE set null ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; diff --git a/apps/backend/drizzle/meta/0002_snapshot.json b/apps/backend/drizzle/meta/0002_snapshot.json new file mode 100644 index 000000000..4c2e74399 --- /dev/null +++ b/apps/backend/drizzle/meta/0002_snapshot.json @@ -0,0 +1,438 @@ +{ + "id": "1653e3a7-93bd-4f8b-b7e5-8b6cda63fa4f", + "prevId": "980b5d8b-81c6-47e7-b979-90b189a98f30", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.accounts": { + "name": "accounts", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "account_type": { + "name": "account_type", + "type": "account_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "provider_account_id": { + "name": "provider_account_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "accounts_user_id_users_id_fk": { + "name": "accounts_user_id_users_id_fk", + "tableFrom": "accounts", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "accounts_user_id_account_type_pk": { + "name": "accounts_user_id_account_type_pk", + "columns": ["user_id", "account_type"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sessions": { + "name": "sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "phone": { + "name": "phone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "avatar": { + "name": "avatar", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "current_schedule_id": { + "name": "current_schedule_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_updated": { + "name": "last_updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "users_current_schedule_id_schedules_id_fk": { + "name": "users_current_schedule_id_schedules_id_fk", + "tableFrom": "users", + "tableTo": "schedules", + "columnsFrom": ["current_schedule_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.schedules": { + "name": "schedules", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "last_updated": { + "name": "last_updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "schedules_user_id_users_id_fk": { + "name": "schedules_user_id_users_id_fk", + "tableFrom": "schedules", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "schedules_user_id_name_unique": { + "name": "schedules_user_id_name_unique", + "nullsNotDistinct": false, + "columns": ["user_id", "name"] + }, + "schedules_user_id_index_unique": { + "name": "schedules_user_id_index_unique", + "nullsNotDistinct": false, + "columns": ["user_id", "index"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.coursesInSchedule": { + "name": "coursesInSchedule", + "schema": "", + "columns": { + "scheduleId": { + "name": "scheduleId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sectionCode": { + "name": "sectionCode", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "term": { + "name": "term", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "last_updated": { + "name": "last_updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "coursesInSchedule_scheduleId_schedules_id_fk": { + "name": "coursesInSchedule_scheduleId_schedules_id_fk", + "tableFrom": "coursesInSchedule", + "tableTo": "schedules", + "columnsFrom": ["scheduleId"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "coursesInSchedule_scheduleId_sectionCode_term_pk": { + "name": "coursesInSchedule_scheduleId_sectionCode_term_pk", + "columns": ["scheduleId", "sectionCode", "term"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.customEvents": { + "name": "customEvents", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "scheduleId": { + "name": "scheduleId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "start": { + "name": "start", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "end": { + "name": "end", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "days": { + "name": "days", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "building": { + "name": "building", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_updated": { + "name": "last_updated", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "customEvents_scheduleId_schedules_id_fk": { + "name": "customEvents_scheduleId_schedules_id_fk", + "tableFrom": "customEvents", + "tableTo": "schedules", + "columnsFrom": ["scheduleId"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.subscriptions": { + "name": "subscriptions", + "schema": "", + "columns": { + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sectionCode": { + "name": "sectionCode", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "subscription_target_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "subscriptions_userId_users_id_fk": { + "name": "subscriptions_userId_users_id_fk", + "tableFrom": "subscriptions", + "tableTo": "users", + "columnsFrom": ["userId"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "subscriptions_userId_sectionCode_pk": { + "name": "subscriptions_userId_sectionCode_pk", + "columns": ["userId", "sectionCode"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.account_type": { + "name": "account_type", + "schema": "public", + "values": ["GOOGLE", "GUEST"] + }, + "public.subscription_target_status": { + "name": "subscription_target_status", + "schema": "public", + "values": ["OPEN", "WAITLISTED"] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/apps/backend/drizzle/meta/_journal.json b/apps/backend/drizzle/meta/_journal.json index 5cd7b0075..536882b04 100644 --- a/apps/backend/drizzle/meta/_journal.json +++ b/apps/backend/drizzle/meta/_journal.json @@ -15,6 +15,13 @@ "when": 1732515819685, "tag": "0001_powerful_tiger_shark", "breakpoints": true + }, + { + "idx": 2, + "version": "7", + "when": 1732578460427, + "tag": "0002_fat_ted_forrester", + "breakpoints": true } ] } diff --git a/apps/backend/src/db/schema/auth/user.ts b/apps/backend/src/db/schema/auth/user.ts index 295c997e8..ed03ad98d 100644 --- a/apps/backend/src/db/schema/auth/user.ts +++ b/apps/backend/src/db/schema/auth/user.ts @@ -33,7 +33,8 @@ export const users = pgTable('users', { currentScheduleId: text('current_schedule_id') .references( // Necessary because this is a circular dependency. - (): AnyPgColumn => schedules.id + (): AnyPgColumn => schedules.id, + { onDelete: 'set null'} ), lastUpdated: timestamp('last_updated', { withTimezone: true }).defaultNow(),