mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 06:28:12 +00:00
Backoffice can now "Request changes" on a pending settings change request without rejecting it outright: a new ChangesRequested status keeps the row open so the customer's next edit appends into the same request instead of starting a fresh cycle, and the reviewer's note persists across that round instead of being cleared on resubmit. Version History and Review History (previously two separate, differently-shaped lists) are merged into one chronological timeline under a new History tab, including document changes shown as a real previous-vs-current diff (both files openable). Bug fixes surfaced while wiring this up: - Replacing a single-file document slot left the old file live alongside the new one instead of retiring it (customer settings + onboarding uploads). - The "previous" file in a document diff 404'd once superseded — the preview route now also matches soft-deleted records. - A document replace was recorded twice in the timeline (once at upload, once again at change-request approval).
67 lines
2.3 KiB
TypeScript
67 lines
2.3 KiB
TypeScript
import { Injectable } from "@nestjs/common";
|
|
import { InjectRepository } from "@nestjs/typeorm";
|
|
import { In, Repository } from "typeorm";
|
|
import { BaseRepository } from "@edr/api-common";
|
|
import {
|
|
ChangeRequestStatus,
|
|
CompanyChangeRequest,
|
|
} from "./entities/company-change-request.entity";
|
|
|
|
/** Statuses that mean "still open, awaiting the customer's next edit" — Pending and ChangesRequested behave identically here, they just carry a note or not. */
|
|
const OPEN_FOR_EDIT_STATUSES = [
|
|
ChangeRequestStatus.Pending,
|
|
ChangeRequestStatus.ChangesRequested,
|
|
];
|
|
|
|
@Injectable()
|
|
export class CompanyChangeRequestRepository extends BaseRepository<CompanyChangeRequest> {
|
|
constructor(
|
|
@InjectRepository(CompanyChangeRequest)
|
|
repo: Repository<CompanyChangeRequest>,
|
|
) {
|
|
super(repo);
|
|
}
|
|
|
|
/** The company's current open request (Pending or ChangesRequested), if any — the row the next edit appends to. */
|
|
async findPendingByCompanyId(
|
|
companyId: string,
|
|
): Promise<CompanyChangeRequest | null> {
|
|
return this.repository.findOne({
|
|
where: { companyId, status: In(OPEN_FOR_EDIT_STATUSES) },
|
|
order: { createdAt: "DESC" },
|
|
});
|
|
}
|
|
|
|
/**
|
|
* The company's latest "open" request — pending (locks the customer) or the
|
|
* most recent rejected one (drives the reapply banner + prefill).
|
|
*
|
|
* Only the company's newest request may be open. A rejection is superseded the
|
|
* moment the customer resubmits: that resubmit opens a *new* request, so once
|
|
* it is approved the newest request is terminal and nothing is open — even
|
|
* though the older rejected row still sits in the table as history.
|
|
*/
|
|
async findLatestOpenByCompanyId(
|
|
companyId: string,
|
|
): Promise<CompanyChangeRequest | null> {
|
|
const pending = await this.findPendingByCompanyId(companyId);
|
|
if (pending) return pending;
|
|
const latest = await this.repository.findOne({
|
|
where: { companyId },
|
|
order: { createdAt: "DESC" },
|
|
});
|
|
return latest?.status === ChangeRequestStatus.Rejected ? latest : null;
|
|
}
|
|
|
|
async findById(id: string): Promise<CompanyChangeRequest | null> {
|
|
return this.repository.findOne({ where: { id } });
|
|
}
|
|
|
|
async findByCompanyId(companyId: string): Promise<CompanyChangeRequest[]> {
|
|
return this.repository.find({
|
|
where: { companyId },
|
|
order: { createdAt: "DESC" },
|
|
});
|
|
}
|
|
}
|