import { FieldValue } from "firebase-admin/firestore"; import { firestore } from "../firebase"; import type { KnowledgeLevel, Provider, TeamCode, User, } from "../types/panit"; const COLLECTION = "users"; export interface RegisterInput { displayName: string; email: string; photoUrl?: string; provider: Provider; favoriteTeamCode?: TeamCode; knowledgeLevel: KnowledgeLevel; } /** * 특정 유저 문서를 조회한다. * * @param uid - Firebase Auth UID * @returns 유저 문서. 존재하지 않으면 `null`. */ export async function getUser(uid: string): Promise { const snap = await firestore.collection(COLLECTION).doc(uid).get(); return snap.exists ? (snap.data() as User) : null; } /** * displayName으로 유저의 uid를 조회한다. 없으면 `null`. * 닉네임 유니크성 검증용 fallback. */ export async function findUidByDisplayName( displayName: string ): Promise { const snap = await firestore .collection(COLLECTION) .where("displayName", "==", displayName) .limit(1) .get(); return snap.empty ? null : snap.docs[0].id; } /** * 신규 유저 문서를 생성한다. `createdAt`은 서버 타임스탬프로 기록되며, * 같은 UID가 있으면 전체 덮어쓴다(`merge: false`). */ export async function createUser(uid: string, input: RegisterInput): Promise { const doc: Record = { displayName: input.displayName, email: input.email, provider: input.provider, knowledgeLevel: input.knowledgeLevel, createdAt: FieldValue.serverTimestamp(), }; if (input.photoUrl) doc.photoUrl = input.photoUrl; if (input.favoriteTeamCode) doc.favoriteTeamCode = input.favoriteTeamCode; await firestore.collection(COLLECTION).doc(uid).set(doc, { merge: false }); } /** * 유저 문서의 일부 필드를 병합 업데이트한다. */ export async function updateUser( uid: string, patch: Partial> ): Promise { await firestore.collection(COLLECTION).doc(uid).set(patch, { merge: true }); } /** * 유저 문서 및 하위 컬렉션(voteHistory 등)을 모두 삭제한다. */ export async function deleteUser(uid: string): Promise { await firestore.recursiveDelete(firestore.collection(COLLECTION).doc(uid)); }