game-master/src/server/db/schema.ts

183 lines
5.0 KiB
TypeScript

import { relations, sql } from "drizzle-orm";
import { pgTableCreator, index, primaryKey } from "drizzle-orm/pg-core";
import { type AdapterAccount } from "next-auth/adapters";
import { createId } from "@paralleldrive/cuid2";
/**
* This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same
* database instance for multiple projects.
*
* @see https://orm.drizzle.team/docs/goodies#multi-project-schema
*/
export const createTable = pgTableCreator((name) => `game-master_${name}`);
const defaultTimeStamp = (name: string, d: any) =>
d
.timestamp(name, { withTimezone: true })
.default(sql`CURRENT_TIMESTAMP`)
.notNull();
export const lobbies = createTable("lobby", (d) => ({
id: d
.varchar({ length: 255 })
.primaryKey()
.notNull()
.$defaultFn(() => createId()),
name: d.varchar({ length: 255 }).notNull(),
maxPlayers: d.integer().notNull().default(0),
createdById: d
.varchar({ length: 255 })
.notNull()
.references(() => players.id, { onDelete: "cascade" }),
createdAt: defaultTimeStamp("created_at", d),
updatedAt: d
.timestamp("updated_at", { withTimezone: true })
.$onUpdate(() => new Date()),
}));
export type Lobby = typeof lobbies.$inferSelect & {
members?: LobbyMember[];
leader?: Player;
};
export const lobbyRelations = relations(lobbies, ({ many, one }) => ({
leader: one(players, {
fields: [lobbies.createdById],
references: [players.id],
}),
members: many(lobbyMembers),
}));
export const lobbyMembers = createTable(
"lobby_member",
(d) => ({
playerId: d
.varchar({ length: 255 })
.notNull()
.references(() => players.id, { onDelete: "cascade" }),
lobbyId: d
.varchar({ length: 255 })
.notNull()
.references(() => lobbies.id, { onDelete: "cascade" }),
joinedAt: defaultTimeStamp("joined_at", d),
role: d
.varchar({ length: 255 })
.notNull()
.$type<LobbyMemberRole>()
.default("player"),
isReady: d.boolean().notNull(),
}),
(t) => [primaryKey({ columns: [t.playerId] })],
);
export type LobbyMember = typeof lobbyMembers.$inferSelect & {
player?: Player;
};
export const lobbyMembersRelations = relations(lobbyMembers, ({ one }) => ({
lobby: one(lobbies, {
fields: [lobbyMembers.lobbyId],
references: [lobbies.id],
}),
player: one(players, {
fields: [lobbyMembers.playerId],
references: [players.id],
}),
}));
export const players = createTable(
"player",
(d) => ({
id: d
.varchar({ length: 255 })
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
displayName: d.varchar({ length: 255 }),
avatar: d.varchar({ length: 255 }),
joinedAt: defaultTimeStamp("joined_at", d),
}),
(t) => [
primaryKey({
columns: [t.id],
}),
],
);
export type Player = typeof players.$inferSelect;
export const users = createTable("user", (d) => ({
id: d
.varchar({ length: 255 })
.notNull()
.primaryKey()
.$defaultFn(() => createId()),
name: d.varchar({ length: 255 }),
email: d.varchar({ length: 255 }).notNull(),
emailVerified: d
.timestamp("email_verified", {
mode: "date",
withTimezone: true,
})
.default(sql`CURRENT_TIMESTAMP`),
}));
export const usersRelations = relations(users, ({ many }) => ({
accounts: many(accounts),
sessions: many(sessions),
}));
export const accounts = createTable(
"account",
(d) => ({
userId: d
.varchar({ length: 255 })
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
type: d.varchar({ length: 255 }).$type<AdapterAccount["type"]>().notNull(),
provider: d.varchar({ length: 255 }).notNull(),
providerAccountId: d.varchar({ length: 255 }).notNull(),
refresh_token: d.text(),
access_token: d.text(),
expires_at: d.integer(),
token_type: d.varchar({ length: 255 }),
scope: d.varchar({ length: 255 }),
id_token: d.text(),
session_state: d.varchar({ length: 255 }),
}),
(t) => [
primaryKey({
columns: [t.provider, t.providerAccountId],
}),
index("account_user_id_idx").on(t.userId),
],
);
export const accountsRelations = relations(accounts, ({ one }) => ({
user: one(users, { fields: [accounts.userId], references: [users.id] }),
}));
export const sessions = createTable(
"session",
(d) => ({
sessionToken: d.varchar({ length: 255 }).notNull().primaryKey(),
userId: d
.varchar({ length: 255 })
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
expires: d.timestamp({ mode: "date" }).notNull(),
}),
(t) => [index("session_user_id_idx").on(t.userId)],
);
export const sessionsRelations = relations(sessions, ({ one }) => ({
user: one(users, { fields: [sessions.userId], references: [users.id] }),
}));
export const verificationTokens = createTable(
"verification_token",
(d) => ({
identifier: d.varchar({ length: 255 }).notNull(),
token: d.varchar({ length: 255 }).notNull(),
expires: d.timestamp({ mode: "date" }).notNull(),
}),
(t) => [primaryKey({ columns: [t.identifier, t.token] })],
);