infoalloggi-monorepo/apps/infoalloggi/src/server/controllers/storage.controller.ts

194 lines
4.5 KiB
TypeScript

import { TRPCError } from "@trpc/server";
import type { UsersId } from "~/schemas/public/Users";
import type {
NewUsersStorage,
UsersStorageUserStorageId,
} from "~/schemas/public/UsersStorage";
import { db, type Querier } from "~/server/db";
import { fetchFiles, retriveFilesSafely } from "../services/storage.service";
export const getMultipleWithRelations = async ({
db,
ids,
}: {
db: Querier;
ids: string[];
}) => {
const files = await fetchFiles();
const userStorage = await db
.selectFrom("users_storage")
.selectAll("users_storage")
.innerJoin("users", "users.id", "users_storage.userId")
.select("users.username")
.where(
"storageId",
"in",
files.map((f) => f.id),
)
.execute();
return ids
.map((id) => {
const file = files.find((f) => f.id === id);
if (!file) return null;
const users = userStorage
.filter((us) => us.storageId === id)
.map((us) => ({
id: us.userId,
username: us.username,
}));
return {
...file,
users,
};
})
.filter((f) => f !== null);
};
export const retrieveUserFiles = async ({ userId }: { userId: UsersId }) => {
try {
//all files linked to the user
const files = await db
.selectFrom("users_storage")
.select(["storageId", "from_admin"])
.where("userId", "=", userId)
.execute();
const { available, unavailable } = await retriveFilesSafely(
files.map((f) => f.storageId),
);
//remove entries in users_storage for files that no longer exist in storage
await db
.deleteFrom("users_storage")
.where("userId", "=", userId)
.where("storageId", "in", unavailable)
.execute();
//merge file metadata with users_storage info
const userFiles = files
.map((uf) => {
const file = available.find((f) => f.id === uf.storageId);
if (!file) return null;
return {
...file,
from_admin: uf.from_admin,
};
})
.filter((f) => f !== null);
return userFiles;
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error while getting user storage: ${(e as Error).message}`,
});
}
};
export const getStorageIdFromUserStorageId = async ({
userStorageId,
}: {
userStorageId: UsersStorageUserStorageId;
}) => {
try {
const storage = await db
.selectFrom("users_storage")
.select("storageId")
.where("user_storage_id", "=", userStorageId)
.executeTakeFirstOrThrow(
() =>
new Error(
`User storage entry not found - userStorageId: ${userStorageId}`,
),
);
return storage.storageId;
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error while getting storage ID from user storage ID: ${(e as Error).message}`,
});
}
};
export const getAllWithFromAdmin = async () => {
try {
const files = await db
.selectFrom("users_storage")
.select(["storageId", "from_admin"])
.execute();
const allFiles = await fetchFiles();
const allFilesWithFromAdmin = allFiles.map((file) => {
const userStorageEntry = files.find((f) => f.storageId === file.id);
return {
...file,
from_admin: userStorageEntry ? userStorageEntry.from_admin : true,
};
});
return allFilesWithFromAdmin;
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error while getting user storage: ${(e as Error).message}`,
});
}
};
export const addUserStorage = async (data: NewUsersStorage) => {
try {
return await db
.insertInto("users_storage")
.values(data)
.onConflict((oc) => oc.columns(["userId", "storageId"]).doNothing())
.returning("user_storage_id")
.executeTakeFirst();
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error while adding user storage: ${(e as Error).message}`,
});
}
};
export const deleteUserStorageEntry = async ({
userId,
storageId,
}: {
userId: UsersId;
storageId: string;
}) => {
try {
await db
.deleteFrom("users_storage")
.where("userId", "=", userId)
.where("storageId", "=", storageId)
.execute();
return "ok";
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error while deleting user storage: ${(e as Error).message}`,
});
}
};
export const purgeFileFromUserStorages = async ({
storageId,
}: {
storageId: string;
}) => {
try {
await db
.deleteFrom("users_storage")
.where("storageId", "=", storageId)
.execute();
return "ok";
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error while deleting user storage: ${(e as Error).message}`,
});
}
};