import { MongoClient, ObjectId, type Db, type Document } from "mongodb"; import type { Family, Organization, Person, Theme } from "./types"; const globalMongo = globalThis as typeof globalThis & { mongoClient?: Promise; mongoIndexed?: boolean; }; export async function db(): Promise { const uri = process.env.MONGODB_URI; if (!uri) throw new Error("MONGODB_URI is not configured"); const clientPromise = globalMongo.mongoClient ?? new MongoClient(uri).connect(); globalMongo.mongoClient = clientPromise; const client = await clientPromise; const database = client.db(process.env.MONGODB_DB || "kinship_directory"); if (!globalMongo.mongoIndexed) { await Promise.all([ database.collection("users").createIndex({ email: 1 }, { unique: true }), database.collection("families").createIndex({ organizationId: 1, familyName: 1 }), database.collection("images").createIndex({ organizationId: 1 }), database.collection("organizations").createIndex({ joinCode: 1 }, { unique: true }), ]); globalMongo.mongoIndexed = true; } return database; } const stringId = (value: unknown) => value instanceof ObjectId ? value.toHexString() : String(value); export function mapPerson(person: Document): Person { return { id: String(person.id), firstName: String(person.firstName || ""), lastName: String(person.lastName || ""), email: person.email ? String(person.email) : undefined, phone: person.phone ? String(person.phone) : undefined, birthday: person.birthday ? String(person.birthday) : undefined, photoId: person.photoId ? String(person.photoId) : undefined, }; } export function mapFamily(doc: Document): Family { return { id: stringId(doc._id), organizationId: stringId(doc.organizationId), familyName: String(doc.familyName), address: doc.address ? String(doc.address) : undefined, city: doc.city ? String(doc.city) : undefined, state: doc.state ? String(doc.state) : undefined, postalCode: doc.postalCode ? String(doc.postalCode) : undefined, homePhone: doc.homePhone ? String(doc.homePhone) : undefined, photoId: doc.photoId ? String(doc.photoId) : undefined, adults: Array.isArray(doc.adults) ? doc.adults.map(mapPerson) : [], children: Array.isArray(doc.children) ? doc.children.map(mapPerson) : [], updatedAt: doc.updatedAt instanceof Date ? doc.updatedAt.toISOString() : new Date().toISOString(), }; } const defaultTheme: Theme = { primary: "#173f35", accent: "#df9b63", surface: "#f7f4ed", font: "warm" }; export function mapOrganization(doc: Document): Organization { return { id: stringId(doc._id), name: String(doc.name), joinCode: String(doc.joinCode), logoId: doc.logoId ? String(doc.logoId) : undefined, faviconId: doc.faviconId ? String(doc.faviconId) : undefined, theme: { ...defaultTheme, ...(doc.theme || {}) }, }; } export function objectId(value: unknown): ObjectId | null { return typeof value === "string" && ObjectId.isValid(value) ? new ObjectId(value) : null; }