refactor: frontend components consolidation

This commit is contained in:
Nicolas Meienberger
2025-11-01 17:49:40 +01:00
parent 18115b374c
commit 3befa127d7
30 changed files with 483 additions and 449 deletions

View File

@@ -1,4 +1,5 @@
export const OPERATION_TIMEOUT = 5000;
export const VOLUME_MOUNT_BASE = "/volumes";
export const VOLUME_MOUNT_BASE = "/data/volumes";
export const REPOSITORY_BASE = "/data/repositories";
export const DATABASE_URL = "/data/ironmount.db";
export const RESTIC_PASS_FILE = "/data/secrets/restic.pass";

View File

@@ -7,6 +7,7 @@ import { DATABASE_URL } from "../core/constants";
import * as schema from "./schema";
const sqlite = new Database(DATABASE_URL);
sqlite.run("PRAGMA foreign_keys = ON;");
export const db = drizzle({ client: sqlite, schema });

View File

@@ -30,9 +30,12 @@ const backupScheduleSchema = type({
nextBackupAt: "number | null",
createdAt: "number",
updatedAt: "number",
});
export type BackupScheduleDto = typeof backupScheduleSchema.infer;
}).and(
type({
volume: volumeSchema,
repository: repositorySchema,
}),
);
/**
* List all backup schedules
@@ -60,12 +63,7 @@ export const listBackupSchedulesDto = describeRoute({
/**
* Get a single backup schedule
*/
export const getBackupScheduleResponse = backupScheduleSchema.and(
type({
volume: volumeSchema,
repository: repositorySchema,
}),
);
export const getBackupScheduleResponse = backupScheduleSchema;
export type GetBackupScheduleDto = typeof getBackupScheduleResponse.infer;
@@ -121,7 +119,7 @@ export const createBackupScheduleBody = type({
export type CreateBackupScheduleBody = typeof createBackupScheduleBody.infer;
export const createBackupScheduleResponse = backupScheduleSchema;
export const createBackupScheduleResponse = backupScheduleSchema.omit("volume", "repository");
export type CreateBackupScheduleDto = typeof createBackupScheduleResponse.infer;
@@ -156,7 +154,7 @@ export const updateBackupScheduleBody = type({
export type UpdateBackupScheduleBody = typeof updateBackupScheduleBody.infer;
export const updateBackupScheduleResponse = backupScheduleSchema;
export const updateBackupScheduleResponse = backupScheduleSchema.omit("volume", "repository");
export type UpdateBackupScheduleDto = typeof updateBackupScheduleResponse.infer;
@@ -192,7 +190,7 @@ export const upsertBackupScheduleBody = type({
export type UpsertBackupScheduleBody = typeof upsertBackupScheduleBody.infer;
export const upsertBackupScheduleResponse = backupScheduleSchema;
export const upsertBackupScheduleResponse = backupScheduleSchema.omit("volume", "repository");
export type UpsertBackupScheduleDto = typeof upsertBackupScheduleResponse.infer;

View File

@@ -27,7 +27,12 @@ const calculateNextRun = (cronExpression: string): number => {
};
const listSchedules = async () => {
const schedules = await db.query.backupSchedulesTable.findMany({});
const schedules = await db.query.backupSchedulesTable.findMany({
with: {
volume: true,
repository: true,
},
});
return schedules;
};
@@ -259,6 +264,7 @@ const getSchedulesToExecute = async () => {
const getScheduleForVolume = async (volumeId: number) => {
const schedule = await db.query.backupSchedulesTable.findFirst({
where: eq(backupSchedulesTable.volumeId, volumeId),
with: { volume: true, repository: true },
});
return schedule ?? null;

View File

@@ -29,14 +29,7 @@ export const volumeController = new Hono()
.get("/", listVolumesDto, async (c) => {
const volumes = await volumeService.listVolumes();
const response = {
volumes: volumes.map((volume) => ({
path: getVolumePath(volume.name),
...volume,
})),
};
return c.json<ListVolumesDto>(response, 200);
return c.json<ListVolumesDto>(volumes, 200);
})
.post("/", createVolumeDto, validator("json", createVolumeBody), async (c) => {
const body = c.req.valid("json");

View File

@@ -5,7 +5,6 @@ import { describeRoute, resolver } from "hono-openapi";
export const volumeSchema = type({
id: "number",
name: "string",
path: "string",
type: type.valueOf(BACKEND_TYPES),
status: type.valueOf(BACKEND_STATUS),
lastError: "string | null",
@@ -21,9 +20,7 @@ export type VolumeDto = typeof volumeSchema.infer;
/**
* List all volumes
*/
export const listVolumesResponse = type({
volumes: volumeSchema.array(),
});
export const listVolumesResponse = volumeSchema.array();
export type ListVolumesDto = typeof listVolumesResponse.infer;
export const listVolumesDto = describeRoute({

View File

@@ -4,7 +4,7 @@ import path from "node:path";
import type { RepositoryConfig } from "@ironmount/schemas/restic";
import { type } from "arktype";
import { $ } from "bun";
import { RESTIC_PASS_FILE } from "../core/constants";
import { REPOSITORY_BASE, RESTIC_PASS_FILE } from "../core/constants";
import { logger } from "./logger";
import { cryptoUtils } from "./crypto";
import type { RetentionPolicy } from "../modules/backups/backups.dto";
@@ -69,7 +69,7 @@ const ensurePassfile = async () => {
const buildRepoUrl = (config: RepositoryConfig): string => {
switch (config.backend) {
case "local":
return `/repositories/${config.name}`;
return `${REPOSITORY_BASE}/${config.name}`;
case "s3":
return `s3:${config.endpoint}/${config.bucket}`;
default: {