This commit is contained in:
63
src/db/schema/admin.ts
Normal file
63
src/db/schema/admin.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import { int, mysqlTable, varchar } from 'drizzle-orm/mysql-core';
|
||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { Permissions } from '@util/permissions.ts';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
|
||||
type Database = MySql2Database<{ admin: typeof admin }>;
|
||||
|
||||
export const admin = mysqlTable('admin', {
|
||||
id: int('id').primaryKey().autoincrement(),
|
||||
username: varchar('username', { length: 255 }).notNull(),
|
||||
password: varchar('password', { length: 255 }).notNull(),
|
||||
permissions: int('permissions').notNull()
|
||||
});
|
||||
|
||||
export type AddAdminReq = Omit<typeof admin.$inferInsert, 'id'>;
|
||||
|
||||
export type EditAdminReq = Omit<typeof admin.$inferInsert, 'id'> & { id: number };
|
||||
|
||||
export type GetAdminReq = {};
|
||||
export type GetAdminRes = Omit<typeof admin.$inferSelect, 'password'>[];
|
||||
|
||||
export type ExistsAdminReq = {
|
||||
username: string;
|
||||
password: string;
|
||||
};
|
||||
export type ExistsAdminRes = {
|
||||
id: number;
|
||||
username: string;
|
||||
permissions: Permissions;
|
||||
} | null;
|
||||
|
||||
export async function addAdmin(db: Database, values: AddAdminReq) {
|
||||
values.password = bcrypt.hashSync(values.password, 10);
|
||||
|
||||
const adminIds = await db.insert(admin).values(values).$returningId();
|
||||
|
||||
return adminIds[0];
|
||||
}
|
||||
|
||||
export async function editAdmin(db: Database, values: EditAdminReq) {
|
||||
values.password = bcrypt.hashSync(values.password, 10);
|
||||
|
||||
await db.update(admin).set(values).where(eq(admin.id, values.id));
|
||||
}
|
||||
|
||||
export async function getAdmins(db: Database, _values: GetAdminReq): Promise<GetAdminRes> {
|
||||
return db.select({ id: admin.id, username: admin.username, permissions: admin.permissions }).from(admin);
|
||||
}
|
||||
|
||||
export async function existsAdmin(db: Database, values: ExistsAdminReq): Promise<ExistsAdminRes> {
|
||||
const a = await db.query.admin.findFirst({
|
||||
where: eq(admin.username, values.username)
|
||||
});
|
||||
|
||||
if (!a || !bcrypt.compareSync(values.password, a.password)) return null;
|
||||
|
||||
return {
|
||||
id: a.id,
|
||||
username: a.username,
|
||||
permissions: new Permissions(a.permissions)
|
||||
};
|
||||
}
|
42
src/db/schema/death.ts
Normal file
42
src/db/schema/death.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { int, mysqlTable, varchar } from 'drizzle-orm/mysql-core';
|
||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||
import { user } from './user.ts';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
type Database = MySql2Database<{ death: typeof death }>;
|
||||
|
||||
export const death = mysqlTable('death', {
|
||||
message: varchar('message', { length: 1024 }).notNull(),
|
||||
deadUserId: int('dead_user_id')
|
||||
.notNull()
|
||||
.references(() => user.id),
|
||||
killerUserId: int('killer_user_id').references(() => user.id)
|
||||
});
|
||||
|
||||
export type AddDeathReq = {
|
||||
message: string;
|
||||
killerUserId?: number;
|
||||
deadUserId: number;
|
||||
};
|
||||
|
||||
export type GetDeathByUserIdReq = {
|
||||
userId: number;
|
||||
};
|
||||
|
||||
export type GetDeathsReq = {};
|
||||
export type GetDeathsRes = (typeof death.$inferSelect)[];
|
||||
|
||||
export async function addDeath(db: Database, values: AddDeathReq) {
|
||||
await db.insert(death).values(values);
|
||||
}
|
||||
|
||||
export async function getDeathByUserId(db: Database, values: GetDeathByUserIdReq) {
|
||||
return db.query.death.findFirst({
|
||||
where: eq(death.deadUserId, values.userId)
|
||||
});
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export async function getDeaths(db: Database, values: GetDeathsReq): Promise<GetDeathsReq> {
|
||||
return db.query.death.findMany();
|
||||
}
|
78
src/db/schema/feedback.ts
Normal file
78
src/db/schema/feedback.ts
Normal file
@ -0,0 +1,78 @@
|
||||
import { int, mysqlTable, text, timestamp, varchar } from 'drizzle-orm/mysql-core';
|
||||
import { user } from './user.ts';
|
||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||
import { eq, inArray } from 'drizzle-orm';
|
||||
import { generateRandomString } from '@util/random.ts';
|
||||
|
||||
type Database = MySql2Database<{ feedback: typeof feedback }>;
|
||||
|
||||
export const feedback = mysqlTable('feedback', {
|
||||
id: int('id').primaryKey().autoincrement(),
|
||||
event: varchar('event', { length: 255 }).notNull(),
|
||||
title: varchar('title', { length: 255 }),
|
||||
content: text('content'),
|
||||
urlHash: varchar('url_hash', { length: 255 }).unique().notNull(),
|
||||
lastChanged: timestamp('last_changed', { mode: 'date' }).notNull().defaultNow(),
|
||||
userId: int('user_id').references(() => user.id)
|
||||
});
|
||||
|
||||
export type AddFeedbackReq = {
|
||||
event: string;
|
||||
content: string;
|
||||
};
|
||||
|
||||
export type AddUserFeedbacksReq = {
|
||||
event: string;
|
||||
title: string;
|
||||
uuids: string[];
|
||||
};
|
||||
|
||||
export type GetFeedbacksReq = {};
|
||||
|
||||
export async function addFeedback(db: Database, values: AddFeedbackReq) {
|
||||
return db.insert(feedback).values({
|
||||
event: values.event,
|
||||
content: values.content,
|
||||
urlHash: generateRandomString(16)
|
||||
});
|
||||
}
|
||||
|
||||
export async function addUserFeedbacks(db: Database, values: AddUserFeedbacksReq) {
|
||||
const users = await db.select({ id: user.id, uuid: user.uuid }).from(user).where(inArray(user.uuid, values.uuids));
|
||||
|
||||
const userFeedbacks = users.map((user) => ({
|
||||
id: user.id,
|
||||
uuid: user.uuid!,
|
||||
urlHash: generateRandomString(16)
|
||||
}));
|
||||
|
||||
await db.insert(feedback).values(
|
||||
userFeedbacks.map((feedback) => ({
|
||||
event: values.event,
|
||||
title: values.title,
|
||||
urlHash: feedback.urlHash,
|
||||
userId: feedback.id
|
||||
}))
|
||||
);
|
||||
|
||||
return userFeedbacks;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export async function getFeedbacks(db: Database, values: GetFeedbacksReq) {
|
||||
return db
|
||||
.select({
|
||||
id: feedback.id,
|
||||
event: feedback.event,
|
||||
title: feedback.title,
|
||||
content: feedback.content,
|
||||
urlHash: feedback.urlHash,
|
||||
lastChanged: feedback.lastChanged,
|
||||
user: {
|
||||
id: user.id,
|
||||
username: user.username
|
||||
}
|
||||
})
|
||||
.from(feedback)
|
||||
.leftJoin(user, eq(feedback.userId, user.id));
|
||||
}
|
104
src/db/schema/report.ts
Normal file
104
src/db/schema/report.ts
Normal file
@ -0,0 +1,104 @@
|
||||
import { alias, int, mysqlTable, text, timestamp, varchar } from 'drizzle-orm/mysql-core';
|
||||
import { strike } from './strike.ts';
|
||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||
import { and, eq } from 'drizzle-orm';
|
||||
import { reportStatus } from './reportStatus.ts';
|
||||
import { generateRandomString } from '@util/random.ts';
|
||||
import { team } from '@db/schema/team.ts';
|
||||
|
||||
type Database = MySql2Database<{ report: typeof report }>;
|
||||
|
||||
export const report = mysqlTable('report', {
|
||||
id: int('id').primaryKey().autoincrement(),
|
||||
reason: varchar('reason', { length: 255 }).notNull(),
|
||||
body: text('body'),
|
||||
urlHash: varchar('url_hash', { length: 255 }).notNull(),
|
||||
createdAt: timestamp('created_at', { mode: 'string' }),
|
||||
reporterTeamId: int('reporter_team_id')
|
||||
.notNull()
|
||||
.references(() => team.id),
|
||||
reportedTeamId: int('reported_team_id').references(() => team.id)
|
||||
});
|
||||
|
||||
export type AddReportReq = {
|
||||
reason: string;
|
||||
body: string | null;
|
||||
createdAt?: string | null;
|
||||
reporterTeamId: number;
|
||||
reportedTeamId?: number | null;
|
||||
};
|
||||
|
||||
export type GetReportsReq = {
|
||||
reporter?: string | null;
|
||||
reported?: string | null;
|
||||
};
|
||||
|
||||
export async function addReport(db: Database, values: AddReportReq) {
|
||||
const r = await db
|
||||
.insert(report)
|
||||
.values({
|
||||
reason: values.reason,
|
||||
body: values.body,
|
||||
urlHash: generateRandomString(16),
|
||||
createdAt: values.createdAt,
|
||||
reporterTeamId: values.reporterTeamId,
|
||||
reportedTeamId: values.reportedTeamId
|
||||
})
|
||||
.$returningId();
|
||||
|
||||
return r[0];
|
||||
}
|
||||
|
||||
export async function getReports(db: Database, values: GetReportsReq) {
|
||||
const reporterTeam = alias(team, 'reporter');
|
||||
const reportedTeam = alias(team, 'reported');
|
||||
|
||||
let reporterIdSubquery;
|
||||
if (values.reporter != null) {
|
||||
reporterIdSubquery = db
|
||||
.select({ id: reporterTeam.id })
|
||||
.from(reporterTeam)
|
||||
.where(eq(reporterTeam.name, values.reporter))
|
||||
.as('reporter_id_subquery');
|
||||
}
|
||||
let reportedIdSubquery;
|
||||
if (values.reported != null) {
|
||||
reportedIdSubquery = db
|
||||
.select({ id: reportedTeam.id })
|
||||
.from(reportedTeam)
|
||||
.where(eq(reportedTeam.name, values.reported))
|
||||
.as('reported_id_subquery');
|
||||
}
|
||||
|
||||
return db
|
||||
.select({
|
||||
id: report.id,
|
||||
reason: report.reason,
|
||||
body: report.body,
|
||||
createdAt: report.createdAt,
|
||||
reporter: {
|
||||
id: reporterTeam.id,
|
||||
name: reporterTeam.name
|
||||
},
|
||||
reported: {
|
||||
id: reportedTeam.id,
|
||||
name: reportedTeam.name
|
||||
},
|
||||
status: {
|
||||
status: reportStatus.status,
|
||||
notice: reportStatus.notice,
|
||||
statement: reportStatus.statement
|
||||
}
|
||||
})
|
||||
.from(report)
|
||||
.innerJoin(reporterTeam, eq(report.reporterTeamId, reporterTeam.id))
|
||||
.leftJoin(reportedTeam, eq(report.reportedTeamId, reportedTeam.id))
|
||||
.leftJoin(reportStatus, eq(report.id, reportStatus.reportId))
|
||||
.leftJoin(strike, eq(reportStatus.strikeId, strike.id))
|
||||
.where(
|
||||
and(
|
||||
values.reporter != null ? eq(report.reporterTeamId, reporterIdSubquery!.id) : undefined,
|
||||
values.reported != null ? eq(report.reportedTeamId, reportedIdSubquery!.id) : undefined
|
||||
)
|
||||
);
|
||||
}
|
54
src/db/schema/reportStatus.ts
Normal file
54
src/db/schema/reportStatus.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import { int, mysqlEnum, mysqlTable, text } from 'drizzle-orm/mysql-core';
|
||||
import { strike } from './strike.ts';
|
||||
import { admin } from './admin.ts';
|
||||
import { report } from './report.ts';
|
||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
type Database = MySql2Database<{ reportStatus: typeof reportStatus }>;
|
||||
|
||||
export const reportStatus = mysqlTable('report_status', {
|
||||
status: mysqlEnum('status', ['open', 'closed']),
|
||||
notice: text('notice'),
|
||||
statement: text('statement'),
|
||||
reportId: int('report_id')
|
||||
.notNull()
|
||||
.unique()
|
||||
.references(() => report.id),
|
||||
reviewerId: int('reviewer_id').references(() => admin.id),
|
||||
strikeId: int('strike_id').references(() => strike.id)
|
||||
});
|
||||
|
||||
export type GetReportStatusReq = {
|
||||
reportId: number;
|
||||
};
|
||||
|
||||
export type EditReportStatusReq = {
|
||||
reportId: number;
|
||||
status: 'open' | 'closed' | null;
|
||||
notice: string | null;
|
||||
statement: string | null;
|
||||
strikeId: number | null;
|
||||
};
|
||||
|
||||
export async function getReportStatus(db: Database, values: GetReportStatusReq) {
|
||||
const rs = await db.query.reportStatus.findFirst({
|
||||
where: eq(reportStatus.reportId, values.reportId)
|
||||
});
|
||||
|
||||
return rs ?? null;
|
||||
}
|
||||
|
||||
export async function editReportStatus(db: Database, values: EditReportStatusReq) {
|
||||
return db
|
||||
.insert(reportStatus)
|
||||
.values(values)
|
||||
.onDuplicateKeyUpdate({
|
||||
set: {
|
||||
status: values.status,
|
||||
notice: values.notice,
|
||||
statement: values.statement,
|
||||
strikeId: values.strikeId
|
||||
}
|
||||
});
|
||||
}
|
41
src/db/schema/settings.ts
Normal file
41
src/db/schema/settings.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { mysqlTable, text, varchar } from 'drizzle-orm/mysql-core';
|
||||
import { eq, inArray } from 'drizzle-orm';
|
||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||
|
||||
type Database = MySql2Database<{ settings: typeof settings }>;
|
||||
|
||||
export const settings = mysqlTable('settings', {
|
||||
name: varchar('name', { length: 255 }).unique().notNull(),
|
||||
value: text()
|
||||
});
|
||||
|
||||
export type GetSettingsReq = {
|
||||
names?: string[];
|
||||
};
|
||||
|
||||
export type SetSettingsReq = {
|
||||
settings: {
|
||||
name: string;
|
||||
value: string | null;
|
||||
}[];
|
||||
};
|
||||
|
||||
export type GetSettingReq = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export async function getSettings(db: Database, values: GetSettingsReq) {
|
||||
return db
|
||||
.select({ name: settings.name, value: settings.value })
|
||||
.from(settings)
|
||||
.where(values.names ? inArray(settings.name, values.names) : undefined);
|
||||
}
|
||||
|
||||
export async function setSettings(db: Database, values: SetSettingsReq) {
|
||||
await db.insert(settings).values(values.settings);
|
||||
}
|
||||
|
||||
export async function getSetting(db: Database, values: GetSettingReq): Promise<string | null> {
|
||||
const value = await db.select({ value: settings.value }).from(settings).where(eq(settings.name, values.name));
|
||||
return value.length > 0 ? value[0]?.value : null;
|
||||
}
|
34
src/db/schema/strike.ts
Normal file
34
src/db/schema/strike.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { int, mysqlTable, timestamp } from 'drizzle-orm/mysql-core';
|
||||
import { strikeReason } from '@db/schema/strikeReason.ts';
|
||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { report } from '@db/schema/report.ts';
|
||||
import { reportStatus } from '@db/schema/reportStatus.ts';
|
||||
|
||||
type Database = MySql2Database<{ strike: typeof strike }>;
|
||||
|
||||
export const strike = mysqlTable('strike', {
|
||||
id: int('id').primaryKey().autoincrement(),
|
||||
at: timestamp('at', { mode: 'string' }).notNull(),
|
||||
strikeReasonId: int('strike_reason_id')
|
||||
.notNull()
|
||||
.references(() => strikeReason.id)
|
||||
});
|
||||
|
||||
export type GetStrikesByTeamId = {
|
||||
teamId: number;
|
||||
};
|
||||
|
||||
export async function getStrikesByTeamId(db: Database, values: GetStrikesByTeamId) {
|
||||
return db
|
||||
.select({
|
||||
id: strike.id,
|
||||
at: strike.at,
|
||||
reason: strikeReason
|
||||
})
|
||||
.from(strike)
|
||||
.innerJoin(strikeReason, eq(strike.strikeReasonId, strikeReason.id))
|
||||
.innerJoin(reportStatus, eq(strike.id, reportStatus.strikeId))
|
||||
.innerJoin(report, eq(reportStatus.reportId, report.id))
|
||||
.where(eq(report.reportedTeamId, values.teamId));
|
||||
}
|
17
src/db/schema/strikeReason.ts
Normal file
17
src/db/schema/strikeReason.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { int, mysqlTable, tinyint, varchar } from 'drizzle-orm/mysql-core';
|
||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||
import { asc } from 'drizzle-orm';
|
||||
|
||||
type Database = MySql2Database<{ strikeReason: typeof strikeReason }>;
|
||||
|
||||
export const strikeReason = mysqlTable('strike_reason', {
|
||||
id: int('id').primaryKey().autoincrement(),
|
||||
name: varchar('name', { length: 255 }).notNull(),
|
||||
weight: tinyint('weight').notNull()
|
||||
});
|
||||
|
||||
export type GetStrikeReasonsReq = {};
|
||||
|
||||
export async function getStrikeReasons(db: Database, _values: GetStrikeReasonsReq) {
|
||||
return db.select().from(strikeReason).orderBy(asc(strikeReason.weight));
|
||||
}
|
256
src/db/schema/team.ts
Normal file
256
src/db/schema/team.ts
Normal file
@ -0,0 +1,256 @@
|
||||
import { char, int, mysqlTable, timestamp, varchar } from 'drizzle-orm/mysql-core';
|
||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||
import { aliasedTable, and, asc, desc, eq, like } from 'drizzle-orm';
|
||||
import { teamMember } from './teamMember.ts';
|
||||
import { user } from './user.ts';
|
||||
import { teamDraft } from './teamDraft.ts';
|
||||
|
||||
type Database = MySql2Database<{ team: typeof team }>;
|
||||
|
||||
export const team = mysqlTable('team', {
|
||||
id: int('id').primaryKey().autoincrement(),
|
||||
name: varchar('name', { length: 255 }).notNull(),
|
||||
color: char('color', { length: 7 }).notNull(),
|
||||
lastJoined: timestamp('last_joined', { mode: 'string' })
|
||||
});
|
||||
|
||||
export type AddTeamReq = {
|
||||
name: string;
|
||||
color?: string;
|
||||
};
|
||||
|
||||
export type EditTeamReq = Partial<Omit<typeof team.$inferSelect, 'id'>> & { id: number };
|
||||
|
||||
export type DeleteTeamReq = {
|
||||
id: number;
|
||||
};
|
||||
|
||||
export type GetTeamsReq = {
|
||||
name?: string | null;
|
||||
username?: string | null;
|
||||
limit?: number;
|
||||
};
|
||||
|
||||
export type GetTeamByIdReq = {
|
||||
id: number;
|
||||
};
|
||||
|
||||
export type GetTeamByNameReq = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type GetTeamByUserUuidReq = {
|
||||
uuid: string;
|
||||
};
|
||||
|
||||
export async function addTeam(db: Database, values: AddTeamReq) {
|
||||
let color = values.color;
|
||||
if (!color) {
|
||||
const teams = await db.query.team.findMany({
|
||||
columns: {
|
||||
color: true
|
||||
},
|
||||
orderBy: [desc(team.id)]
|
||||
});
|
||||
|
||||
if (teams.length > 0) {
|
||||
for (const team of teams) {
|
||||
for (let i = 0; i < teamColors.length; i++) {
|
||||
if (teamColors[i] == team.color) {
|
||||
color = teamColors[(i + 1) % teamColors.length];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (color) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!color) color = teamColors[0];
|
||||
}
|
||||
|
||||
const teamIds = await db
|
||||
.insert(team)
|
||||
.values({
|
||||
name: values.name,
|
||||
color: color
|
||||
})
|
||||
.$returningId();
|
||||
|
||||
return {
|
||||
id: teamIds[0].id,
|
||||
name: values.name,
|
||||
color: color
|
||||
};
|
||||
}
|
||||
|
||||
export async function editTeam(db: Database, values: EditTeamReq) {
|
||||
await db.update(team).set(values).where(eq(team.id, values.id));
|
||||
}
|
||||
|
||||
export async function deleteTeam(db: Database, values: DeleteTeamReq) {
|
||||
await db.delete(team).where(eq(team.id, values.id));
|
||||
}
|
||||
|
||||
export async function getTeams(db: Database, values: GetTeamsReq) {
|
||||
const memberOneUser = aliasedTable(user, 'member_one_user');
|
||||
const memberTwoUser = aliasedTable(user, 'member_two_user');
|
||||
|
||||
return db
|
||||
.select({
|
||||
id: team.id,
|
||||
name: team.name,
|
||||
color: team.color,
|
||||
lastJoined: team.lastJoined,
|
||||
memberOne: {
|
||||
id: memberOneUser.id,
|
||||
username: teamDraft.memberOneName,
|
||||
uuid: memberOneUser.uuid
|
||||
},
|
||||
memberTwo: {
|
||||
id: memberTwoUser.id,
|
||||
username: teamDraft.memberTwoName,
|
||||
uuid: memberTwoUser.uuid
|
||||
}
|
||||
})
|
||||
.from(team)
|
||||
.where(
|
||||
and(
|
||||
values?.name != null ? like(team.name, `%${values.name}%`) : undefined,
|
||||
values?.username != null ? like(teamDraft.memberOneName, `%${values.username}%`) : undefined,
|
||||
values?.username != null ? like(teamDraft.memberTwoName, `%${values.username}%`) : undefined
|
||||
)
|
||||
)
|
||||
.orderBy(asc(team.id))
|
||||
.innerJoin(teamDraft, eq(team.id, teamDraft.teamId))
|
||||
.leftJoin(memberOneUser, eq(teamDraft.memberOneName, memberOneUser.username))
|
||||
.leftJoin(memberTwoUser, eq(teamDraft.memberTwoName, memberTwoUser.username))
|
||||
.limit(values?.limit ?? 100);
|
||||
}
|
||||
|
||||
export async function getTeamById(db: Database, values: GetTeamByIdReq) {
|
||||
const teams = await db.select().from(team).where(eq(team.id, values.id));
|
||||
|
||||
return teams[0] ?? null;
|
||||
}
|
||||
|
||||
export async function getTeamByName(db: Database, values: GetTeamByNameReq) {
|
||||
const teams = await db.select().from(team).where(eq(team.name, values.name));
|
||||
|
||||
return teams[0] ?? null;
|
||||
}
|
||||
|
||||
export async function getTeamByUserUuid(db: Database, values: GetTeamByUserUuidReq) {
|
||||
const teams = await db
|
||||
.select({ team })
|
||||
.from(team)
|
||||
.innerJoin(teamMember, eq(team.id, teamMember.teamId))
|
||||
.innerJoin(user, eq(teamMember.userId, user.id))
|
||||
.where(eq(user.uuid, values.uuid));
|
||||
|
||||
return teams[0] ?? null;
|
||||
}
|
||||
|
||||
const teamColors = [
|
||||
'#cd853f',
|
||||
'#ff7f50',
|
||||
'#66cdaa',
|
||||
'#ffd700',
|
||||
'#ba55d3',
|
||||
'#d8bfd8',
|
||||
'#dc143c',
|
||||
'#ff6347',
|
||||
'#2e8b57',
|
||||
'#daa520',
|
||||
'#deb887',
|
||||
'#00fa9a',
|
||||
'#778899',
|
||||
'#ffa500',
|
||||
'#e9967a',
|
||||
'#b03060',
|
||||
'#8b0000',
|
||||
'#bdb76b',
|
||||
'#663399',
|
||||
'#d2b48c',
|
||||
'#00ced1',
|
||||
'#d2691e',
|
||||
'#32cd32',
|
||||
'#ff4500',
|
||||
'#0000ff',
|
||||
'#adff2f',
|
||||
'#b22222',
|
||||
'#20b2aa',
|
||||
'#00bfff',
|
||||
'#fa8072',
|
||||
'#cd5c5c',
|
||||
'#9370db',
|
||||
'#00ff00',
|
||||
'#006400',
|
||||
'#00008b',
|
||||
'#f08080',
|
||||
'#f4a460',
|
||||
'#c71585',
|
||||
'#6b8e23',
|
||||
'#8a2be2',
|
||||
'#b8860b',
|
||||
'#ff69b4',
|
||||
'#000080',
|
||||
'#bc8f8f',
|
||||
'#ff1493',
|
||||
'#00ffff',
|
||||
'#b0e0e6',
|
||||
'#ff0000',
|
||||
'#00ff7f',
|
||||
'#dc143c',
|
||||
'#dda0dd',
|
||||
'#8b008b',
|
||||
'#8fbc8f',
|
||||
'#9932cc',
|
||||
'#ff00ff',
|
||||
'#228b22',
|
||||
'#5f9ea0',
|
||||
'#3cb371',
|
||||
'#b0c4de',
|
||||
'#00ff00',
|
||||
'#87ceeb',
|
||||
'#008b8b',
|
||||
'#191970',
|
||||
'#90ee90',
|
||||
'#ff8c00',
|
||||
'#4b0082',
|
||||
'#db7093',
|
||||
'#cd853f',
|
||||
'#7fff00',
|
||||
'#c71585',
|
||||
'#7f0000',
|
||||
'#fa8072',
|
||||
'#8b4513',
|
||||
'#7b68ee',
|
||||
'#dda0dd',
|
||||
'#a52a2a',
|
||||
'#00ced1',
|
||||
'#d2691e',
|
||||
'#b8860b',
|
||||
'#2f4f4f',
|
||||
'#663399',
|
||||
'#9370db',
|
||||
'#da70d6',
|
||||
'#b03060',
|
||||
'#bc8f8f',
|
||||
'#a0522d',
|
||||
'#6495ed',
|
||||
'#d8bfd8',
|
||||
'#adff2f',
|
||||
'#8b0000',
|
||||
'#800000',
|
||||
'#ffd700',
|
||||
'#00fa9a',
|
||||
'#4682b4',
|
||||
'#808000',
|
||||
'#6a5acd',
|
||||
'#ff1493',
|
||||
'#00ff7f',
|
||||
'#40e0d0',
|
||||
'#ff4500',
|
||||
'#1e90ff',
|
||||
'#ff6347'
|
||||
];
|
56
src/db/schema/teamDraft.ts
Normal file
56
src/db/schema/teamDraft.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import { int, mysqlTable, varchar } from 'drizzle-orm/mysql-core';
|
||||
import { team } from './team.ts';
|
||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
type Database = MySql2Database<{ teamDraft: typeof teamDraft }>;
|
||||
|
||||
export const teamDraft = mysqlTable('team_draft', {
|
||||
memberOneName: varchar('member_one_name', { length: 255 }).unique().notNull(),
|
||||
memberTwoName: varchar('member_two_name', { length: 255 }).unique().notNull(),
|
||||
teamId: int('team_id')
|
||||
.notNull()
|
||||
.references(() => team.id)
|
||||
});
|
||||
|
||||
export type AddTeamDraftReq = {
|
||||
memberOneName: string;
|
||||
memberTwoName: string;
|
||||
teamId: number;
|
||||
};
|
||||
|
||||
export type DeleteTeamDraftReq = {
|
||||
teamId: number;
|
||||
};
|
||||
|
||||
export type GetTeamDraftByUsernameReq = {
|
||||
username: string;
|
||||
};
|
||||
|
||||
export type GetTeamDraftByMemberOneReq = {
|
||||
memberOneName: string;
|
||||
};
|
||||
|
||||
export async function addTeamDraft(db: Database, values: AddTeamDraftReq) {
|
||||
await db.insert(teamDraft).values(values);
|
||||
}
|
||||
|
||||
export async function deleteTeamDraft(db: Database, values: DeleteTeamDraftReq) {
|
||||
await db.delete(teamDraft).where(eq(teamDraft.teamId, values.teamId));
|
||||
}
|
||||
|
||||
export async function getTeamDraftByUsername(db: Database, values: GetTeamDraftByUsernameReq) {
|
||||
const td = await db.query.teamDraft.findFirst({
|
||||
where: eq(teamDraft.memberOneName, values.username)
|
||||
});
|
||||
|
||||
return td ?? null;
|
||||
}
|
||||
|
||||
export async function getTeamDraftByMemberOne(db: Database, values: GetTeamDraftByMemberOneReq) {
|
||||
const td = await db.query.teamDraft.findFirst({
|
||||
where: eq(teamDraft.memberOneName, values.memberOneName)
|
||||
});
|
||||
|
||||
return td ?? null;
|
||||
}
|
35
src/db/schema/teamMember.ts
Normal file
35
src/db/schema/teamMember.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { int, mysqlTable } from 'drizzle-orm/mysql-core';
|
||||
import { user } from './user.ts';
|
||||
import { team } from './team.ts';
|
||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
type Database = MySql2Database<{ teamMember: typeof teamMember }>;
|
||||
|
||||
export const teamMember = mysqlTable('team_member', {
|
||||
teamId: int('team_id')
|
||||
.notNull()
|
||||
.references(() => team.id),
|
||||
userId: int('user_id')
|
||||
.notNull()
|
||||
.references(() => user.id)
|
||||
});
|
||||
|
||||
export type AddTeamMemberReq = {
|
||||
teamId: number;
|
||||
userId: number;
|
||||
};
|
||||
|
||||
export type DeleteTeamMemberByTeamIdReq = {
|
||||
teamId: number;
|
||||
};
|
||||
|
||||
export async function addTeamMember(db: Database, values: AddTeamMemberReq) {
|
||||
const teamMemberIds = await db.insert(teamMember).values(values).$returningId();
|
||||
|
||||
return teamMemberIds[0];
|
||||
}
|
||||
|
||||
export async function deleteTeamMemberByTeamId(db: Database, values: DeleteTeamMemberByTeamIdReq) {
|
||||
await db.delete(teamMember).where(eq(teamMember.teamId, values.teamId));
|
||||
}
|
107
src/db/schema/user.ts
Normal file
107
src/db/schema/user.ts
Normal file
@ -0,0 +1,107 @@
|
||||
import { date, int, mysqlTable, varchar } from 'drizzle-orm/mysql-core';
|
||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||
import { eq, inArray, like, or } from 'drizzle-orm';
|
||||
|
||||
type Database = MySql2Database<{ user: typeof user }>;
|
||||
|
||||
export const user = mysqlTable('user', {
|
||||
id: int('id').primaryKey().autoincrement(),
|
||||
firstname: varchar('firstname', { length: 255 }).notNull(),
|
||||
lastname: varchar('lastname', { length: 255 }).notNull(),
|
||||
birthday: date('birthday', { mode: 'string' }).notNull(),
|
||||
telephone: varchar('telephone', { length: 255 }),
|
||||
username: varchar('username', { length: 255 }).notNull(),
|
||||
uuid: varchar('uuid', { length: 36 })
|
||||
});
|
||||
|
||||
export type AddUserReq = Omit<typeof user.$inferInsert, 'id'>;
|
||||
|
||||
export type EditUserReq = Partial<Omit<typeof user.$inferInsert, 'id'>> & { id: number };
|
||||
|
||||
export type DeleteUserReq = {
|
||||
id: number;
|
||||
};
|
||||
|
||||
export type ExistsUserReq = {
|
||||
username?: string;
|
||||
uuid?: string;
|
||||
};
|
||||
|
||||
export type GetUsersReq = {
|
||||
username?: string | null;
|
||||
limit?: number;
|
||||
};
|
||||
export type GetUsersRes = (typeof user.$inferSelect)[];
|
||||
|
||||
export type GetUserByIdReq = {
|
||||
id: number;
|
||||
};
|
||||
export type GetUserByIdRes = typeof user.$inferSelect | null;
|
||||
|
||||
export type GetUserByUsernameReq = {
|
||||
username: string;
|
||||
};
|
||||
export type GetUserByUsernameRes = typeof user.$inferSelect | null;
|
||||
|
||||
export type GetUsersByUuidReq = {
|
||||
uuid: string[];
|
||||
};
|
||||
|
||||
export async function addUser(db: Database, values: AddUserReq) {
|
||||
const userIds = await db.insert(user).values(values).$returningId();
|
||||
|
||||
return userIds[0];
|
||||
}
|
||||
|
||||
export async function editUser(db: Database, values: EditUserReq) {
|
||||
await db.update(user).set(values).where(eq(user.id, values.id));
|
||||
}
|
||||
|
||||
export async function deleteUser(db: Database, values: DeleteUserReq) {
|
||||
await db.delete(user).where(eq(user.id, values.id));
|
||||
}
|
||||
|
||||
export async function existsUser(db: Database, values: ExistsUserReq) {
|
||||
const u = db.query.user.findFirst({
|
||||
where: or(
|
||||
values.username != null ? eq(user.username, values.username) : undefined,
|
||||
values.uuid != null ? eq(user.uuid, values.uuid) : undefined
|
||||
)
|
||||
});
|
||||
|
||||
return u ?? null;
|
||||
}
|
||||
|
||||
export async function getUsers(db: Database, values: GetUsersReq): Promise<GetUsersRes> {
|
||||
return db.query.user.findMany({
|
||||
where: values.username != null ? like(user.username, `%${values.username}%`) : undefined,
|
||||
limit: values.limit
|
||||
});
|
||||
}
|
||||
|
||||
export async function getUserById(db: Database, values: GetUserByIdReq): Promise<GetUserByIdRes> {
|
||||
const u = await db.query.user.findFirst({
|
||||
where: eq(user.id, values.id)
|
||||
});
|
||||
|
||||
return u ?? null;
|
||||
}
|
||||
|
||||
export async function getUserByUsername(db: Database, values: GetUserByUsernameReq): Promise<GetUserByUsernameRes> {
|
||||
const u = await db.query.user.findFirst({
|
||||
where: eq(user.username, values.username)
|
||||
});
|
||||
|
||||
return u ?? null;
|
||||
}
|
||||
|
||||
export async function getUsersByUuid(db: Database, values: GetUsersByUuidReq) {
|
||||
const users = await db.query.user.findMany({
|
||||
where: inArray(user.uuid, values.uuid)
|
||||
});
|
||||
|
||||
return users.reduce(
|
||||
(prev, curr) => Object.assign(prev, { [curr.uuid!]: curr }),
|
||||
{} as Record<string, Omit<typeof user.$inferSelect, 'uuid'> & { uuid: string }>
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user