/** * Drizzle Page Repository Adapter * * Implements PageRepository interface using Drizzle ORM. */ import { eq, isNull, and, asc, inArray } from 'drizzle-orm'; import { nanoid } from 'nanoid'; import type { DrizzleDatabase } from '../../index.js'; import { pages, type Page } from '../../schema.js'; import type { PageRepository, CreatePageData, UpdatePageData, } from '../page-repository.js'; export class DrizzlePageRepository implements PageRepository { constructor(private db: DrizzleDatabase) {} async create(data: CreatePageData): Promise { const id = data.id ?? nanoid(); const now = new Date(); const [created] = await this.db.insert(pages).values({ id, ...data, createdAt: now, updatedAt: now, }).returning(); return created; } async findById(id: string): Promise { const result = await this.db .select() .from(pages) .where(eq(pages.id, id)) .limit(1); return result[0] ?? null; } async findByIds(ids: string[]): Promise { if (ids.length === 0) return []; return this.db .select() .from(pages) .where(inArray(pages.id, ids)); } async findByInitiativeId(initiativeId: string): Promise { return this.db .select() .from(pages) .where(eq(pages.initiativeId, initiativeId)) .orderBy(asc(pages.sortOrder)); } async findByParentPageId(parentPageId: string): Promise { return this.db .select() .from(pages) .where(eq(pages.parentPageId, parentPageId)) .orderBy(asc(pages.sortOrder)); } async findRootPage(initiativeId: string): Promise { const result = await this.db .select() .from(pages) .where( and( eq(pages.initiativeId, initiativeId), isNull(pages.parentPageId), ), ) .limit(1); return result[0] ?? null; } async getOrCreateRootPage(initiativeId: string): Promise { const existing = await this.findRootPage(initiativeId); if (existing) return existing; return this.create({ initiativeId, parentPageId: null, title: 'Untitled', content: null, sortOrder: 0, }); } async update(id: string, data: UpdatePageData): Promise { const [updated] = await this.db .update(pages) .set({ ...data, updatedAt: new Date() }) .where(eq(pages.id, id)) .returning(); if (!updated) { throw new Error(`Page not found: ${id}`); } return updated; } async delete(id: string): Promise { const [deleted] = await this.db.delete(pages).where(eq(pages.id, id)).returning(); if (!deleted) { throw new Error(`Page not found: ${id}`); } } }