mirror of
https://github.com/Lapikud/tipilan.git
synced 2026-03-23 13:24:21 +00:00
Improve schema readability & maintainability
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { defineConfig } from "drizzle-kit";
|
import { defineConfig } from "drizzle-kit";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
schema: "./src/db/schema.ts",
|
schema: "./src/db/schema/schema.ts",
|
||||||
out: "./migrations",
|
out: "./migrations",
|
||||||
dialect: "sqlite",
|
dialect: "sqlite",
|
||||||
dbCredentials: {
|
dbCredentials: {
|
||||||
|
|||||||
1
migrations/0002_real_korath.sql
Normal file
1
migrations/0002_real_korath.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
DROP INDEX `user_steam_id_unique`;
|
||||||
281
migrations/meta/0002_snapshot.json
Normal file
281
migrations/meta/0002_snapshot.json
Normal file
@@ -0,0 +1,281 @@
|
|||||||
|
{
|
||||||
|
"version": "6",
|
||||||
|
"dialect": "sqlite",
|
||||||
|
"id": "5d600618-0105-4104-b150-c63015ae55c7",
|
||||||
|
"prevId": "eae7a237-8469-4a6a-acac-1910adfc98ff",
|
||||||
|
"tables": {
|
||||||
|
"user": {
|
||||||
|
"name": "user",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"steam_id": {
|
||||||
|
"name": "steam_id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"first_name": {
|
||||||
|
"name": "first_name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"last_name": {
|
||||||
|
"name": "last_name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"ticket_id": {
|
||||||
|
"name": "ticket_id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"ticket_type": {
|
||||||
|
"name": "ticket_type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"user_ticket_id_unique": {
|
||||||
|
"name": "user_ticket_id_unique",
|
||||||
|
"columns": [
|
||||||
|
"ticket_id"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {}
|
||||||
|
},
|
||||||
|
"team": {
|
||||||
|
"name": "team",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {}
|
||||||
|
},
|
||||||
|
"member": {
|
||||||
|
"name": "member",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"user_id": {
|
||||||
|
"name": "user_id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"team_id": {
|
||||||
|
"name": "team_id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"name": "role",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"user_team_unique": {
|
||||||
|
"name": "user_team_unique",
|
||||||
|
"columns": [
|
||||||
|
"user_id",
|
||||||
|
"team_id"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {
|
||||||
|
"member_user_id_user_id_fk": {
|
||||||
|
"name": "member_user_id_user_id_fk",
|
||||||
|
"tableFrom": "member",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"user_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"member_team_id_team_id_fk": {
|
||||||
|
"name": "member_team_id_team_id_fk",
|
||||||
|
"tableFrom": "member",
|
||||||
|
"tableTo": "team",
|
||||||
|
"columnsFrom": [
|
||||||
|
"team_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {}
|
||||||
|
},
|
||||||
|
"tournament_team": {
|
||||||
|
"name": "tournament_team",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"tournament_id": {
|
||||||
|
"name": "tournament_id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"team_id": {
|
||||||
|
"name": "team_id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"registration_date": {
|
||||||
|
"name": "registration_date",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"tournament_team_unique": {
|
||||||
|
"name": "tournament_team_unique",
|
||||||
|
"columns": [
|
||||||
|
"tournament_id",
|
||||||
|
"team_id"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {
|
||||||
|
"tournament_team_tournament_id_tournament_id_fk": {
|
||||||
|
"name": "tournament_team_tournament_id_tournament_id_fk",
|
||||||
|
"tableFrom": "tournament_team",
|
||||||
|
"tableTo": "tournament",
|
||||||
|
"columnsFrom": [
|
||||||
|
"tournament_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"tournament_team_team_id_team_id_fk": {
|
||||||
|
"name": "tournament_team_team_id_team_id_fk",
|
||||||
|
"tableFrom": "tournament_team",
|
||||||
|
"tableTo": "team",
|
||||||
|
"columnsFrom": [
|
||||||
|
"team_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {}
|
||||||
|
},
|
||||||
|
"tournament": {
|
||||||
|
"name": "tournament",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"views": {},
|
||||||
|
"enums": {},
|
||||||
|
"_meta": {
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {},
|
||||||
|
"columns": {}
|
||||||
|
},
|
||||||
|
"internal": {
|
||||||
|
"indexes": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,13 @@
|
|||||||
"when": 1752632968857,
|
"when": 1752632968857,
|
||||||
"tag": "0001_cool_ma_gnuci",
|
"tag": "0001_cool_ma_gnuci",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 2,
|
||||||
|
"version": "6",
|
||||||
|
"when": 1754400044471,
|
||||||
|
"tag": "0002_real_korath",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -17,8 +17,6 @@ const workSans = Work_Sans({
|
|||||||
subsets: ["latin"],
|
subsets: ["latin"],
|
||||||
});
|
});
|
||||||
|
|
||||||
// Commented out for now, because it doesn't work having client components in the layout file
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "TipiLAN 2025",
|
title: "TipiLAN 2025",
|
||||||
description: "TipiLAN 2025 – Eesti suurim tudengite korraldatud LAN!",
|
description: "TipiLAN 2025 – Eesti suurim tudengite korraldatud LAN!",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { drizzle } from "drizzle-orm/bun-sqlite";
|
import { drizzle } from "drizzle-orm/bun-sqlite";
|
||||||
import { Database } from "bun:sqlite";
|
import { Database } from "bun:sqlite";
|
||||||
import * as schema from "./schema";
|
import * as schema from "./schema/schema";
|
||||||
|
|
||||||
const sqlite = new Database("data/tipilan.db");
|
const sqlite = new Database("data/tipilan.db");
|
||||||
export const db = drizzle(sqlite, { schema });
|
export const db = drizzle(sqlite, { schema });
|
||||||
|
|||||||
138
src/db/schema.ts
138
src/db/schema.ts
@@ -1,138 +0,0 @@
|
|||||||
import {
|
|
||||||
sqliteTable,
|
|
||||||
text,
|
|
||||||
integer,
|
|
||||||
uniqueIndex,
|
|
||||||
} from "drizzle-orm/sqlite-core";
|
|
||||||
import { relations } from "drizzle-orm";
|
|
||||||
import { createId } from "@paralleldrive/cuid2";
|
|
||||||
|
|
||||||
// Roles enum equivalent
|
|
||||||
export const RoleEnum = {
|
|
||||||
VISITOR: "VISITOR",
|
|
||||||
PARTICIPANT: "PARTICIPANT",
|
|
||||||
TEAMMATE: "TEAMMATE",
|
|
||||||
CAPTAIN: "CAPTAIN",
|
|
||||||
ADMIN: "ADMIN",
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export type Role = (typeof RoleEnum)[keyof typeof RoleEnum];
|
|
||||||
|
|
||||||
// User table
|
|
||||||
export const users = sqliteTable("user", {
|
|
||||||
id: text("id")
|
|
||||||
.primaryKey()
|
|
||||||
.notNull()
|
|
||||||
.$defaultFn(() => createId()),
|
|
||||||
email: text("email").notNull(),
|
|
||||||
steamId: text("steam_id").unique(),
|
|
||||||
firstName: text("first_name").notNull(),
|
|
||||||
lastName: text("last_name").notNull(),
|
|
||||||
ticketId: text("ticket_id").unique(),
|
|
||||||
ticketType: text("ticket_type"),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Team table
|
|
||||||
export const teams = sqliteTable("team", {
|
|
||||||
id: text("id")
|
|
||||||
.primaryKey()
|
|
||||||
.notNull()
|
|
||||||
.$defaultFn(() => createId()),
|
|
||||||
name: text("name").notNull(),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Member table (join table for User and Team with role)
|
|
||||||
export const members = sqliteTable(
|
|
||||||
"member",
|
|
||||||
{
|
|
||||||
id: text("id")
|
|
||||||
.primaryKey()
|
|
||||||
.notNull()
|
|
||||||
.$defaultFn(() => createId()),
|
|
||||||
userId: text("user_id")
|
|
||||||
.notNull()
|
|
||||||
.references(() => users.id, { onDelete: "cascade" }),
|
|
||||||
teamId: text("team_id").references(() => teams.id, { onDelete: "cascade" }),
|
|
||||||
role: text("role", {
|
|
||||||
enum: Object.values(RoleEnum) as [string, ...string[]],
|
|
||||||
}).notNull(),
|
|
||||||
},
|
|
||||||
(table) => {
|
|
||||||
return {
|
|
||||||
userTeamUnique: uniqueIndex("user_team_unique").on(
|
|
||||||
table.userId,
|
|
||||||
table.teamId,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Tournament table
|
|
||||||
export const tournaments = sqliteTable("tournament", {
|
|
||||||
id: text("id")
|
|
||||||
.primaryKey()
|
|
||||||
.notNull()
|
|
||||||
.$defaultFn(() => createId()),
|
|
||||||
name: text("name").notNull(),
|
|
||||||
});
|
|
||||||
|
|
||||||
// TournamentTeam join table
|
|
||||||
export const tournamentTeams = sqliteTable(
|
|
||||||
"tournament_team",
|
|
||||||
{
|
|
||||||
id: text("id")
|
|
||||||
.primaryKey()
|
|
||||||
.notNull()
|
|
||||||
.$defaultFn(() => createId()),
|
|
||||||
tournamentId: text("tournament_id")
|
|
||||||
.notNull()
|
|
||||||
.references(() => tournaments.id, { onDelete: "cascade" }),
|
|
||||||
teamId: text("team_id")
|
|
||||||
.notNull()
|
|
||||||
.references(() => teams.id, { onDelete: "cascade" }),
|
|
||||||
registrationDate: integer("registration_date", { mode: "timestamp" })
|
|
||||||
.notNull()
|
|
||||||
.$defaultFn(() => new Date()),
|
|
||||||
},
|
|
||||||
(table) => {
|
|
||||||
return {
|
|
||||||
tournamentTeamUnique: uniqueIndex("tournament_team_unique").on(
|
|
||||||
table.tournamentId,
|
|
||||||
table.teamId,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Relations
|
|
||||||
export const usersRelations = relations(users, ({ many }) => ({
|
|
||||||
members: many(members),
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const teamsRelations = relations(teams, ({ many }) => ({
|
|
||||||
members: many(members),
|
|
||||||
tournamentTeams: many(tournamentTeams),
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const membersRelations = relations(members, ({ one }) => ({
|
|
||||||
user: one(users, { fields: [members.userId], references: [users.id] }),
|
|
||||||
team: one(teams, { fields: [members.teamId], references: [teams.id] }),
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const tournamentsRelations = relations(tournaments, ({ many }) => ({
|
|
||||||
tournamentTeams: many(tournamentTeams),
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const tournamentTeamsRelations = relations(
|
|
||||||
tournamentTeams,
|
|
||||||
({ one }) => ({
|
|
||||||
tournament: one(tournaments, {
|
|
||||||
fields: [tournamentTeams.tournamentId],
|
|
||||||
references: [tournaments.id],
|
|
||||||
}),
|
|
||||||
team: one(teams, {
|
|
||||||
fields: [tournamentTeams.teamId],
|
|
||||||
references: [teams.id],
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
14
src/db/schema/index.ts
Normal file
14
src/db/schema/index.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Export all types
|
||||||
|
export * from "./types";
|
||||||
|
|
||||||
|
// Export all tables
|
||||||
|
export * from "./users";
|
||||||
|
export * from "./teams";
|
||||||
|
export * from "./members";
|
||||||
|
export * from "./tournaments";
|
||||||
|
|
||||||
|
// Export session table
|
||||||
|
// export * from ./session";
|
||||||
|
|
||||||
|
// Export all relations
|
||||||
|
export * from "./relations";
|
||||||
31
src/db/schema/members.ts
Normal file
31
src/db/schema/members.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
|
||||||
|
import { createId } from "@paralleldrive/cuid2";
|
||||||
|
import { users } from "./users";
|
||||||
|
import { teams } from "./teams";
|
||||||
|
import { RoleEnum } from "./types";
|
||||||
|
|
||||||
|
// Member table (join table for User and Team with role)
|
||||||
|
export const members = sqliteTable(
|
||||||
|
"member",
|
||||||
|
{
|
||||||
|
id: text("id")
|
||||||
|
.primaryKey()
|
||||||
|
.notNull()
|
||||||
|
.$defaultFn(() => createId()),
|
||||||
|
userId: text("user_id")
|
||||||
|
.notNull()
|
||||||
|
.references(() => users.id, { onDelete: "cascade" }),
|
||||||
|
teamId: text("team_id").references(() => teams.id, { onDelete: "cascade" }),
|
||||||
|
role: text("role", {
|
||||||
|
enum: Object.values(RoleEnum) as [string, ...string[]],
|
||||||
|
}).notNull(),
|
||||||
|
},
|
||||||
|
(table) => {
|
||||||
|
return {
|
||||||
|
userTeamUnique: uniqueIndex("user_team_unique").on(
|
||||||
|
table.userId,
|
||||||
|
table.teamId,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
);
|
||||||
42
src/db/schema/relations.ts
Normal file
42
src/db/schema/relations.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import { relations } from "drizzle-orm";
|
||||||
|
import { users } from "./users";
|
||||||
|
import { teams } from "./teams";
|
||||||
|
import { members } from "./members";
|
||||||
|
import { tournaments, tournamentTeams } from "./tournaments";
|
||||||
|
|
||||||
|
// User relations
|
||||||
|
export const usersRelations = relations(users, ({ many }) => ({
|
||||||
|
members: many(members),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Team relations
|
||||||
|
export const teamsRelations = relations(teams, ({ many }) => ({
|
||||||
|
members: many(members),
|
||||||
|
tournamentTeams: many(tournamentTeams),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Member relations
|
||||||
|
export const membersRelations = relations(members, ({ one }) => ({
|
||||||
|
user: one(users, { fields: [members.userId], references: [users.id] }),
|
||||||
|
team: one(teams, { fields: [members.teamId], references: [teams.id] }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Tournament relations
|
||||||
|
export const tournamentsRelations = relations(tournaments, ({ many }) => ({
|
||||||
|
tournamentTeams: many(tournamentTeams),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Tournament team relations
|
||||||
|
export const tournamentTeamsRelations = relations(
|
||||||
|
tournamentTeams,
|
||||||
|
({ one }) => ({
|
||||||
|
tournament: one(tournaments, {
|
||||||
|
fields: [tournamentTeams.tournamentId],
|
||||||
|
references: [tournaments.id],
|
||||||
|
}),
|
||||||
|
team: one(teams, {
|
||||||
|
fields: [tournamentTeams.teamId],
|
||||||
|
references: [teams.id],
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
);
|
||||||
2
src/db/schema/schema.ts
Normal file
2
src/db/schema/schema.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
// Re-export all schema components from modular files
|
||||||
|
export * from "./index";
|
||||||
11
src/db/schema/teams.ts
Normal file
11
src/db/schema/teams.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { sqliteTable, text } from "drizzle-orm/sqlite-core";
|
||||||
|
import { createId } from "@paralleldrive/cuid2";
|
||||||
|
|
||||||
|
// Team table
|
||||||
|
export const teams = sqliteTable("team", {
|
||||||
|
id: text("id")
|
||||||
|
.primaryKey()
|
||||||
|
.notNull()
|
||||||
|
.$defaultFn(() => createId()),
|
||||||
|
name: text("name").notNull(),
|
||||||
|
});
|
||||||
46
src/db/schema/tournaments.ts
Normal file
46
src/db/schema/tournaments.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import {
|
||||||
|
sqliteTable,
|
||||||
|
text,
|
||||||
|
integer,
|
||||||
|
uniqueIndex,
|
||||||
|
} from "drizzle-orm/sqlite-core";
|
||||||
|
|
||||||
|
import { createId } from "@paralleldrive/cuid2";
|
||||||
|
import { teams } from "./teams";
|
||||||
|
|
||||||
|
// Tournament table
|
||||||
|
export const tournaments = sqliteTable("tournament", {
|
||||||
|
id: text("id")
|
||||||
|
.primaryKey()
|
||||||
|
.notNull()
|
||||||
|
.$defaultFn(() => createId()),
|
||||||
|
name: text("name").notNull(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// TournamentTeam join table
|
||||||
|
export const tournamentTeams = sqliteTable(
|
||||||
|
"tournament_team",
|
||||||
|
{
|
||||||
|
id: text("id")
|
||||||
|
.primaryKey()
|
||||||
|
.notNull()
|
||||||
|
.$defaultFn(() => createId()),
|
||||||
|
tournamentId: text("tournament_id")
|
||||||
|
.notNull()
|
||||||
|
.references(() => tournaments.id, { onDelete: "cascade" }),
|
||||||
|
teamId: text("team_id")
|
||||||
|
.notNull()
|
||||||
|
.references(() => teams.id, { onDelete: "cascade" }),
|
||||||
|
registrationDate: integer("registration_date", { mode: "timestamp" })
|
||||||
|
.notNull()
|
||||||
|
.$defaultFn(() => new Date()),
|
||||||
|
},
|
||||||
|
(table) => {
|
||||||
|
return {
|
||||||
|
tournamentTeamUnique: uniqueIndex("tournament_team_unique").on(
|
||||||
|
table.tournamentId,
|
||||||
|
table.teamId,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
);
|
||||||
10
src/db/schema/types.ts
Normal file
10
src/db/schema/types.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// Roles enum equivalent
|
||||||
|
export const RoleEnum = {
|
||||||
|
VISITOR: "VISITOR",
|
||||||
|
PARTICIPANT: "PARTICIPANT",
|
||||||
|
TEAMMATE: "TEAMMATE",
|
||||||
|
CAPTAIN: "CAPTAIN",
|
||||||
|
ADMIN: "ADMIN",
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type Role = (typeof RoleEnum)[keyof typeof RoleEnum];
|
||||||
18
src/db/schema/users.ts
Normal file
18
src/db/schema/users.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { sqliteTable, text } from "drizzle-orm/sqlite-core";
|
||||||
|
import { createId } from "@paralleldrive/cuid2";
|
||||||
|
|
||||||
|
// User table
|
||||||
|
export const users = sqliteTable("user", {
|
||||||
|
id: text("id")
|
||||||
|
.primaryKey()
|
||||||
|
.notNull()
|
||||||
|
.$defaultFn(() => createId()),
|
||||||
|
email: text("email").notNull(),
|
||||||
|
|
||||||
|
// Other information
|
||||||
|
steamId: text("steam_id"),
|
||||||
|
firstName: text("first_name").notNull(),
|
||||||
|
lastName: text("last_name").notNull(),
|
||||||
|
ticketId: text("ticket_id").unique(),
|
||||||
|
ticketType: text("ticket_type"),
|
||||||
|
});
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
import { db } from "@/db/drizzle";
|
import { db } from "@/db/drizzle";
|
||||||
import { users, teams, members, tournamentTeams } from "@/db/schema";
|
import { users } from "@/db/schema/users";
|
||||||
|
import { teams } from "@/db/schema/teams";
|
||||||
|
import { members } from "@/db/schema/members";
|
||||||
|
import { tournamentTeams } from "@/db/schema/tournaments";
|
||||||
import { eq, and, isNull } from "drizzle-orm";
|
import { eq, and, isNull } from "drizzle-orm";
|
||||||
import { RoleEnum, type Role } from "@/db/schema";
|
import { RoleEnum, type Role } from "@/db/schema/types";
|
||||||
|
|
||||||
// Types based on the Fienta API response
|
// Types based on the Fienta API response
|
||||||
export interface FientaApiResponse {
|
export interface FientaApiResponse {
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import type { InferSelectModel } from "drizzle-orm";
|
import type { InferSelectModel } from "drizzle-orm";
|
||||||
import { users, teams, members } from "@/db/schema";
|
import { users } from "@/db/schema/users";
|
||||||
|
import { teams } from "@/db/schema/teams";
|
||||||
|
import { members } from "@/db/schema/members";
|
||||||
|
|
||||||
// Base types from schema
|
// Base types from schema
|
||||||
export type User = InferSelectModel<typeof users>;
|
export type User = InferSelectModel<typeof users>;
|
||||||
|
|||||||
Reference in New Issue
Block a user