mirror of
https://github.com/nicotsx/ironmount.git
synced 2025-12-10 12:10:51 +01:00
refactor: use correct namings
This commit is contained in:
@@ -42,14 +42,14 @@ export function generateBreadcrumbs(pathname: string, params: Record<string, str
|
||||
return breadcrumbs;
|
||||
}
|
||||
|
||||
if (pathname.startsWith("/backup-jobs")) {
|
||||
if (pathname.startsWith("/backups")) {
|
||||
breadcrumbs.push({
|
||||
label: "Backup jobs",
|
||||
href: "/backup-jobs",
|
||||
isCurrentPage: pathname === "/backup-jobs",
|
||||
label: "Backups",
|
||||
href: "/backups",
|
||||
isCurrentPage: pathname === "/backups",
|
||||
});
|
||||
|
||||
if (pathname.startsWith("/backup-jobs/") && params.scheduleId) {
|
||||
if (pathname.startsWith("/backups/") && params.scheduleId) {
|
||||
breadcrumbs.push({
|
||||
label: `Schedule #${params.scheduleId}`,
|
||||
isCurrentPage: true,
|
||||
|
||||
@@ -4,8 +4,7 @@ import { type } from "arktype";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { listRepositoriesOptions } from "~/api-client/@tanstack/react-query.gen";
|
||||
import { RepositoryIcon } from "~/components/repository-icon";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "~/components/ui/card";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "~/components/ui/card";
|
||||
import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "~/components/ui/form";
|
||||
import { Input } from "~/components/ui/input";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/components/ui/select";
|
||||
@@ -46,6 +45,7 @@ type Props = {
|
||||
onSubmit: (data: BackupScheduleFormValues) => void;
|
||||
loading?: boolean;
|
||||
summaryContent?: React.ReactNode;
|
||||
formId: string;
|
||||
};
|
||||
|
||||
const backupScheduleToFormValues = (schedule?: BackupSchedule): BackupScheduleFormValues | undefined => {
|
||||
@@ -73,7 +73,7 @@ const backupScheduleToFormValues = (schedule?: BackupSchedule): BackupScheduleFo
|
||||
};
|
||||
};
|
||||
|
||||
export const CreateScheduleForm = ({ initialValues, onSubmit, volume, loading }: Props) => {
|
||||
export const CreateScheduleForm = ({ initialValues, formId, onSubmit, volume }: Props) => {
|
||||
const form = useForm<BackupScheduleFormValues>({
|
||||
resolver: arktypeResolver(cleanSchema as unknown as typeof formSchema),
|
||||
defaultValues: backupScheduleToFormValues(initialValues),
|
||||
@@ -91,6 +91,7 @@ export const CreateScheduleForm = ({ initialValues, onSubmit, volume, loading }:
|
||||
<form
|
||||
onSubmit={form.handleSubmit(onSubmit)}
|
||||
className="grid gap-4 xl:grid-cols-[minmax(0,_2.3fr)_minmax(320px,_1fr)]"
|
||||
id={formId}
|
||||
>
|
||||
<div className="grid gap-4">
|
||||
<Card>
|
||||
@@ -335,11 +336,6 @@ export const CreateScheduleForm = ({ initialValues, onSubmit, volume, loading }:
|
||||
)}
|
||||
/>
|
||||
</CardContent>
|
||||
<CardFooter className="border-t pt-6">
|
||||
<Button type="submit" className="ml-auto" variant="default" loading={loading}>
|
||||
{initialValues ? "Update schedule" : "Create schedule"}
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="h-full">
|
||||
|
||||
@@ -58,7 +58,9 @@ export const ScheduleSummary = (props: Props) => {
|
||||
<CardHeader className="flex flex-row items-center justify-between gap-4">
|
||||
<div>
|
||||
<CardTitle>Backup schedule</CardTitle>
|
||||
<CardDescription>Automated backup configuration for {volume.name}</CardDescription>
|
||||
<CardDescription>
|
||||
Automated backup configuration for volume <strong className="text-strong-accent">{volume.name}</strong>
|
||||
</CardDescription>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<OnOff isOn={schedule.enabled} toggle={handleToggleEnabled} enabledLabel="Enabled" disabledLabel="Paused" />
|
||||
@@ -79,7 +81,7 @@ export const ScheduleSummary = (props: Props) => {
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs uppercase text-muted-foreground">Repository</p>
|
||||
<p className="font-medium">{summary.repositoryLabel}</p>
|
||||
<p className="font-medium">{repository.name}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs uppercase text-muted-foreground">Last backup</p>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState } from "react";
|
||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { useId, useState } from "react";
|
||||
import { useQuery, useMutation } from "@tanstack/react-query";
|
||||
import { Link, useParams } from "react-router";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "~/components/ui/button";
|
||||
@@ -15,13 +15,13 @@ import { CreateScheduleForm, type BackupScheduleFormValues } from "../components
|
||||
import { ScheduleSummary } from "../components/schedule-summary";
|
||||
|
||||
export default function ScheduleDetailsPage() {
|
||||
const { scheduleId } = useParams<{ scheduleId: string }>();
|
||||
const queryClient = useQueryClient();
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const [isEditMode, setIsEditMode] = useState(false);
|
||||
const formId = useId();
|
||||
|
||||
const { data: schedule, isLoading: loadingSchedule } = useQuery({
|
||||
...getBackupScheduleOptions({
|
||||
path: { scheduleId: scheduleId || "" },
|
||||
path: { scheduleId: id || "" },
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -31,8 +31,6 @@ export default function ScheduleDetailsPage() {
|
||||
...upsertBackupScheduleMutation(),
|
||||
onSuccess: () => {
|
||||
toast.success("Backup schedule saved successfully");
|
||||
queryClient.invalidateQueries({ queryKey: ["listBackupSchedules"] });
|
||||
queryClient.invalidateQueries({ queryKey: ["getBackupSchedule", scheduleId] });
|
||||
setIsEditMode(false);
|
||||
},
|
||||
onError: (error) => {
|
||||
@@ -46,7 +44,6 @@ export default function ScheduleDetailsPage() {
|
||||
...runBackupNowMutation(),
|
||||
onSuccess: () => {
|
||||
toast.success("Backup started successfully");
|
||||
queryClient.invalidateQueries({ queryKey: ["getBackupSchedule", scheduleId] });
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.error("Failed to start backup", {
|
||||
@@ -117,42 +114,41 @@ export default function ScheduleDetailsPage() {
|
||||
|
||||
if (!schedule) {
|
||||
return (
|
||||
<div className="container mx-auto p-4 sm:p-8">
|
||||
<Card>
|
||||
<CardContent className="py-12 text-center">
|
||||
<p className="text-muted-foreground">Schedule not found</p>
|
||||
<Button asChild className="mt-4">
|
||||
<Link to="/backup-jobs">Back to Backup Jobs</Link>
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
<Card>
|
||||
<CardContent className="py-12 text-center">
|
||||
<p className="text-muted-foreground">Not found</p>
|
||||
<Button className="mt-4">
|
||||
<Link to="/backups">Back to backups</Link>
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isEditMode) {
|
||||
return (
|
||||
<div className="container mx-auto p-4 sm:p-8">
|
||||
<ScheduleSummary
|
||||
handleToggleEnabled={handleToggleEnabled}
|
||||
handleRunBackupNow={handleRunBackupNow}
|
||||
repository={schedule.repository}
|
||||
setIsEditMode={setIsEditMode}
|
||||
schedule={schedule}
|
||||
volume={schedule.volume}
|
||||
/>
|
||||
</div>
|
||||
<ScheduleSummary
|
||||
handleToggleEnabled={handleToggleEnabled}
|
||||
handleRunBackupNow={handleRunBackupNow}
|
||||
repository={schedule.repository}
|
||||
setIsEditMode={setIsEditMode}
|
||||
schedule={schedule}
|
||||
volume={schedule.volume}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container mx-auto p-4 sm:p-8 space-y-4">
|
||||
<div className="flex justify-end">
|
||||
<div>
|
||||
<CreateScheduleForm volume={schedule.volume} initialValues={schedule} onSubmit={handleSubmit} formId={formId} />
|
||||
<div className="flex justify-end mt-4 gap-2">
|
||||
<Button type="submit" className="ml-auto" variant="primary" form={formId} loading={upsertSchedule.isPending}>
|
||||
Update schedule
|
||||
</Button>
|
||||
<Button variant="outline" onClick={() => setIsEditMode(false)}>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
<CreateScheduleForm volume={schedule.volume} initialValues={schedule} onSubmit={handleSubmit} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -63,13 +63,15 @@ export default function Backups({ loaderData }: Route.ComponentProps) {
|
||||
<div className="container mx-auto space-y-6">
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{schedules.map((schedule) => (
|
||||
<Link key={schedule.id} to={`/backup-jobs/${schedule.id}`}>
|
||||
<Link key={schedule.id} to={`/backups/${schedule.id}`}>
|
||||
<Card key={schedule.id} className="flex flex-col">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<div className="flex items-center gap-2 flex-1 min-w-0">
|
||||
<HardDrive className="h-5 w-5 text-muted-foreground flex-shrink-0" />
|
||||
<CardTitle className="text-lg truncate">Volume #{schedule.volumeId}</CardTitle>
|
||||
<CardTitle className="text-lg truncate">
|
||||
Volume <span className="text-strong-accent">{schedule.volume.name}</span>
|
||||
</CardTitle>
|
||||
</div>
|
||||
<Badge variant={schedule.enabled ? "default" : "secondary"} className="flex-shrink-0">
|
||||
{schedule.enabled ? "Active" : "Paused"}
|
||||
@@ -77,7 +79,7 @@ export default function Backups({ loaderData }: Route.ComponentProps) {
|
||||
</div>
|
||||
<CardDescription className="flex items-center gap-2 mt-2">
|
||||
<Database className="h-4 w-4" />
|
||||
<span className="truncate">{schedule.repositoryId}</span>
|
||||
<span className="truncate">{schedule.repository.name}</span>
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 space-y-4">
|
||||
@@ -102,7 +104,7 @@ export default function Backups({ loaderData }: Route.ComponentProps) {
|
||||
<div className="flex items-center justify-between text-sm">
|
||||
<span className="text-muted-foreground">Status</span>
|
||||
<Badge
|
||||
variant={schedule.lastBackupStatus === "success" ? "default" : "destructive"}
|
||||
variant={schedule.lastBackupStatus === "success" ? "primary" : "destructive"}
|
||||
className="text-xs"
|
||||
>
|
||||
{schedule.lastBackupStatus}
|
||||
|
||||
1
apps/server/drizzle/0009_little_adam_warlock.sql
Normal file
1
apps/server/drizzle/0009_little_adam_warlock.sql
Normal file
@@ -0,0 +1 @@
|
||||
DROP INDEX `backup_schedules_table_volume_id_unique`;
|
||||
451
apps/server/drizzle/meta/0009_snapshot.json
Normal file
451
apps/server/drizzle/meta/0009_snapshot.json
Normal file
@@ -0,0 +1,451 @@
|
||||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "6a326ac0-cb3a-4c63-8800-bc86d18e0c1d",
|
||||
"prevId": "6e35f329-5431-47fd-8862-8fb06b0afe4b",
|
||||
"tables": {
|
||||
"backup_schedules_table": {
|
||||
"name": "backup_schedules_table",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"volume_id": {
|
||||
"name": "volume_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"repository_id": {
|
||||
"name": "repository_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"enabled": {
|
||||
"name": "enabled",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": true
|
||||
},
|
||||
"cron_expression": {
|
||||
"name": "cron_expression",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"retention_policy": {
|
||||
"name": "retention_policy",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"exclude_patterns": {
|
||||
"name": "exclude_patterns",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": "'[]'"
|
||||
},
|
||||
"include_patterns": {
|
||||
"name": "include_patterns",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": "'[]'"
|
||||
},
|
||||
"last_backup_at": {
|
||||
"name": "last_backup_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"last_backup_status": {
|
||||
"name": "last_backup_status",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"last_backup_error": {
|
||||
"name": "last_backup_error",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"next_backup_at": {
|
||||
"name": "next_backup_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"backup_schedules_table_volume_id_volumes_table_id_fk": {
|
||||
"name": "backup_schedules_table_volume_id_volumes_table_id_fk",
|
||||
"tableFrom": "backup_schedules_table",
|
||||
"tableTo": "volumes_table",
|
||||
"columnsFrom": [
|
||||
"volume_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"backup_schedules_table_repository_id_repositories_table_id_fk": {
|
||||
"name": "backup_schedules_table_repository_id_repositories_table_id_fk",
|
||||
"tableFrom": "backup_schedules_table",
|
||||
"tableTo": "repositories_table",
|
||||
"columnsFrom": [
|
||||
"repository_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"repositories_table": {
|
||||
"name": "repositories_table",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"config": {
|
||||
"name": "config",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"compression_mode": {
|
||||
"name": "compression_mode",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": "'auto'"
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": "'unknown'"
|
||||
},
|
||||
"last_checked": {
|
||||
"name": "last_checked",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"last_error": {
|
||||
"name": "last_error",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"repositories_table_name_unique": {
|
||||
"name": "repositories_table_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"sessions_table": {
|
||||
"name": "sessions_table",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_table_user_id_users_table_id_fk": {
|
||||
"name": "sessions_table_user_id_users_table_id_fk",
|
||||
"tableFrom": "sessions_table",
|
||||
"tableTo": "users_table",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"users_table": {
|
||||
"name": "users_table",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"username": {
|
||||
"name": "username",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"users_table_username_unique": {
|
||||
"name": "users_table_username_unique",
|
||||
"columns": [
|
||||
"username"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"volumes_table": {
|
||||
"name": "volumes_table",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "'unmounted'"
|
||||
},
|
||||
"last_error": {
|
||||
"name": "last_error",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"last_health_check": {
|
||||
"name": "last_health_check",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
},
|
||||
"config": {
|
||||
"name": "config",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"auto_remount": {
|
||||
"name": "auto_remount",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"volumes_table_name_unique": {
|
||||
"name": "volumes_table_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,13 @@
|
||||
"when": 1761414054481,
|
||||
"tag": "0008_silent_lady_bullseye",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 9,
|
||||
"version": "6",
|
||||
"when": 1762095226041,
|
||||
"tag": "0009_little_adam_warlock",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -70,7 +70,6 @@ export const backupSchedulesTable = sqliteTable("backup_schedules_table", {
|
||||
id: int().primaryKey({ autoIncrement: true }),
|
||||
volumeId: int("volume_id")
|
||||
.notNull()
|
||||
.unique()
|
||||
.references(() => volumesTable.id, { onDelete: "cascade" }),
|
||||
repositoryId: text("repository_id")
|
||||
.notNull()
|
||||
|
||||
@@ -71,8 +71,6 @@ export const repositoriesController = new Hono()
|
||||
|
||||
const response = { snapshots };
|
||||
|
||||
c.header("Cache-Control", "max-age=30, stale-while-revalidate=300");
|
||||
|
||||
return c.json<ListSnapshotsDto>(response, 200);
|
||||
})
|
||||
.get(
|
||||
|
||||
Reference in New Issue
Block a user