From 1e04c763f0180d578bb66b21893cf5bc695d631a Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Sun, 1 Feb 2026 15:30:36 +0100 Subject: [PATCH] refactor: convert all findMany to new structure --- .../auth-middlewares/convert-legacy-user.ts | 8 +- app/lib/auth-middlewares/only-one-user.ts | 4 +- app/lib/auth.ts | 2 +- .../cli/commands/assign-organization.ts | 6 +- app/server/db/db.ts | 7 +- app/server/db/relations.ts | 141 ++++++++++++++++ app/server/db/schema.ts | 151 ++++-------------- app/server/jobs/auto-remount.ts | 4 +- app/server/jobs/healthchecks.ts | 6 +- app/server/jobs/repository-healthchecks.ts | 4 +- app/server/modules/auth/auth.middleware.ts | 10 +- app/server/modules/auth/auth.service.ts | 6 +- app/server/modules/auth/helpers.ts | 4 +- app/server/modules/backups/backups.service.ts | 107 +++++++------ app/server/modules/lifecycle/migrations.ts | 5 +- .../migrations/00001-retag-snapshots.ts | 6 +- .../migrations/00003-assign-organization.ts | 9 +- app/server/modules/lifecycle/shutdown.ts | 4 +- app/server/modules/lifecycle/startup.ts | 16 +- .../notifications/notifications.service.ts | 27 ++-- .../repositories/repositories.service.ts | 13 +- .../modules/system/system.controller.ts | 6 +- app/server/modules/system/system.service.ts | 3 +- app/server/modules/volumes/volume.service.ts | 12 +- app/server/utils/restic.ts | 6 +- app/test/helpers/organization.ts | 2 +- e2e/helpers/db.ts | 4 +- 27 files changed, 304 insertions(+), 269 deletions(-) create mode 100644 app/server/db/relations.ts diff --git a/app/lib/auth-middlewares/convert-legacy-user.ts b/app/lib/auth-middlewares/convert-legacy-user.ts index f96c3034..759d7109 100644 --- a/app/lib/auth-middlewares/convert-legacy-user.ts +++ b/app/lib/auth-middlewares/convert-legacy-user.ts @@ -1,5 +1,5 @@ import { hashPassword } from "better-auth/crypto"; -import { and, eq, ne } from "drizzle-orm"; +import { eq } from "drizzle-orm"; import { db } from "~/server/db/db"; import { account, usersTable, member, organization } from "~/server/db/schema"; import type { AuthMiddlewareContext } from "../auth"; @@ -14,7 +14,9 @@ export const convertLegacyUserOnFirstLogin = async (ctx: AuthMiddlewareContext) } const legacyUser = await db.query.usersTable.findFirst({ - where: and(eq(usersTable.username, body.username.trim().toLowerCase()), ne(usersTable.passwordHash, "")), + where: { + AND: [{ username: body.username.trim().toLowerCase() }, { passwordHash: { NOT: "" } }], + }, }); if (legacyUser) { @@ -26,7 +28,7 @@ export const convertLegacyUserOnFirstLogin = async (ctx: AuthMiddlewareContext) const accountId = crypto.randomUUID(); const oldMembership = await tx.query.member.findFirst({ - where: eq(member.userId, legacyUser.id), + where: { userId: legacyUser.id }, with: { organization: true, }, diff --git a/app/lib/auth-middlewares/only-one-user.ts b/app/lib/auth-middlewares/only-one-user.ts index 9d69cd9e..6f013f35 100644 --- a/app/lib/auth-middlewares/only-one-user.ts +++ b/app/lib/auth-middlewares/only-one-user.ts @@ -1,8 +1,6 @@ import { db } from "~/server/db/db"; import type { AuthMiddlewareContext } from "../auth"; import { logger } from "~/server/utils/logger"; -import { eq } from "drizzle-orm"; -import { appMetadataTable } from "~/server/db/schema"; import { ForbiddenError } from "http-errors-enhanced"; import { REGISTRATION_ENABLED_KEY } from "~/client/lib/constants"; @@ -15,7 +13,7 @@ export const ensureOnlyOneUser = async (ctx: AuthMiddlewareContext) => { } const result = await db.query.appMetadataTable.findFirst({ - where: eq(appMetadataTable.key, REGISTRATION_ENABLED_KEY), + where: { key: REGISTRATION_ENABLED_KEY }, }); if (result?.value !== "true" && existingUser) { diff --git a/app/lib/auth.ts b/app/lib/auth.ts index 85e4fd16..8b418291 100644 --- a/app/lib/auth.ts +++ b/app/lib/auth.ts @@ -98,7 +98,7 @@ const createBetterAuth = (secret: string) => { create: { before: async (session) => { const orgMembership = await db.query.member.findFirst({ - where: eq(member.userId, session.userId), + where: { userId: session.userId }, }); if (!orgMembership) { diff --git a/app/server/cli/commands/assign-organization.ts b/app/server/cli/commands/assign-organization.ts index a00b50d7..ee32f323 100644 --- a/app/server/cli/commands/assign-organization.ts +++ b/app/server/cli/commands/assign-organization.ts @@ -15,7 +15,7 @@ const listOrganizations = () => { const getUserCurrentOrganization = async (userId: string) => { const membership = await db.query.member.findFirst({ - where: eq(member.userId, userId), + where: { userId }, with: { organization: true, }, @@ -36,9 +36,7 @@ const assignUserToOrganization = async (userId: string, organizationId: string) throw new Error("Organization not found"); } - const existingMembership = await db.query.member.findFirst({ - where: eq(member.userId, userId), - }); + const existingMembership = await db.query.member.findFirst({ where: { userId } }); await db.transaction(async (tx) => { if (existingMembership) { diff --git a/app/server/db/db.ts b/app/server/db/db.ts index ac57536d..0f6862aa 100644 --- a/app/server/db/db.ts +++ b/app/server/db/db.ts @@ -1,4 +1,5 @@ import { Database } from "bun:sqlite"; +import { relations } from "./relations"; import path from "node:path"; import { drizzle } from "drizzle-orm/bun-sqlite"; import { migrate } from "drizzle-orm/bun-sqlite/migrator"; @@ -13,7 +14,7 @@ import type * as schemaTypes from "./schema"; * to isolate the db initialization code from the rest of the server code. */ let _sqlite: Database | undefined; -let _db: ReturnType> | undefined; +let _db: ReturnType | undefined; let _schema: typeof schemaTypes | undefined; /** @@ -35,7 +36,7 @@ const initDb = () => { } _sqlite = new Database(DATABASE_URL); - return drizzle({ client: _sqlite, schema: _schema }); + return drizzle({ client: _sqlite, relations, schema: _schema }); }; /** @@ -51,7 +52,7 @@ export const db = new Proxy( return Reflect.get(_db, prop, receiver); }, }, -) as ReturnType>; +) as ReturnType; export const runDbMigrations = () => { let migrationsFolder: string; diff --git a/app/server/db/relations.ts b/app/server/db/relations.ts new file mode 100644 index 00000000..14448e7c --- /dev/null +++ b/app/server/db/relations.ts @@ -0,0 +1,141 @@ +import { defineRelations } from "drizzle-orm"; +import * as schema from "./schema"; + +export const relations = defineRelations(schema, (r) => ({ + repositoriesTable: { + backupSchedulesTablesViaBackupScheduleMirrorsTable: r.many.backupSchedulesTable({ + from: r.repositoriesTable.id.through(r.backupScheduleMirrorsTable.repositoryId), + to: r.backupSchedulesTable.id.through(r.backupScheduleMirrorsTable.scheduleId), + alias: "repositoriesTable_id_backupSchedulesTable_id_via_backupScheduleMirrorsTable", + }), + backupSchedules: r.many.backupSchedulesTable({ + alias: "backupSchedulesTable_repositoryId_repositoriesTable_id", + }), + organization: r.one.organization({ + from: r.repositoriesTable.organizationId, + to: r.organization.id, + }), + }, + backupScheduleMirrorsTable: { + repository: r.one.repositoriesTable({ + from: r.backupScheduleMirrorsTable.repositoryId, + to: r.repositoriesTable.id, + optional: false, + }), + backupSchedule: r.one.backupSchedulesTable({ + from: r.backupScheduleMirrorsTable.scheduleId, + to: r.backupSchedulesTable.id, + optional: false, + }), + }, + backupSchedulesTable: { + mirrors: r.many.repositoriesTable({ + alias: "repositoriesTable_id_backupSchedulesTable_id_via_backupScheduleMirrorsTable", + }), + notificationDestinationsTables: r.many.notificationDestinationsTable(), + organization: r.one.organization({ + from: r.backupSchedulesTable.organizationId, + to: r.organization.id, + optional: false, + }), + repository: r.one.repositoriesTable({ + from: r.backupSchedulesTable.repositoryId, + to: r.repositoriesTable.id, + alias: "backupSchedulesTable_repositoryId_repositoriesTable_id", + optional: false, + }), + volume: r.one.volumesTable({ + from: r.backupSchedulesTable.volumeId, + to: r.volumesTable.id, + optional: false, + }), + }, + notificationDestinationsTable: { + backupSchedules: r.many.backupSchedulesTable({ + from: r.notificationDestinationsTable.id.through(r.backupScheduleNotificationsTable.destinationId), + to: r.backupSchedulesTable.id.through(r.backupScheduleNotificationsTable.scheduleId), + }), + organization: r.one.organization({ + from: r.notificationDestinationsTable.organizationId, + to: r.organization.id, + }), + }, + account: { + user: r.one.usersTable({ + from: r.account.userId, + to: r.usersTable.id, + }), + }, + usersTable: { + accounts: r.many.account(), + sessions: r.many.sessionsTable(), + members: r.many.member(), + twoFactors: r.many.twoFactor(), + organizations: r.many.organization({ + from: r.usersTable.id.through(r.member.userId), + to: r.organization.id.through(r.member.organizationId), + alias: "usersTable_id_organization_id_via_member", + }), + }, + sessionsTable: { + user: r.one.usersTable({ + from: r.sessionsTable.userId, + to: r.usersTable.id, + }), + }, + twoFactor: { + usersTable: r.one.usersTable({ + from: r.twoFactor.userId, + to: r.usersTable.id, + }), + }, + organization: { + users: r.many.usersTable({ + alias: "usersTable_id_organization_id_via_member", + }), + backupSchedules: r.many.backupSchedulesTable(), + notificationDestinations: r.many.notificationDestinationsTable(), + repositories: r.many.repositoriesTable(), + volumes: r.many.volumesTable(), + members: r.many.member(), + invitations: r.many.invitation(), + }, + volumesTable: { + backupSchedules: r.many.backupSchedulesTable(), + organization: r.one.organization({ + from: r.volumesTable.organizationId, + to: r.organization.id, + }), + }, + member: { + user: r.one.usersTable({ + from: r.member.userId, + to: r.usersTable.id, + optional: false, + }), + organization: r.one.organization({ + from: r.member.organizationId, + to: r.organization.id, + optional: false, + }), + }, + invitation: { + organization: r.one.organization({ + from: r.invitation.organizationId, + to: r.organization.id, + optional: false, + }), + }, + backupScheduleNotificationsTable: { + destination: r.one.notificationDestinationsTable({ + from: r.backupScheduleNotificationsTable.destinationId, + to: r.notificationDestinationsTable.id, + optional: false, + }), + backupSchedule: r.one.backupSchedulesTable({ + from: r.backupScheduleNotificationsTable.scheduleId, + to: r.backupSchedulesTable.id, + optional: false, + }), + }, +})); diff --git a/app/server/db/schema.ts b/app/server/db/schema.ts index cea47842..ecdce860 100644 --- a/app/server/db/schema.ts +++ b/app/server/db/schema.ts @@ -1,4 +1,4 @@ -import { relations, sql } from "drizzle-orm"; +import { sql } from "drizzle-orm"; import { index, int, integer, sqliteTable, text, real, primaryKey, unique, uniqueIndex } from "drizzle-orm/sqlite-core"; import type { CompressionMode, @@ -175,29 +175,33 @@ export const invitation = sqliteTable( /** * Volumes Table */ -export const volumesTable = sqliteTable("volumes_table", { - id: int().primaryKey({ autoIncrement: true }), - shortId: text("short_id").notNull().unique(), - name: text().notNull(), - type: text().$type().notNull(), - status: text().$type().notNull().default("unmounted"), - lastError: text("last_error"), - lastHealthCheck: integer("last_health_check", { mode: "number" }) - .notNull() - .default(sql`(unixepoch() * 1000)`), - createdAt: integer("created_at", { mode: "number" }) - .notNull() - .default(sql`(unixepoch() * 1000)`), - updatedAt: integer("updated_at", { mode: "number" }) - .notNull() - .$onUpdate(() => Date.now()) - .default(sql`(unixepoch() * 1000)`), - config: text("config", { mode: "json" }).$type().notNull(), - autoRemount: int("auto_remount", { mode: "boolean" }).notNull().default(true), - organizationId: text("organization_id") - .notNull() - .references(() => organization.id, { onDelete: "cascade" }), -}, (table) => [unique().on(table.name, table.organizationId)]); +export const volumesTable = sqliteTable( + "volumes_table", + { + id: int().primaryKey({ autoIncrement: true }), + shortId: text("short_id").notNull().unique(), + name: text().notNull(), + type: text().$type().notNull(), + status: text().$type().notNull().default("unmounted"), + lastError: text("last_error"), + lastHealthCheck: integer("last_health_check", { mode: "number" }) + .notNull() + .default(sql`(unixepoch() * 1000)`), + createdAt: integer("created_at", { mode: "number" }) + .notNull() + .default(sql`(unixepoch() * 1000)`), + updatedAt: integer("updated_at", { mode: "number" }) + .notNull() + .$onUpdate(() => Date.now()) + .default(sql`(unixepoch() * 1000)`), + config: text("config", { mode: "json" }).$type().notNull(), + autoRemount: int("auto_remount", { mode: "boolean" }).notNull().default(true), + organizationId: text("organization_id") + .notNull() + .references(() => organization.id, { onDelete: "cascade" }), + }, + (table) => [unique().on(table.name, table.organizationId)], +); export type Volume = typeof volumesTable.$inferSelect; export type VolumeInsert = typeof volumesTable.$inferInsert; @@ -381,102 +385,3 @@ export const twoFactor = sqliteTable( }, (table) => [index("twoFactor_secret_idx").on(table.secret), index("twoFactor_userId_idx").on(table.userId)], ); - -export const userRelations = relations(usersTable, ({ many }) => ({ - sessions: many(sessionsTable), - accounts: many(account), - members: many(member), - invitations: many(invitation), - twoFactors: many(twoFactor), -})); - -export const sessionRelations = relations(sessionsTable, ({ one }) => ({ - user: one(usersTable, { - fields: [sessionsTable.userId], - references: [usersTable.id], - }), - activeOrganization: one(organization, { - fields: [sessionsTable.activeOrganizationId], - references: [organization.id], - }), -})); - -export const accountRelations = relations(account, ({ one }) => ({ - user: one(usersTable, { - fields: [account.userId], - references: [usersTable.id], - }), -})); - -export const organizationRelations = relations(organization, ({ many }) => ({ - members: many(member), - invitations: many(invitation), -})); - -export const memberRelations = relations(member, ({ one }) => ({ - organization: one(organization, { - fields: [member.organizationId], - references: [organization.id], - }), - usersTable: one(usersTable, { - fields: [member.userId], - references: [usersTable.id], - }), -})); - -export const invitationRelations = relations(invitation, ({ one }) => ({ - organization: one(organization, { - fields: [invitation.organizationId], - references: [organization.id], - }), - usersTable: one(usersTable, { - fields: [invitation.inviterId], - references: [usersTable.id], - }), -})); - -export const twoFactorRelations = relations(twoFactor, ({ one }) => ({ - usersTable: one(usersTable, { - fields: [twoFactor.userId], - references: [usersTable.id], - }), -})); - -export const backupScheduleMirrorRelations = relations(backupScheduleMirrorsTable, ({ one }) => ({ - schedule: one(backupSchedulesTable, { - fields: [backupScheduleMirrorsTable.scheduleId], - references: [backupSchedulesTable.id], - }), - repository: one(repositoriesTable, { - fields: [backupScheduleMirrorsTable.repositoryId], - references: [repositoriesTable.id], - }), -})); - -export const backupScheduleRelations = relations(backupSchedulesTable, ({ one, many }) => ({ - volume: one(volumesTable, { - fields: [backupSchedulesTable.volumeId], - references: [volumesTable.id], - }), - repository: one(repositoriesTable, { - fields: [backupSchedulesTable.repositoryId], - references: [repositoriesTable.id], - }), - notifications: many(backupScheduleNotificationsTable), - mirrors: many(backupScheduleMirrorsTable), -})); - -export const notificationDestinationRelations = relations(notificationDestinationsTable, ({ many }) => ({ - schedules: many(backupScheduleNotificationsTable), -})); - -export const backupScheduleNotificationRelations = relations(backupScheduleNotificationsTable, ({ one }) => ({ - schedule: one(backupSchedulesTable, { - fields: [backupScheduleNotificationsTable.scheduleId], - references: [backupSchedulesTable.id], - }), - destination: one(notificationDestinationsTable, { - fields: [backupScheduleNotificationsTable.destinationId], - references: [notificationDestinationsTable.id], - }), -})); diff --git a/app/server/jobs/auto-remount.ts b/app/server/jobs/auto-remount.ts index af528d03..5098a786 100644 --- a/app/server/jobs/auto-remount.ts +++ b/app/server/jobs/auto-remount.ts @@ -2,8 +2,6 @@ import { Job } from "../core/scheduler"; import { volumeService } from "../modules/volumes/volume.service"; import { logger } from "../utils/logger"; import { db } from "../db/db"; -import { eq } from "drizzle-orm"; -import { volumesTable } from "../db/schema"; import { withContext } from "../core/request-context"; export class VolumeAutoRemountJob extends Job { @@ -11,7 +9,7 @@ export class VolumeAutoRemountJob extends Job { logger.debug("Running auto-remount for all errored volumes..."); const volumes = await db.query.volumesTable.findMany({ - where: eq(volumesTable.status, "error"), + where: { status: "error" }, }); for (const volume of volumes) { diff --git a/app/server/jobs/healthchecks.ts b/app/server/jobs/healthchecks.ts index c872ebae..7491ca98 100644 --- a/app/server/jobs/healthchecks.ts +++ b/app/server/jobs/healthchecks.ts @@ -2,8 +2,6 @@ import { Job } from "../core/scheduler"; import { volumeService } from "../modules/volumes/volume.service"; import { logger } from "../utils/logger"; import { db } from "../db/db"; -import { eq, or } from "drizzle-orm"; -import { volumesTable } from "../db/schema"; import { withContext } from "../core/request-context"; export class VolumeHealthCheckJob extends Job { @@ -11,7 +9,9 @@ export class VolumeHealthCheckJob extends Job { logger.debug("Running health check for all volumes..."); const volumes = await db.query.volumesTable.findMany({ - where: or(eq(volumesTable.status, "mounted"), eq(volumesTable.status, "error")), + where: { + OR: [{ status: "mounted" }, { status: "error" }], + }, }); for (const volume of volumes) { diff --git a/app/server/jobs/repository-healthchecks.ts b/app/server/jobs/repository-healthchecks.ts index 94b054c4..bb0aa80e 100644 --- a/app/server/jobs/repository-healthchecks.ts +++ b/app/server/jobs/repository-healthchecks.ts @@ -2,8 +2,6 @@ import { Job } from "../core/scheduler"; import { repositoriesService } from "../modules/repositories/repositories.service"; import { logger } from "../utils/logger"; import { db } from "../db/db"; -import { eq, or } from "drizzle-orm"; -import { repositoriesTable } from "../db/schema"; import { withContext } from "../core/request-context"; export class RepositoryHealthCheckJob extends Job { @@ -11,7 +9,7 @@ export class RepositoryHealthCheckJob extends Job { logger.debug("Running health check for all repositories..."); const repositories = await db.query.repositoriesTable.findMany({ - where: or(eq(repositoriesTable.status, "healthy"), eq(repositoriesTable.status, "error")), + where: { OR: [{ status: "healthy" }, { status: "error" }] }, }); for (const repository of repositories) { diff --git a/app/server/modules/auth/auth.middleware.ts b/app/server/modules/auth/auth.middleware.ts index 24f415af..90134cd5 100644 --- a/app/server/modules/auth/auth.middleware.ts +++ b/app/server/modules/auth/auth.middleware.ts @@ -1,8 +1,6 @@ import { createMiddleware } from "hono/factory"; import { auth } from "~/lib/auth"; import { db } from "~/server/db/db"; -import { member } from "~/server/db/schema"; -import { eq, and } from "drizzle-orm"; import { withContext } from "~/server/core/request-context"; declare module "hono" { @@ -34,7 +32,9 @@ export const requireAuth = createMiddleware(async (c, next) => { } const membership = await db.query.member.findFirst({ - where: and(eq(member.userId, user.id), eq(member.organizationId, activeOrganizationId)), + where: { + AND: [{ userId: user.id }, { organizationId: activeOrganizationId }], + }, }); if (!membership) { @@ -58,7 +58,9 @@ export const requireOrgAdmin = createMiddleware(async (c, next) => { const organizationId = c.get("organizationId"); const membership = await db.query.member.findFirst({ - where: and(eq(member.userId, user.id), eq(member.organizationId, organizationId)), + where: { + AND: [{ userId: user.id }, { organizationId: organizationId }], + }, }); if (!membership || (membership.role !== "owner" && membership.role !== "admin")) { diff --git a/app/server/modules/auth/auth.service.ts b/app/server/modules/auth/auth.service.ts index 15b60ad5..cf1bcc22 100644 --- a/app/server/modules/auth/auth.service.ts +++ b/app/server/modules/auth/auth.service.ts @@ -24,7 +24,9 @@ export class AuthService { */ async getUserDeletionImpact(userId: string): Promise { const userMemberships = await db.query.member.findMany({ - where: and(eq(member.userId, userId), eq(member.role, "owner")), + where: { + AND: [{ userId: userId }, { role: "owner" }], + }, }); const impacts: UserDeletionImpactDto["organizations"] = []; @@ -43,7 +45,7 @@ export class AuthService { if (otherOwners[0].count === 0) { const org = await db.query.organization.findFirst({ - where: eq(organization.id, membership.organizationId), + where: { id: membership.organizationId }, }); if (org) { diff --git a/app/server/modules/auth/helpers.ts b/app/server/modules/auth/helpers.ts index f5e31470..1a3733b9 100644 --- a/app/server/modules/auth/helpers.ts +++ b/app/server/modules/auth/helpers.ts @@ -1,7 +1,5 @@ import { verifyPassword } from "better-auth/crypto"; -import { eq } from "drizzle-orm"; import { db } from "~/server/db/db"; -import { account } from "~/server/db/schema"; type PasswordVerificationBody = { userId: string; @@ -10,7 +8,7 @@ type PasswordVerificationBody = { export const verifyUserPassword = async ({ password, userId }: PasswordVerificationBody) => { const userAccount = await db.query.account.findFirst({ - where: eq(account.userId, userId), + where: { userId }, }); if (!userAccount || !userAccount.password) { diff --git a/app/server/modules/backups/backups.service.ts b/app/server/modules/backups/backups.service.ts index 7b290817..5661b52e 100644 --- a/app/server/modules/backups/backups.service.ts +++ b/app/server/modules/backups/backups.service.ts @@ -1,9 +1,9 @@ -import { and, asc, eq, isNull, ne, or } from "drizzle-orm"; +import { and, eq } from "drizzle-orm"; import cron from "node-cron"; import { CronExpressionParser } from "cron-parser"; import { NotFoundError, BadRequestError, ConflictError } from "http-errors-enhanced"; import { db } from "../../db/db"; -import { backupSchedulesTable, backupScheduleMirrorsTable, repositoriesTable, volumesTable } from "../../db/schema"; +import { backupSchedulesTable, backupScheduleMirrorsTable, repositoriesTable } from "../../db/schema"; import { restic } from "../../utils/restic"; import { logger } from "../../utils/logger"; import { cache } from "../../utils/cache"; @@ -60,12 +60,9 @@ const processPattern = (pattern: string, volumePath: string) => { const listSchedules = async () => { const organizationId = getOrganizationId(); const schedules = await db.query.backupSchedulesTable.findMany({ - where: eq(backupSchedulesTable.organizationId, organizationId), - with: { - volume: true, - repository: true, - }, - orderBy: [asc(backupSchedulesTable.sortOrder), asc(backupSchedulesTable.id)], + where: { organizationId }, + with: { volume: true, repository: true }, + orderBy: { sortOrder: "asc", id: "asc" }, }); return schedules; }; @@ -73,11 +70,8 @@ const listSchedules = async () => { const getSchedule = async (scheduleId: number) => { const organizationId = getOrganizationId(); const schedule = await db.query.backupSchedulesTable.findFirst({ - where: and(eq(backupSchedulesTable.id, scheduleId), eq(backupSchedulesTable.organizationId, organizationId)), - with: { - volume: true, - repository: true, - }, + where: { AND: [{ id: scheduleId }, { organizationId }] }, + with: { volume: true, repository: true }, }); if (!schedule) { @@ -94,7 +88,9 @@ const createSchedule = async (data: CreateBackupScheduleBody) => { } const existingName = await db.query.backupSchedulesTable.findFirst({ - where: and(eq(backupSchedulesTable.name, data.name), eq(backupSchedulesTable.organizationId, organizationId)), + where: { + AND: [{ name: data.name }, { organizationId }], + }, }); if (existingName) { @@ -102,7 +98,9 @@ const createSchedule = async (data: CreateBackupScheduleBody) => { } const volume = await db.query.volumesTable.findFirst({ - where: and(eq(volumesTable.id, data.volumeId), eq(volumesTable.organizationId, organizationId)), + where: { + AND: [{ id: data.volumeId }, { organizationId }], + }, }); if (!volume) { @@ -110,7 +108,9 @@ const createSchedule = async (data: CreateBackupScheduleBody) => { } const repository = await db.query.repositoriesTable.findFirst({ - where: and(eq(repositoriesTable.id, data.repositoryId), eq(repositoriesTable.organizationId, organizationId)), + where: { + AND: [{ id: data.repositoryId }, { organizationId }], + }, }); if (!repository) { @@ -148,7 +148,9 @@ const createSchedule = async (data: CreateBackupScheduleBody) => { const updateSchedule = async (scheduleId: number, data: UpdateBackupScheduleBody) => { const organizationId = getOrganizationId(); const schedule = await db.query.backupSchedulesTable.findFirst({ - where: and(eq(backupSchedulesTable.id, scheduleId), eq(backupSchedulesTable.organizationId, organizationId)), + where: { + AND: [{ id: scheduleId }, { organizationId }], + }, }); if (!schedule) { @@ -161,11 +163,9 @@ const updateSchedule = async (scheduleId: number, data: UpdateBackupScheduleBody if (data.name) { const existingName = await db.query.backupSchedulesTable.findFirst({ - where: and( - eq(backupSchedulesTable.name, data.name), - ne(backupSchedulesTable.id, scheduleId), - eq(backupSchedulesTable.organizationId, organizationId), - ), + where: { + AND: [{ name: data.name }, { NOT: { id: scheduleId } }, { organizationId }], + }, }); if (existingName) { @@ -174,7 +174,9 @@ const updateSchedule = async (scheduleId: number, data: UpdateBackupScheduleBody } const repository = await db.query.repositoriesTable.findFirst({ - where: and(eq(repositoriesTable.id, data.repositoryId), eq(repositoriesTable.organizationId, organizationId)), + where: { + AND: [{ id: data.repositoryId }, { organizationId }], + }, }); if (!repository) { @@ -200,7 +202,9 @@ const updateSchedule = async (scheduleId: number, data: UpdateBackupScheduleBody const deleteSchedule = async (scheduleId: number) => { const organizationId = getOrganizationId(); const schedule = await db.query.backupSchedulesTable.findFirst({ - where: and(eq(backupSchedulesTable.id, scheduleId), eq(backupSchedulesTable.organizationId, organizationId)), + where: { + AND: [{ id: scheduleId }, { organizationId }], + }, }); if (!schedule) { @@ -215,7 +219,7 @@ const deleteSchedule = async (scheduleId: number) => { const executeBackup = async (scheduleId: number, manual = false) => { const organizationId = getOrganizationId(); const schedule = await db.query.backupSchedulesTable.findFirst({ - where: and(eq(backupSchedulesTable.id, scheduleId), eq(backupSchedulesTable.organizationId, organizationId)), + where: { AND: [{ id: scheduleId }, { organizationId }] }, }); if (!schedule) { @@ -233,7 +237,7 @@ const executeBackup = async (scheduleId: number, manual = false) => { } const volume = await db.query.volumesTable.findFirst({ - where: and(eq(volumesTable.id, schedule.volumeId), eq(volumesTable.organizationId, organizationId)), + where: { AND: [{ id: schedule.volumeId }, { organizationId }] }, }); if (!volume) { @@ -241,7 +245,7 @@ const executeBackup = async (scheduleId: number, manual = false) => { } const repository = await db.query.repositoriesTable.findFirst({ - where: and(eq(repositoriesTable.id, schedule.repositoryId), eq(repositoriesTable.organizationId, organizationId)), + where: { AND: [{ id: schedule.repositoryId }, { organizationId }] }, }); if (!repository) { @@ -436,11 +440,9 @@ const getSchedulesToExecute = async () => { const organizationId = getOrganizationId(); const now = Date.now(); const schedules = await db.query.backupSchedulesTable.findMany({ - where: and( - eq(backupSchedulesTable.enabled, true), - or(ne(backupSchedulesTable.lastBackupStatus, "in_progress"), isNull(backupSchedulesTable.lastBackupStatus)), - eq(backupSchedulesTable.organizationId, organizationId), - ), + where: { + AND: [{ enabled: true }, { lastBackupStatus: { NOT: "in_progress" } }, { organizationId }], + }, }); const schedulesToRun: number[] = []; @@ -457,7 +459,7 @@ const getSchedulesToExecute = async () => { const getScheduleForVolume = async (volumeId: number) => { const organizationId = getOrganizationId(); const schedule = await db.query.backupSchedulesTable.findFirst({ - where: and(eq(backupSchedulesTable.volumeId, volumeId), eq(backupSchedulesTable.organizationId, organizationId)), + where: { AND: [{ volumeId }, { organizationId }] }, with: { volume: true, repository: true }, }); @@ -467,7 +469,7 @@ const getScheduleForVolume = async (volumeId: number) => { const stopBackup = async (scheduleId: number) => { const organizationId = getOrganizationId(); const schedule = await db.query.backupSchedulesTable.findFirst({ - where: and(eq(backupSchedulesTable.id, scheduleId), eq(backupSchedulesTable.organizationId, organizationId)), + where: { AND: [{ id: scheduleId }, { organizationId }] }, }); if (!schedule) { @@ -498,7 +500,9 @@ const stopBackup = async (scheduleId: number) => { const runForget = async (scheduleId: number, repositoryId?: string) => { const organizationId = getOrganizationId(); const schedule = await db.query.backupSchedulesTable.findFirst({ - where: and(eq(backupSchedulesTable.id, scheduleId), eq(backupSchedulesTable.organizationId, organizationId)), + where: { + AND: [{ id: scheduleId }, { organizationId }], + }, }); if (!schedule) { @@ -510,10 +514,9 @@ const runForget = async (scheduleId: number, repositoryId?: string) => { } const repository = await db.query.repositoriesTable.findFirst({ - where: and( - eq(repositoriesTable.id, repositoryId ?? schedule.repositoryId), - eq(repositoriesTable.organizationId, organizationId), - ), + where: { + AND: [{ id: repositoryId ?? schedule.repositoryId }, { organizationId }], + }, }); if (!repository) { @@ -535,7 +538,9 @@ const runForget = async (scheduleId: number, repositoryId?: string) => { const getMirrors = async (scheduleId: number) => { const organizationId = getOrganizationId(); const schedule = await db.query.backupSchedulesTable.findFirst({ - where: and(eq(backupSchedulesTable.id, scheduleId), eq(backupSchedulesTable.organizationId, organizationId)), + where: { + AND: [{ id: scheduleId }, { organizationId }], + }, }); if (!schedule) { @@ -543,7 +548,9 @@ const getMirrors = async (scheduleId: number) => { } const mirrors = await db.query.backupScheduleMirrorsTable.findMany({ - where: eq(backupScheduleMirrorsTable.scheduleId, scheduleId), + where: { + scheduleId, + }, with: { repository: true }, }); @@ -553,7 +560,7 @@ const getMirrors = async (scheduleId: number) => { const updateMirrors = async (scheduleId: number, data: UpdateScheduleMirrorsBody) => { const organizationId = getOrganizationId(); const schedule = await db.query.backupSchedulesTable.findFirst({ - where: and(eq(backupSchedulesTable.id, scheduleId), eq(backupSchedulesTable.organizationId, organizationId)), + where: { AND: [{ id: scheduleId }, { organizationId }] }, with: { repository: true }, }); @@ -567,7 +574,7 @@ const updateMirrors = async (scheduleId: number, data: UpdateScheduleMirrorsBody } const repo = await db.query.repositoriesTable.findFirst({ - where: and(eq(repositoriesTable.id, mirror.repositoryId), eq(repositoriesTable.organizationId, organizationId)), + where: { AND: [{ id: mirror.repositoryId }, { organizationId }] }, }); if (!repo) { @@ -584,7 +591,7 @@ const updateMirrors = async (scheduleId: number, data: UpdateScheduleMirrorsBody } const existingMirrors = await db.query.backupScheduleMirrorsTable.findMany({ - where: eq(backupScheduleMirrorsTable.scheduleId, scheduleId), + where: { scheduleId }, }); const existingMirrorsMap = new Map( @@ -622,7 +629,7 @@ const copyToMirrors = async ( ) => { const organizationId = getOrganizationId(); const schedule = await db.query.backupSchedulesTable.findFirst({ - where: and(eq(backupSchedulesTable.id, scheduleId), eq(backupSchedulesTable.organizationId, organizationId)), + where: { AND: [{ id: scheduleId }, { organizationId }] }, }); if (!schedule) { @@ -630,7 +637,7 @@ const copyToMirrors = async ( } const mirrors = await db.query.backupScheduleMirrorsTable.findMany({ - where: eq(backupScheduleMirrorsTable.scheduleId, scheduleId), + where: { scheduleId }, with: { repository: true }, }); @@ -712,7 +719,7 @@ const copyToMirrors = async ( const getMirrorCompatibility = async (scheduleId: number) => { const organizationId = getOrganizationId(); const schedule = await db.query.backupSchedulesTable.findFirst({ - where: and(eq(backupSchedulesTable.id, scheduleId), eq(backupSchedulesTable.organizationId, organizationId)), + where: { AND: [{ id: scheduleId }, { organizationId }] }, with: { repository: true }, }); @@ -720,9 +727,7 @@ const getMirrorCompatibility = async (scheduleId: number) => { throw new NotFoundError("Backup schedule not found"); } - const allRepositories = await db.query.repositoriesTable.findMany({ - where: eq(repositoriesTable.organizationId, organizationId), - }); + const allRepositories = await db.query.repositoriesTable.findMany({ where: { organizationId } }); const repos = allRepositories.filter((repo) => repo.id !== schedule.repositoryId); const compatibility = await Promise.all( @@ -740,7 +745,7 @@ const reorderSchedules = async (scheduleIds: number[]) => { } const existingSchedules = await db.query.backupSchedulesTable.findMany({ - where: eq(backupSchedulesTable.organizationId, organizationId), + where: { organizationId }, columns: { id: true }, }); const existingIds = new Set(existingSchedules.map((s) => s.id)); diff --git a/app/server/modules/lifecycle/migrations.ts b/app/server/modules/lifecycle/migrations.ts index a4a49a03..69147d49 100644 --- a/app/server/modules/lifecycle/migrations.ts +++ b/app/server/modules/lifecycle/migrations.ts @@ -3,7 +3,6 @@ import { v00001 } from "./migrations/00001-retag-snapshots"; import { v00002 } from "./migrations/00002-isolate-restic-passwords"; import { v00003 } from "./migrations/00003-assign-organization"; import { sql } from "drizzle-orm"; -import { eq } from "drizzle-orm"; import { appMetadataTable, usersTable } from "../../db/schema"; import { db } from "../../db/db"; @@ -26,9 +25,7 @@ const recordMigrationCheckpoint = async (version: string): Promise => { const hasMigrationCheckpoint = async (id: string): Promise => { const key = `${MIGRATION_KEY_PREFIX}${id}`; - const result = await db.query.appMetadataTable.findFirst({ - where: eq(appMetadataTable.key, key), - }); + const result = await db.query.appMetadataTable.findFirst({ where: { key } }); return result !== undefined; }; diff --git a/app/server/modules/lifecycle/migrations/00001-retag-snapshots.ts b/app/server/modules/lifecycle/migrations/00001-retag-snapshots.ts index 0eb4f137..3736c141 100644 --- a/app/server/modules/lifecycle/migrations/00001-retag-snapshots.ts +++ b/app/server/modules/lifecycle/migrations/00001-retag-snapshots.ts @@ -1,6 +1,6 @@ import { eq } from "drizzle-orm"; import { db } from "../../../db/db"; -import { backupScheduleMirrorsTable, repositoriesTable, type Repository } from "../../../db/schema"; +import { backupScheduleMirrorsTable, type Repository } from "../../../db/schema"; import { logger } from "../../../utils/logger"; import { toMessage } from "~/server/utils/errors"; import { exec } from "~/server/utils/spawn"; @@ -42,7 +42,7 @@ const execute = async () => { const newTag = schedule.shortId; const repository = await db.query.repositoriesTable.findFirst({ - where: eq(repositoriesTable.id, schedule.repositoryId), + where: { id: schedule.repositoryId }, }); if (!repository) { @@ -63,7 +63,7 @@ const execute = async () => { for (const mirror of mirrors) { const mirrorRepo = await db.query.repositoriesTable.findFirst({ - where: eq(repositoriesTable.id, mirror.repositoryId), + where: { id: mirror.repositoryId }, }); if (!mirrorRepo) { diff --git a/app/server/modules/lifecycle/migrations/00003-assign-organization.ts b/app/server/modules/lifecycle/migrations/00003-assign-organization.ts index e3ac9d9f..d35af947 100644 --- a/app/server/modules/lifecycle/migrations/00003-assign-organization.ts +++ b/app/server/modules/lifecycle/migrations/00003-assign-organization.ts @@ -1,6 +1,5 @@ -import { eq } from "drizzle-orm"; import { db } from "../../../db/db"; -import { member, usersTable } from "../../../db/schema"; +import { member } from "../../../db/schema"; import { logger } from "../../../utils/logger"; import { toMessage } from "~/server/utils/errors"; @@ -8,7 +7,9 @@ const execute = async () => { const errors: Array<{ name: string; error: string }> = []; try { - const allUsers = await db.query.usersTable.findMany({ where: eq(usersTable.role, "admin") }); + const allUsers = await db.query.usersTable.findMany({ + where: { role: "admin" }, + }); const allOrganizations = await db.query.organization.findMany({}); if (allUsers.length === 0) { @@ -35,7 +36,7 @@ const execute = async () => { const org = allOrganizations[0]; const existingMembers = await db.query.member.findMany({ - where: (memberTable, { eq }) => eq(memberTable.userId, user.id), + where: { userId: user.id }, }); if (existingMembers.length > 0) { diff --git a/app/server/modules/lifecycle/shutdown.ts b/app/server/modules/lifecycle/shutdown.ts index 13a38bfc..5d72e1a3 100644 --- a/app/server/modules/lifecycle/shutdown.ts +++ b/app/server/modules/lifecycle/shutdown.ts @@ -1,7 +1,5 @@ import { Scheduler } from "../../core/scheduler"; -import { eq, or } from "drizzle-orm"; import { db } from "../../db/db"; -import { volumesTable } from "../../db/schema"; import { logger } from "../../utils/logger"; import { createVolumeBackend } from "../backends/backend"; @@ -9,7 +7,7 @@ export const shutdown = async () => { await Scheduler.stop(); const volumes = await db.query.volumesTable.findMany({ - where: or(eq(volumesTable.status, "mounted")), + where: { status: "mounted" }, }); for (const volume of volumes) { diff --git a/app/server/modules/lifecycle/startup.ts b/app/server/modules/lifecycle/startup.ts index 39a36731..c272cac1 100644 --- a/app/server/modules/lifecycle/startup.ts +++ b/app/server/modules/lifecycle/startup.ts @@ -1,7 +1,7 @@ import { Scheduler } from "../../core/scheduler"; -import { and, eq, or } from "drizzle-orm"; +import { eq } from "drizzle-orm"; import { db } from "../../db/db"; -import { backupSchedulesTable, volumesTable } from "../../db/schema"; +import { backupSchedulesTable } from "../../db/schema"; import { logger } from "../../utils/logger"; import { volumeService } from "../volumes/volume.service"; import { CleanupDanglingMountsJob } from "../../jobs/cleanup-dangling"; @@ -62,10 +62,14 @@ export const startup = async () => { await ensureLatestConfigurationSchema(); const volumes = await db.query.volumesTable.findMany({ - where: or( - eq(volumesTable.status, "mounted"), - and(eq(volumesTable.autoRemount, true), eq(volumesTable.status, "error")), - ), + where: { + OR: [ + { status: "mounted" }, + { + AND: [{ autoRemount: true }, { status: "error" }], + }, + ], + }, }); for (const volume of volumes) { diff --git a/app/server/modules/notifications/notifications.service.ts b/app/server/modules/notifications/notifications.service.ts index f3af6b64..09d7ad60 100644 --- a/app/server/modules/notifications/notifications.service.ts +++ b/app/server/modules/notifications/notifications.service.ts @@ -1,10 +1,9 @@ -import { eq, and, inArray } from "drizzle-orm"; +import { eq, and } from "drizzle-orm"; import { BadRequestError, ConflictError, InternalServerError, NotFoundError } from "http-errors-enhanced"; import { db } from "../../db/db"; import { notificationDestinationsTable, backupScheduleNotificationsTable, - backupSchedulesTable, type NotificationDestination, } from "../../db/schema"; import { cryptoUtils } from "../../utils/crypto"; @@ -19,8 +18,8 @@ import { getOrganizationId } from "~/server/core/request-context"; const listDestinations = async () => { const organizationId = getOrganizationId(); const destinations = await db.query.notificationDestinationsTable.findMany({ - where: eq(notificationDestinationsTable.organizationId, organizationId), - orderBy: (destinations, { asc }) => [asc(destinations.name)], + where: { organizationId }, + orderBy: { name: "asc" }, }); return destinations; }; @@ -28,10 +27,7 @@ const listDestinations = async () => { const getDestination = async (id: number) => { const organizationId = getOrganizationId(); const destination = await db.query.notificationDestinationsTable.findFirst({ - where: and( - eq(notificationDestinationsTable.id, id), - eq(notificationDestinationsTable.organizationId, organizationId), - ), + where: { AND: [{ id }, { organizationId }] }, }); if (!destination) { @@ -256,7 +252,7 @@ const testDestination = async (id: number) => { const getScheduleNotifications = async (scheduleId: number) => { const organizationId = getOrganizationId(); const schedule = await db.query.backupSchedulesTable.findFirst({ - where: and(eq(backupSchedulesTable.id, scheduleId), eq(backupSchedulesTable.organizationId, organizationId)), + where: { AND: [{ id: scheduleId }, { organizationId }] }, }); if (!schedule) { @@ -264,7 +260,7 @@ const getScheduleNotifications = async (scheduleId: number) => { } const assignments = await db.query.backupScheduleNotificationsTable.findMany({ - where: eq(backupScheduleNotificationsTable.scheduleId, scheduleId), + where: { scheduleId }, with: { destination: true, }, @@ -285,7 +281,7 @@ const updateScheduleNotifications = async ( ) => { const organizationId = getOrganizationId(); const schedule = await db.query.backupSchedulesTable.findFirst({ - where: and(eq(backupSchedulesTable.id, scheduleId), eq(backupSchedulesTable.organizationId, organizationId)), + where: { AND: [{ id: scheduleId }, { organizationId }] }, }); if (!schedule) { @@ -295,10 +291,9 @@ const updateScheduleNotifications = async ( const destinationIds = [...new Set(assignments.map((a) => a.destinationId))]; if (destinationIds.length > 0) { const destinations = await db.query.notificationDestinationsTable.findMany({ - where: and( - inArray(notificationDestinationsTable.id, destinationIds), - eq(notificationDestinationsTable.organizationId, organizationId), - ), + where: { + AND: [{ id: { in: destinationIds } }, { organizationId }], + }, }); if (destinations.length !== destinationIds.length) { @@ -338,7 +333,7 @@ const sendBackupNotification = async ( const organizationId = getOrganizationId(); const assignments = await db.query.backupScheduleNotificationsTable.findMany({ - where: eq(backupScheduleNotificationsTable.scheduleId, scheduleId), + where: { scheduleId }, with: { destination: true, }, diff --git a/app/server/modules/repositories/repositories.service.ts b/app/server/modules/repositories/repositories.service.ts index c513f75a..c94b3f4c 100644 --- a/app/server/modules/repositories/repositories.service.ts +++ b/app/server/modules/repositories/repositories.service.ts @@ -1,5 +1,5 @@ import crypto from "node:crypto"; -import { and, eq, or } from "drizzle-orm"; +import { and, eq } from "drizzle-orm"; import { ConflictError, InternalServerError, NotFoundError } from "http-errors-enhanced"; import { db } from "../../db/db"; import { repositoriesTable } from "../../db/schema"; @@ -26,18 +26,15 @@ const runningDoctors = new Map(); const findRepository = async (idOrShortId: string) => { const organizationId = getOrganizationId(); return await db.query.repositoriesTable.findFirst({ - where: and( - or(eq(repositoriesTable.id, idOrShortId), eq(repositoriesTable.shortId, idOrShortId)), - eq(repositoriesTable.organizationId, organizationId), - ), + where: { + AND: [{ OR: [{ id: idOrShortId }, { shortId: idOrShortId }] }, { organizationId }], + }, }); }; const listRepositories = async () => { const organizationId = getOrganizationId(); - const repositories = await db.query.repositoriesTable.findMany({ - where: eq(repositoriesTable.organizationId, organizationId), - }); + const repositories = await db.query.repositoriesTable.findMany({ where: { organizationId } }); return repositories; }; diff --git a/app/server/modules/system/system.controller.ts b/app/server/modules/system/system.controller.ts index d83a4d20..dad1252a 100644 --- a/app/server/modules/system/system.controller.ts +++ b/app/server/modules/system/system.controller.ts @@ -15,7 +15,7 @@ import { import { systemService } from "./system.service"; import { requireAuth, requireOrgAdmin } from "../auth/auth.middleware"; import { db } from "../../db/db"; -import { organization, usersTable } from "../../db/schema"; +import { usersTable } from "../../db/schema"; import { eq } from "drizzle-orm"; import { verifyUserPassword } from "../auth/helpers"; import { cryptoUtils } from "../../utils/crypto"; @@ -78,9 +78,7 @@ export const systemController = new Hono() } try { - const org = await db.query.organization.findFirst({ - where: eq(organization.id, organizationId), - }); + const org = await db.query.organization.findFirst({ where: { id: organizationId } }); if (!org?.metadata?.resticPassword) { return c.json({ message: "Organization Restic password not found" }, 404); diff --git a/app/server/modules/system/system.service.ts b/app/server/modules/system/system.service.ts index 2549024e..2f4fad67 100644 --- a/app/server/modules/system/system.service.ts +++ b/app/server/modules/system/system.service.ts @@ -6,7 +6,6 @@ import { cache } from "../../utils/cache"; import { logger } from "~/server/utils/logger"; import { db } from "../../db/db"; import { appMetadataTable } from "../../db/schema"; -import { eq } from "drizzle-orm"; import { REGISTRATION_ENABLED_KEY } from "~/client/lib/constants"; const CACHE_TTL = 60 * 60; @@ -91,7 +90,7 @@ const getUpdates = async (): Promise => { const isRegistrationEnabled = async () => { const result = await db.query.appMetadataTable.findFirst({ - where: eq(appMetadataTable.key, REGISTRATION_ENABLED_KEY), + where: { key: REGISTRATION_ENABLED_KEY }, }); return result?.value === "true"; diff --git a/app/server/modules/volumes/volume.service.ts b/app/server/modules/volumes/volume.service.ts index 401966d6..a79d39db 100644 --- a/app/server/modules/volumes/volume.service.ts +++ b/app/server/modules/volumes/volume.service.ts @@ -46,7 +46,7 @@ async function encryptSensitiveFields(config: BackendConfig): Promise { const organizationId = getOrganizationId(); const volumes = await db.query.volumesTable.findMany({ - where: eq(volumesTable.organizationId, organizationId), + where: { organizationId: organizationId }, }); return volumes; @@ -56,10 +56,12 @@ const findVolume = async (idOrShortId: string | number) => { const organizationId = getOrganizationId(); const isNumeric = typeof idOrShortId === "number" || /^\d+$/.test(String(idOrShortId)); return await db.query.volumesTable.findFirst({ - where: and( - isNumeric ? eq(volumesTable.id, Number(idOrShortId)) : eq(volumesTable.shortId, idOrShortId), - eq(volumesTable.organizationId, organizationId), - ), + where: { + AND: [ + isNumeric ? { id: Number(idOrShortId) } : { shortId: String(idOrShortId) }, + { organizationId: organizationId }, + ], + }, }); }; diff --git a/app/server/utils/restic.ts b/app/server/utils/restic.ts index 4f5b4874..0d91d2ae 100644 --- a/app/server/utils/restic.ts +++ b/app/server/utils/restic.ts @@ -4,7 +4,6 @@ import path from "node:path"; import os from "node:os"; import { throttle } from "es-toolkit"; import { type } from "arktype"; -import { eq } from "drizzle-orm"; import { REPOSITORY_BASE, RESTIC_PASS_FILE, DEFAULT_EXCLUDES, RESTIC_CACHE_DIR } from "../core/constants"; import { config as appConfig } from "../core/config"; import { logger } from "./logger"; @@ -14,7 +13,6 @@ import { safeSpawn, exec } from "./spawn"; import type { CompressionMode, RepositoryConfig, OverwriteMode, BandwidthLimit } from "~/schemas/restic"; import { ResticError } from "./errors"; import { db } from "../db/db"; -import { organization } from "../db/schema"; const backupOutputSchema = type({ message_type: "'summary'", @@ -110,9 +108,7 @@ export const buildEnv = async (config: RepositoryConfig, organizationId: string) await fs.writeFile(passwordFilePath, decryptedPassword, { mode: 0o600 }); env.RESTIC_PASSWORD_FILE = passwordFilePath; } else { - const org = await db.query.organization.findFirst({ - where: eq(organization.id, organizationId), - }); + const org = await db.query.organization.findFirst({ where: { id: organizationId } }); if (!org) { throw new Error(`Organization ${organizationId} not found`); diff --git a/app/test/helpers/organization.ts b/app/test/helpers/organization.ts index 0a356c18..f2249268 100644 --- a/app/test/helpers/organization.ts +++ b/app/test/helpers/organization.ts @@ -19,7 +19,7 @@ export const createTestOrganization = async (overrides: Partial eq(o.id, org.id ?? TEST_ORG_ID), + where: { id: org.id }, }); if (existing) { diff --git a/e2e/helpers/db.ts b/e2e/helpers/db.ts index bec09ce1..f265a887 100644 --- a/e2e/helpers/db.ts +++ b/e2e/helpers/db.ts @@ -2,11 +2,11 @@ import { createClient } from "@libsql/client"; import { drizzle } from "drizzle-orm/libsql"; import path from "node:path"; import { DATABASE_URL } from "~/server/core/constants"; -import * as schema from "~/server/db/schema"; +import { relations } from "~/server/db/relations"; const sqlite = createClient({ url: `file:${path.join(process.cwd(), "playwright", DATABASE_URL)}` }); -export const db = drizzle({ client: sqlite, schema: schema }); +export const db = drizzle({ client: sqlite, relations: relations }); export const resetDatabase = async () => { const cursor = await sqlite.execute("SELECT name FROM sqlite_master WHERE type='table'");