Implement database administration
Add routes and admin panel elements for creating a database backup, restoring from a backup, deleting the existing schedule, and replacing the database with the demo schedule. These server as crude ways to manage the data stored in the system.
This commit is contained in:
parent
b2f48e98e0
commit
e5e923bc8d
6 changed files with 190 additions and 5 deletions
44
server/api/admin/database-import.post.ts
Normal file
44
server/api/admin/database-import.post.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
import { readNextSessionId, readNextUserId, readSessions, type ServerSession, type ServerUser, writeNextSessionId, writeNextUserId, writeSchedule, writeSessions, writeSubscriptions, writeUsers } from "~/server/database";
|
||||
import type { ApiSchedule, ApiSubscription } from "~/shared/types/api";
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await requireServerSessionWithAdmin(event);
|
||||
const formData = await readMultipartFormData(event);
|
||||
let snapshot: undefined | {
|
||||
nextUserId: number,
|
||||
users: ServerUser[],
|
||||
nextSessionId: number,
|
||||
sessions: ServerSession[],
|
||||
subscriptions: ApiSubscription[],
|
||||
schedule: ApiSchedule,
|
||||
};
|
||||
for (const part of formData ?? []) {
|
||||
if (part.name === "snapshot") {
|
||||
snapshot = JSON.parse(part.data.toString("utf-8"));
|
||||
}
|
||||
}
|
||||
if (!snapshot) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "Bad Request",
|
||||
message: "snapshot missing."
|
||||
});
|
||||
}
|
||||
|
||||
const currentNextUserId = await readNextUserId();
|
||||
await writeNextUserId(Math.max(currentNextUserId, snapshot.nextUserId));
|
||||
await writeUsers(snapshot.users);
|
||||
const currentNextSessionId = await readNextSessionId();
|
||||
await writeNextSessionId(Math.max(currentNextSessionId, snapshot.nextSessionId));
|
||||
const currentSessions = new Map((await readSessions()).map(session => [session.id, session]));
|
||||
await writeSessions(snapshot.sessions.filter(session => {
|
||||
const current = currentSessions.get(session.id);
|
||||
// Only keep sessions that match the account id in both sets to avoid
|
||||
// resurrecting deleted sessions. This will still cause session cross
|
||||
// pollution if a snapshot from another instance is loaded here.
|
||||
return current && current.account.id === session.account.id;
|
||||
}));
|
||||
await writeSubscriptions(snapshot.subscriptions);
|
||||
await writeSchedule(snapshot.schedule);
|
||||
await sendRedirect(event, "/");
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue