Enhance files service to save file data

Implemented detailed logic to check machine and group existence before saving files. Added comprehensive error handling to provide clear feedback when database operations fail. Improved file saving functionality with associations between files and machines.
This commit is contained in:
Mathis H (Avnyr) 2024-10-07 12:00:46 +02:00
parent 46b090c366
commit ef5349063d
Signed by: Mathis
GPG Key ID: DD9E0666A747D126

View File

@ -1,9 +1,20 @@
import { Injectable, NotFoundException, StreamableFile } from '@nestjs/common'; import {
import { DbService } from 'apps/backend/src/app/db/db.service'; Injectable,
import { FilesTable } from 'apps/backend/src/app/db/schema'; InternalServerErrorException,
import { StorageService } from 'apps/backend/src/app/storage/storage.service'; NotFoundException,
import { eq, ilike } from 'drizzle-orm'; StreamableFile,
} from "@nestjs/common";
import { DbService } from "apps/backend/src/app/db/db.service";
import {
FilesForMachinesTable,
FilesGroupTable,
FilesTable,
FilesTypeForMachine,
MachinesTable,
} from "apps/backend/src/app/db/schema";
import { StorageService } from "apps/backend/src/app/storage/storage.service";
import { data } from "autoprefixer";
import { eq, ilike } from "drizzle-orm";
@Injectable() @Injectable()
export class FilesService { export class FilesService {
@ -30,7 +41,7 @@ export class FilesService {
if (foundFiles.length === 0) if (foundFiles.length === 0)
throw new NotFoundException("File not found", { throw new NotFoundException("File not found", {
description: `Identifier : ${fileId}` description: `Identifier : ${fileId}`,
}); });
if (foundFiles.length > 1) if (foundFiles.length > 1)
@ -51,7 +62,7 @@ export class FilesService {
); );
const fileNameWithoutSpaces = file.fileName.replace(/\s/g, "_"); const fileNameWithoutSpaces = file.fileName.replace(/\s/g, "_");
return new StreamableFile(fileBuffer, { return new StreamableFile(fileBuffer, {
disposition: `attachment; filename="${fileNameWithoutSpaces}.${fileInformation.fileType.ext.toLowerCase()}"` disposition: `attachment; filename="${fileNameWithoutSpaces}.${fileInformation.fileType.ext.toLowerCase()}"`,
}); });
} }
@ -68,7 +79,90 @@ export class FilesService {
} }
//TODO save a file //TODO save a file
public async save() { public async save(file: Buffer, data: Map<string, unknown>) {
const _machineIds = Array.from(data.get("machineId") as string[]);
const machinesIds = new Set<string>();
console.log(
`Checking if machine with ID ${_machineIds} exist in the database...`,
);
for (const machineId of _machineIds) {
const machineExists = await this.database
.use()
.select({
uuid: MachinesTable.id,
})
.from(MachinesTable)
.where(eq(MachinesTable.id, machineId))
.prepare("checkMachineExists")
.execute();
if (machineExists.length === 0) {
throw new NotFoundException(`Machine with ID "${machineId}" not found`);
}
machinesIds.add(machineExists[0].uuid);
}
const _group = data.get("groupId") as string;
// verify that the group exist in the database
const groupExists = await this.database
.use()
.select()
.from(FilesGroupTable)
.where(eq(FilesGroupTable.uuid, _group))
.prepare("checkGroupExists")
.execute();
if (groupExists.length === 0) {
throw new NotFoundException(`Group with ID "${_group}" not found`);
}
try {
const saveResult = await this.storage.new(
data.get("fileName") as string,
file,
_machineIds,
Boolean(data.get("isDocumentation")),
);
const inserted = await this.database
.use()
.insert(FilesTable)
.values({
fileName: data.get("fileName") as string,
checksum: saveResult.fileChecksum,
extension: saveResult.fileType.ext,
fileSize: saveResult.fileSize,
fileType: saveResult.fileType.mime,
isRestricted: Boolean(data.get("isRestricted")),
isDocumentation: Boolean(data.get("isDocumentation")),
uploadedBy: data.get("uploadedBy") as string,
})
.returning();
for (const machineId of machinesIds) {
//TODO insert a link betwen fileId and MachineIds[]
const linkRow = await this.database
.use()
.insert(FilesForMachinesTable)
.values({
fileId: inserted[0].uuid,
machineId: machineId,
});
}
} catch (e) {
throw new InternalServerErrorException(
"It seems that the insertion in the database failed.",
{
cause:
process.env.NODE_ENV === "production"
? "Internal server error"
: {
message: e.message,
stack: e.stack,
},
description: `Nom de fichier : "${data.get("fileName")}" `,
},
);
}
} }
} }