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

195 lines
4.5 KiB
TypeScript
Raw Normal View History

2025-08-04 17:45:44 +02:00
import { TRPCError } from "@trpc/server";
import type { UsersId } from "~/schemas/public/Users";
import type {
NewUsersStorage,
UsersStorageUserStorageId,
} from "~/schemas/public/UsersStorage";
2025-10-24 16:10:59 +02:00
import { db, type Querier } from "~/server/db";
import { fetchFiles, retriveFilesSafely } from "../services/storage.service";
2025-08-04 17:45:44 +02:00
2025-10-24 16:10:59 +02:00
export const getMultipleWithRelations = async ({
2025-08-28 18:27:07 +02:00
db,
2025-10-24 16:10:59 +02:00
ids,
2025-08-04 17:45:44 +02:00
}: {
2025-08-28 18:27:07 +02:00
db: Querier;
2025-10-24 16:10:59 +02:00
ids: string[];
2025-08-04 17:45:44 +02:00
}) => {
2025-10-24 16:10:59 +02:00
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);
2025-08-04 17:45:44 +02:00
};
2025-10-24 16:10:59 +02:00
export const retrieveUserFiles = async ({ userId }: { userId: UsersId }) => {
2025-08-28 18:27:07 +02:00
try {
2025-10-24 16:10:59 +02:00
//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)
2025-08-28 18:27:07 +02:00
.execute();
2025-10-24 16:10:59 +02:00
//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) {
2025-08-28 18:27:07 +02:00
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
2025-10-24 16:10:59 +02:00
message: `Error while getting user storage: ${(e as Error).message}`,
2025-08-28 18:27:07 +02:00
});
}
2025-08-04 17:45:44 +02:00
};
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}`,
});
}
};
2025-10-24 16:10:59 +02:00
export const getAllWithFromAdmin = async () => {
2025-08-28 18:27:07 +02:00
try {
2025-10-24 16:10:59 +02:00
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,
};
2025-08-28 18:27:07 +02:00
});
2025-08-04 17:45:44 +02:00
2025-10-24 16:10:59 +02:00
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();
2025-08-28 18:27:07 +02:00
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error while adding user storage: ${(e as Error).message}`,
});
}
2025-08-04 17:45:44 +02:00
};
2025-10-24 16:10:59 +02:00
export const deleteUserStorageEntry = async ({
2025-08-28 18:27:07 +02:00
userId,
storageId,
2025-08-04 17:45:44 +02:00
}: {
2025-08-28 18:27:07 +02:00
userId: UsersId;
2025-10-24 16:10:59 +02:00
storageId: string;
2025-08-04 17:45:44 +02:00
}) => {
2025-08-28 18:27:07 +02:00
try {
2025-10-24 16:10:59 +02:00
await db
.deleteFrom("users_storage")
.where("userId", "=", userId)
.where("storageId", "=", storageId)
.execute();
2025-08-28 18:27:07 +02:00
return "ok";
2025-10-24 16:10:59 +02:00
} catch (e) {
2025-08-28 18:27:07 +02:00
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
2025-10-24 16:10:59 +02:00
message: `Error while deleting user storage: ${(e as Error).message}`,
2025-08-28 18:27:07 +02:00
});
}
2025-08-04 17:45:44 +02:00
};
2025-10-24 16:10:59 +02:00
export const purgeFileFromUserStorages = async ({
storageId,
2025-08-04 17:45:44 +02:00
}: {
2025-10-24 16:10:59 +02:00
storageId: string;
2025-08-04 17:45:44 +02:00
}) => {
2025-10-24 16:10:59 +02:00
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}`,
});
}
2025-08-04 17:45:44 +02:00
};