166 lines
5.1 KiB
TypeScript
Executable File
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),
|
|
})
|
|
);
|
|
|