From ae592481af67289c63e7663fff6d7f4d7d65df87 Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Fri, 17 Oct 2025 21:03:13 +0200 Subject: [PATCH] feat: base restic repo schemas --- apps/server/src/db/schema.ts | 21 ++++++++++++- packages/schemas/src/index.ts | 58 +++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/apps/server/src/db/schema.ts b/apps/server/src/db/schema.ts index 51b70c1..fe79129 100644 --- a/apps/server/src/db/schema.ts +++ b/apps/server/src/db/schema.ts @@ -1,4 +1,12 @@ -import type { BackendStatus, BackendType, volumeConfigSchema } from "@ironmount/schemas"; +import type { + BackendStatus, + BackendType, + CompressionMode, + RepositoryBackend, + RepositoryStatus, + repositoryConfigSchema, + volumeConfigSchema, +} from "@ironmount/schemas"; import { sql } from "drizzle-orm"; import { int, sqliteTable, text } from "drizzle-orm/sqlite-core"; @@ -41,4 +49,15 @@ export type Session = typeof sessionsTable.$inferSelect; export const repositoriesTable = sqliteTable("repositories_table", { id: text().primaryKey(), + name: text().notNull().unique(), + backend: text().$type().notNull(), + config: text("config", { mode: "json" }).$type().notNull(), + compressionMode: text("compression_mode").$type().default("auto"), + status: text().$type().default("unknown"), + lastChecked: int("last_checked", { mode: "timestamp" }), + lastError: text("last_error"), + createdAt: int("created_at", { mode: "timestamp" }).notNull().default(sql`(unixepoch())`), + updatedAt: int("updated_at", { mode: "timestamp" }).notNull().default(sql`(unixepoch())`), }); + +export type Repository = typeof repositoriesTable.$inferSelect; diff --git a/packages/schemas/src/index.ts b/packages/schemas/src/index.ts index 28d8604..3d647c5 100644 --- a/packages/schemas/src/index.ts +++ b/packages/schemas/src/index.ts @@ -53,3 +53,61 @@ export const BACKEND_STATUS = { } as const; export type BackendStatus = keyof typeof BACKEND_STATUS; + +export const REPOSITORY_BACKENDS = { + local: "local", + sftp: "sftp", + s3: "s3", +} as const; + +export type RepositoryBackend = keyof typeof REPOSITORY_BACKENDS; + +export const localRepositoryConfigSchema = type({ + backend: "'local'", + path: "string", + password: "string", +}); + +export const sftpRepositoryConfigSchema = type({ + backend: "'sftp'", + host: "string", + user: "string", + port: type("string.integer").or(type("number")).to("1 <= number <= 65535").default(22), + path: "string", + sftpPassword: "string?", + sftpPrivateKey: "string?", + sftpCommand: "string?", + sftpArgs: "string?", +}); + +export const s3RepositoryConfigSchema = type({ + backend: "'s3'", + endpoint: "string", + bucket: "string", + accessKeyId: "string", + secretAccessKey: "string", +}); + +export const repositoryConfigSchema = localRepositoryConfigSchema + .or(sftpRepositoryConfigSchema) + .or(s3RepositoryConfigSchema); + +export type RepositoryConfig = typeof repositoryConfigSchema.infer; + +export const COMPRESSION_MODES = { + off: "off", + auto: "auto", + fastest: "fastest", + better: "better", + max: "max", +} as const; + +export type CompressionMode = keyof typeof COMPRESSION_MODES; + +export const REPOSITORY_STATUS = { + healthy: "healthy", + error: "error", + unknown: "unknown", +} as const; + +export type RepositoryStatus = keyof typeof REPOSITORY_STATUS;