2026-07-19 12:29:52 -05:00
|
|
|
import { eq } from "drizzle-orm";
|
|
|
|
|
import { userPreferences } from "../db/schema.js";
|
|
|
|
|
import type { DatabaseContext } from "./database-context.js";
|
2026-08-06 14:41:39 -05:00
|
|
|
import { rowsAffected } from "./mutation-result.js";
|
|
|
|
|
import { insertReturningWhere, updateReturning } from "./returning.js";
|
2026-07-19 12:29:52 -05:00
|
|
|
|
|
|
|
|
export type UserPreferenceRecord = typeof userPreferences.$inferSelect;
|
|
|
|
|
export type NewUserPreferenceRecord = typeof userPreferences.$inferInsert;
|
|
|
|
|
export type UserPreferenceUpdate = Partial<
|
|
|
|
|
Omit<NewUserPreferenceRecord, "userId">
|
|
|
|
|
>;
|
|
|
|
|
|
|
|
|
|
export class UserPreferenceRepository {
|
|
|
|
|
constructor(
|
|
|
|
|
private readonly context: DatabaseContext,
|
|
|
|
|
private readonly onWrite?: () => void | Promise<void>,
|
|
|
|
|
) {}
|
|
|
|
|
|
|
|
|
|
async findByUserId(userId: string): Promise<UserPreferenceRecord | null> {
|
|
|
|
|
const rows = await this.context.drizzle
|
|
|
|
|
.select()
|
|
|
|
|
.from(userPreferences)
|
|
|
|
|
.where(eq(userPreferences.userId, userId))
|
|
|
|
|
.limit(1);
|
|
|
|
|
|
|
|
|
|
return rows[0] ?? null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async upsert(
|
|
|
|
|
userId: string,
|
|
|
|
|
update: UserPreferenceUpdate,
|
|
|
|
|
): Promise<UserPreferenceRecord> {
|
|
|
|
|
const existing = await this.findByUserId(userId);
|
|
|
|
|
|
|
|
|
|
if (!existing) {
|
2026-08-06 14:41:39 -05:00
|
|
|
const rows = await insertReturningWhere(
|
|
|
|
|
this.context,
|
|
|
|
|
userPreferences,
|
|
|
|
|
{ userId, ...update },
|
|
|
|
|
eq(userPreferences.userId, userId),
|
|
|
|
|
);
|
2026-07-19 12:29:52 -05:00
|
|
|
await this.afterWrite();
|
|
|
|
|
return rows[0];
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-06 14:41:39 -05:00
|
|
|
const rows = await updateReturning(
|
|
|
|
|
this.context,
|
|
|
|
|
userPreferences,
|
|
|
|
|
update,
|
|
|
|
|
eq(userPreferences.userId, userId),
|
|
|
|
|
);
|
2026-07-19 12:29:52 -05:00
|
|
|
await this.afterWrite();
|
|
|
|
|
return rows[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async deleteByUserId(userId: string): Promise<number> {
|
2026-08-06 14:41:39 -05:00
|
|
|
const result = await this.context.drizzle
|
2026-07-19 12:29:52 -05:00
|
|
|
.delete(userPreferences)
|
2026-08-06 14:41:39 -05:00
|
|
|
.where(eq(userPreferences.userId, userId));
|
2026-07-19 12:29:52 -05:00
|
|
|
|
2026-08-06 14:41:39 -05:00
|
|
|
if (rowsAffected(result) > 0) {
|
2026-07-19 12:29:52 -05:00
|
|
|
await this.afterWrite();
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-06 14:41:39 -05:00
|
|
|
return rowsAffected(result);
|
2026-07-19 12:29:52 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async afterWrite(): Promise<void> {
|
|
|
|
|
await this.onWrite?.();
|
|
|
|
|
}
|
|
|
|
|
}
|