166 lines
5.1 KiB
TypeScript
Executable File

// https://orm.drizzle.team/docs/sql-schema-declaration
import { db } from '~/server/db';
import { sql } from "drizzle-orm";
import {
boolean,
index,
integer,
jsonb,
numeric,
pgEnum,
pgTable,
serial,
text,
timestamp,
varchar,
} from "drizzle-orm/pg-core";
export const users = pgTable(
'users',
{
id: serial('id').primaryKey(),
appleId: varchar('apple_id', { length: 200 }).unique(),
email: varchar('email', { length: 100 }).unique().notNull(),
fullName: varchar('full_name', { length: 100 }).notNull(),
pfpUrl: varchar('pfp_url', { length: 255 }),
pushToken: varchar('push_token', { length: 100 }).unique().notNull(),
createdAt: timestamp('created_at', { withTimezone: true })
.default(sql`CURRENT_TIMESTAMP`).notNull(),
metadata: jsonb('metadata'),
},
(table) => ({
appleIdIndex: index('users_apple_id_idx').on(table.appleId),
emailIndex: index('users_email_idx').on(table.email),
fullNameIndex: index('users_full_name_idx').on(table.fullName),
})
);
export const relationships = pgTable(
'relationships',
{
id: serial('id').primaryKey(),
title: varchar('title', { length: 50 })
.default("My Relationship").notNull(),
requestorId: integer('requestor_id').references(() => users.id).notNull(),
isAccepted: boolean('is_accepted').default(false),
relationshipStartDate: timestamp('relationship_start_date', { withTimezone: true })
.default(sql`CURRENT_TIMESTAMP`).notNull(),
},
(table) => ({
requestorIdIndex: index('relationships_requestor_id_idx').on(table.requestorId),
})
);
export const userRelationships = pgTable(
'user_relationships',
{
id: serial('id').primaryKey(),
userId: integer('user_id').references(() => users.id).notNull(),
relationshipId: integer('relationship_id').references(() => relationships.id).notNull(),
},
(table) => ({
userIdIndex: index('user_relationships_user_id_idx').on(table.userId),
relationshipIdIndex: index('user_relationships_relationship_id_idx').on(table.relationshipId),
})
);
export const countdowns = pgTable(
'countdowns',
{
id: serial('id').primaryKey(),
relationshipId: integer('relationship_id').references(() => relationships.id).notNull(),
title: varchar('title', { length: 50 })
.default('Countdown to Next Visit').notNull(),
date: timestamp('date', { withTimezone: true }).notNull(),
createdAt: timestamp('created_at', { withTimezone: true })
.default(sql`CURRENT_TIMESTAMP`).notNull(),
},
(table) => ({
relationshipIdIndex: index('countdowns_relationship_id_idx').on(table.relationshipId),
})
);
export const messages = pgTable(
'messages',
{
id: serial('id').primaryKey(),
senderId: integer('sender_id').references(() => users.id).notNull(),
receiverId: integer('receiver_id').references(() => users.id).notNull(),
text: text('text').notNull(),
createdAt: timestamp('created_at', { withTimezone: true })
.default(sql`CURRENT_TIMESTAMP`).notNull(),
isRead: boolean('is_read').default(false),
hasLocation: boolean('has_location').default(false),
hasMedia: boolean('has_media').default(false),
hasQuickReply: boolean('has_quick_reply').default(false),
},
(table) => ({
senderIdIndex: index('messages_sender_id_idx').on(table.senderId),
receiverIdIndex: index('messages_receiver_id_idx').on(table.receiverId),
})
);
export const mediaTypes = pgEnum(
'message_media_types',
['image', 'video', 'audio', 'file']
);
export const media = pgTable(
'media',
{
id: serial('id').primaryKey(),
messageId: integer('message_id').references(() => messages.id).notNull(),
type: mediaTypes('type').notNull(),
url: varchar('url', { length: 255 }).notNull(),
size: numeric('size'),
metadata: varchar('metadata', { length: 255 }),
order: integer('order'),
},
(table) => ({
messageIdIndex: index('media_message_id_idx').on(table.messageId),
})
);
export const locations = pgTable(
'locations',
{
id: serial('id').primaryKey(),
messageId: integer('message_id').references(() => messages.id).notNull(),
latitude: numeric('latitude').notNull(),
longitude: numeric('longitude').notNull(),
},
(table) => ({
messageIdIndex: index('locations_message_id_idx').on(table.messageId),
})
);
export const quickReplyType = pgEnum(
'quick_reply_types',
['radio', 'checkbox']
);
export const quickReplies = pgTable(
'quick_replies',
{
id: serial('id').primaryKey(),
messageId: integer('message_id').references(() => messages.id).notNull(),
type: quickReplyType('type').notNull(),
keepIt: boolean('keep_it').default(false),
},
(table) => ({
messageIdIndex: index('quick_replies_message_id_idx').on(table.messageId),
})
);
export const quickReplyOptions = pgTable(
'quick_reply_options',
{
id: serial('id').primaryKey(),
quickReplyId: integer('quick_reply_id').references(() => quickReplies.id).notNull(),
title: varchar('title', { length: 100 }).notNull(),
value: varchar('value', { length: 100 }).notNull(),
},
(table) => ({
quickReplyIdIndex: index('qr_options_quick_reply_id_idx').on(table.quickReplyId),
})
);