Files
aurorabot/shared/modules/user/user.service.ts
syntaxbullet 5bd390b4ee docs: add JSDoc to service public methods
One-line JSDoc on 82 methods across 11 service files for quick
scanning without reading full implementations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:36:18 +02:00

79 lines
3.0 KiB
TypeScript

import { users } from "@db/schema";
import { eq } from "drizzle-orm";
import { DrizzleClient } from "@shared/db/DrizzleClient";
import { withTransaction } from "@/lib/db";
import type { Transaction } from "@shared/lib/types";
export const userService = {
/** Fetch a user by Discord ID, including their class relation. */
getUserById: async (id: string) => {
const user = await DrizzleClient.query.users.findFirst({
where: eq(users.id, BigInt(id)),
with: { class: true }
});
return user;
},
/** Fetch a user by their username. */
getUserByUsername: async (username: string) => {
const user = await DrizzleClient.query.users.findFirst({ where: eq(users.username, username) });
return user;
},
/** Fetch a user by ID, creating a new record if one does not exist. */
getOrCreateUser: async (id: string, username: string, tx?: Transaction) => {
return await withTransaction(async (txFn) => {
let user = await txFn.query.users.findFirst({
where: eq(users.id, BigInt(id)),
with: { class: true }
});
if (!user) {
await txFn.insert(users).values({
id: BigInt(id),
username,
}).returning();
// Re-query to get the user with class relation
user = await txFn.query.users.findFirst({
where: eq(users.id, BigInt(id)),
with: { class: true }
});
}
return user;
}, tx);
},
/** Get the class assigned to a user, or undefined if none. */
getUserClass: async (id: string) => {
const user = await DrizzleClient.query.users.findFirst({
where: eq(users.id, BigInt(id)),
with: { class: true }
});
return user?.class;
},
/** Create a new user with an optional initial class assignment. */
createUser: async (id: string | bigint, username: string, classId?: bigint, tx?: Transaction) => {
return await withTransaction(async (txFn) => {
const [user] = await txFn.insert(users).values({
id: BigInt(id),
username,
classId,
}).returning();
return user;
}, tx);
},
/** Update a user record with partial data. */
updateUser: async (id: string, data: Partial<typeof users.$inferInsert>, tx?: Transaction) => {
return await withTransaction(async (txFn) => {
const [user] = await txFn.update(users)
.set(data)
.where(eq(users.id, BigInt(id)))
.returning();
return user;
}, tx);
},
/** Delete a user by ID. */
deleteUser: async (id: string, tx?: Transaction) => {
return await withTransaction(async (txFn) => {
await txFn.delete(users).where(eq(users.id, BigInt(id)));
}, tx);
},
};