feat(freight): non-terminal change-request review + unified customer timeline

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).
This commit is contained in:
Nathnael
2026-07-31 14:12:30 +00:00
parent 3952e8bbdf
commit 4f81a0bbb8
23 changed files with 795 additions and 166 deletions

View File

@@ -2810,6 +2810,21 @@ export const api = {
],
),
requestChangeRequestChanges: endpoint<
{ id: string; note: string },
CompanyChangeRequest
>(
"customers",
"requestChangeRequestChanges",
({ id, note }) => customersService.requestChangeRequestChanges(id, note),
undefined,
(_input, data) => [
QUERY_KEYS.CUSTOMERS.changeRequests(data.companyId),
QUERY_KEYS.CUSTOMERS.byId(data.companyId),
QUERY_KEYS.CUSTOMERS.ROOT,
],
),
/**
* Ask the customer to correct one document. Invalidates the documents list
* and the company itself, since an open request blocks role approval.

View File

@@ -173,6 +173,19 @@ export const customersService = {
.then((r) => r.data);
},
/** Ask for specific changes without rejecting — the request stays open for the customer's next edit to append to. */
requestChangeRequestChanges(
id: string,
note: string,
): Promise<CompanyChangeRequest> {
return apiClient
.post<CompanyChangeRequest>(
URL_CONSTANTS.COMPANIES.CHANGE_REQUEST_REQUEST_CHANGES(id),
{ note },
)
.then((r) => r.data);
},
/**
* Ask the customer to correct one uploaded document. Narrower than rejecting
* the whole role: the customer keeps their other documents and only re-uploads