mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 01:20:55 +00:00
107 lines
3.2 KiB
TypeScript
107 lines
3.2 KiB
TypeScript
import { BaseRepository } from "@edr/api-common";
|
|
import { Injectable } from "@nestjs/common";
|
|
import { InjectRepository } from "@nestjs/typeorm";
|
|
import { In, Repository } from "typeorm";
|
|
|
|
import { FileRecord } from "./entities/file.entity";
|
|
|
|
@Injectable()
|
|
export class FilesRepository extends BaseRepository<FileRecord> {
|
|
constructor(
|
|
@InjectRepository(FileRecord)
|
|
repository: Repository<FileRecord>,
|
|
) {
|
|
super(repository);
|
|
}
|
|
|
|
findByResource(resourceId: string, resource: string): Promise<FileRecord[]> {
|
|
return this.repository.find({ where: { resourceId, resource } });
|
|
}
|
|
|
|
/**
|
|
* Batch sibling of {@link findByResource} for hydrating a page of resources at
|
|
* once (a thread of chat messages, say) instead of one query per row.
|
|
*/
|
|
async findByResourceIds(
|
|
resourceIds: string[],
|
|
resource: string,
|
|
): Promise<FileRecord[]> {
|
|
if (resourceIds.length === 0) return [];
|
|
return this.repository.find({
|
|
where: { resourceId: In(resourceIds), resource },
|
|
order: { createdAt: "ASC" },
|
|
});
|
|
}
|
|
|
|
findByCode(
|
|
resourceId: string,
|
|
resource: string,
|
|
code: string,
|
|
): Promise<FileRecord | null> {
|
|
return this.repository.findOne({ where: { resourceId, resource, code } });
|
|
}
|
|
|
|
/**
|
|
* Retire the live version(s) of a document code. SOFT delete on purpose: the
|
|
* bytes and the row stay so the original upload can still be read back from
|
|
* the version history after staff replace it. Every normal read already
|
|
* filters soft-deleted rows, so callers see only the current version.
|
|
*
|
|
* `replacedBy` / `reason` are stamped on the retired row when a newer file is
|
|
* taking its place (as opposed to a plain removal).
|
|
*/
|
|
async deleteByCode(
|
|
resourceId: string,
|
|
resource: string,
|
|
code: string,
|
|
replacedBy?: { userId?: string | null; reason?: string | null },
|
|
): Promise<void> {
|
|
if (replacedBy) {
|
|
await this.repository.update(
|
|
{ resourceId, resource, code },
|
|
{
|
|
replacedByUserId: replacedBy.userId ?? null,
|
|
replaceReason: replacedBy.reason ?? null,
|
|
},
|
|
);
|
|
}
|
|
await this.repository.softDelete({ resourceId, resource, code });
|
|
}
|
|
|
|
/**
|
|
* Every version of one document code, newest first — superseded versions
|
|
* included. The only read that deliberately looks past the soft-delete filter.
|
|
*/
|
|
findVersionHistory(
|
|
resourceId: string,
|
|
resource: string,
|
|
code: string,
|
|
): Promise<FileRecord[]> {
|
|
return this.repository.find({
|
|
where: { resourceId, resource, code },
|
|
withDeleted: true,
|
|
order: { createdAt: "DESC" },
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Documents belonging to any of the given resources that a reviewer has asked
|
|
* the customer to correct. Used by the approval gate, so it takes a list of
|
|
* resource ids (a company plus each of its company profiles) in one query.
|
|
*/
|
|
async findWithOpenChangeRequest(
|
|
resourceIds: string[],
|
|
resource: string,
|
|
): Promise<FileRecord[]> {
|
|
if (resourceIds.length === 0) return [];
|
|
return this.repository.find({
|
|
where: {
|
|
resourceId: In(resourceIds),
|
|
resource,
|
|
reviewStatus: "change_requested",
|
|
},
|
|
order: { createdAt: "ASC" },
|
|
});
|
|
}
|
|
}
|