fix(work-orders): search one-character WO numbers for duplicates

This commit is contained in:
Arthur Bassi 2026-08-11 14:51:29 -03:00
parent 5f20fd5263
commit 4f0f70428f
2 changed files with 33 additions and 7 deletions

View file

@ -193,13 +193,13 @@ export const workOrdersApi = {
findByWoNumber: async (woNumber: string): Promise<WorkOrderTableRow | undefined> => {
const normalized = woNumber.trim();
// board/search contract: only send search when length >= 2.
const minLength = 2;
// Safety cap — if hit before exhausting results, fail closed (do not treat as unique).
const safetyMaxPages = 50;
if (normalized.length < minLength) {
// Search every non-empty WO# — backend advanced search accepts 1-character queries, and
// wizard/create allow single-digit numbers (SH-189 must not bypass remote uniqueness).
if (!normalized) {
return undefined;
}
// Safety cap — if hit before exhausting results, fail closed (do not treat as unique).
const safetyMaxPages = 50;
// `board/search` is fuzzy and paginated (0-based); exhaust pages for an exact WO#.
const pageSize = 100;

View file

@ -364,12 +364,38 @@ describe("workOrdersApi.findByWoNumber", () => {
expect(result).toMatchObject({ id: 999, woNumber: "10000009999" });
});
it("skips remote search for single-character WO numbers", async () => {
const result = await workOrdersApi.findByWoNumber("1");
it("skips remote search for empty WO numbers", async () => {
const result = await workOrdersApi.findByWoNumber(" ");
expect(apiGet).not.toHaveBeenCalled();
expect(result).toBeUndefined();
});
it("finds a one-character WO number duplicate outside loaded board rows", async () => {
apiGet.mockResolvedValue({
items: [
{
id: 7,
woNumber: "9",
lifecycleStatusLabel: "Incomplete",
},
],
totalCount: 1,
page: 0,
pageSize: 100,
});
const result = await workOrdersApi.findByWoNumber("9");
expect(apiGet).toHaveBeenCalledTimes(1);
const searchParams = apiGet.mock.calls[0]?.[1]?.searchParams as URLSearchParams;
expect(Object.fromEntries(searchParams)).toEqual({
search: "9",
page: "0",
pageSize: "100",
});
expect(result).toMatchObject({ id: 7, woNumber: "9" });
});
it("throws when the safety page limit is hit before exhausting results", async () => {
apiGet.mockResolvedValue({
items: Array.from({ length: 100 }, (_, index) => ({