feat(ui_template): 항목 고르기를 실서버에 이음 — 가짜 응답 지움 (PLAN 21-9)
- GET /api/m02/items?all=1 = [{layer, owner, items}] 를 줄마다 layer · owner 를 붙여 폄 · 404 갈래와 ui_template_item_picker_fake.ts 지움
- 보이는 항목 이름 = 종류 + 분류1~3 (열은 집계표 열 id) · summary_item.name 도 같은 이름
- 폴더 줄은 서버 names{일위대가 · 자재조합 · 도번 · 면적번 · 재료번} 이름을 보임(키는 툴팁) · 이름이 없으면 키를 작은 글로
- 복사 응답 {key} 의 개인 항목을 바로 고름
- 자료 시험을 서버 줄 모양으로 다시 씀
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K7JS47SacjPxZ718QsZKyr
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* 항목 고르기 자료 쪽 검증 — 나무 · 찾기 · 돌려줄 summary_item · 폴더 줄 · 가짜 응답(21-1 모양).
|
||||
* 항목 고르기 자료 쪽 검증 — 나무 · 찾기 · 돌려줄 summary_item · 폴더 줄(21-1 · 21-9 서버 모양).
|
||||
* 실행: node --experimental-strip-types resources/tester/ui/item-picker-data.test.ts
|
||||
*/
|
||||
import assert from "node:assert/strict";
|
||||
@@ -8,18 +8,69 @@ import {
|
||||
filterRows,
|
||||
folderLines,
|
||||
isCurrent,
|
||||
itemName,
|
||||
pathIds,
|
||||
rowId,
|
||||
toSummary,
|
||||
type PickerRow,
|
||||
type TreeLabels,
|
||||
} from "../../../ui_template/ui_template_item_picker_data.ts";
|
||||
import { fakeCopy, fakeItems } from "../../../ui_template/ui_template_item_picker_fake.ts";
|
||||
|
||||
const labels: TreeLabels = {
|
||||
layers: { system: "마스터", company: "회사", personal: "개인" },
|
||||
unclassified: "분류 없음",
|
||||
};
|
||||
const rows = fakeItems();
|
||||
|
||||
/** 서버 줄 그대로 — `열` 은 집계표 열 id · 보이는 이름은 종류 + 분류 */
|
||||
const row = (
|
||||
key: string,
|
||||
열: string,
|
||||
종류: string,
|
||||
분류: [string, string, string],
|
||||
layer: PickerRow["layer"],
|
||||
extra: Partial<PickerRow> = {},
|
||||
): PickerRow => ({
|
||||
key,
|
||||
열,
|
||||
종류,
|
||||
분류1: 분류[0],
|
||||
분류2: 분류[1],
|
||||
분류3: 분류[2],
|
||||
단위: "m",
|
||||
일위대가: "UA000004",
|
||||
자재조합: "UM000001",
|
||||
도번: "SD01010100",
|
||||
면적번: "SA01010100",
|
||||
재료번: "SM01010100",
|
||||
layer,
|
||||
owner: layer === "company" ? "샘플회사" : layer === "personal" ? "샘플회사/사용자" : null,
|
||||
...extra,
|
||||
});
|
||||
|
||||
const rows: PickerRow[] = [
|
||||
row("SS000001", "rv", "돌기슭막이", ["메쌓기", "1.2m", "기초유"], "system", {
|
||||
names: {
|
||||
일위대가: "돌기슭막이 메쌓기 일위대가",
|
||||
자재조합: null,
|
||||
도번: "돌기슭막이 도면",
|
||||
면적번: "돌기슭막이 면적산출",
|
||||
재료번: "돌기슭막이 재료산출",
|
||||
},
|
||||
}),
|
||||
row("SS000002", "rv2", "돌기슭막이", ["메쌓기", "1.5m", "기초유"], "system"),
|
||||
row("SS000003", "rv3", "돌기슭막이", ["찰쌓기", "1.2m", ""], "system"),
|
||||
row("SS000004", "pv", "콘크리트포장", ["일반", "T=20cm", ""], "system"),
|
||||
row("SS000005", "pg", "관보호공", ["콘크리트", "", ""], "system"),
|
||||
row("SS000101", "c1", "돌기슭막이", ["메쌓기", "1.2m", "기초유"], "company"),
|
||||
row("SS000102", "c2", "옹벽", ["", "H=2m", ""], "company"),
|
||||
row("SS000201", "p1", "돌기슭막이", ["메쌓기", "1.2m", "기초유"], "personal"),
|
||||
];
|
||||
|
||||
// 이름 = 종류 + 분류 이음 · 비면 열 id · 키
|
||||
assert.equal(itemName(rows[0]), "돌기슭막이 메쌓기 1.2m 기초유");
|
||||
assert.equal(itemName(rows[6]), "옹벽 H=2m");
|
||||
assert.equal(itemName({ key: "SS000009", 열: "zz" }), "zz");
|
||||
assert.equal(itemName({ key: "SS000009", 열: "" }), "SS000009");
|
||||
|
||||
// 나무 — 그룹은 늘 마스터 · 회사 · 개인 차례 · 그룹 → 종류 → 분류1 → 잎
|
||||
const tree = buildTree(rows, labels);
|
||||
@@ -50,10 +101,9 @@ assert.equal(leaf?.count, null);
|
||||
assert.ok(leaf?.row);
|
||||
|
||||
// 분류가 빈 항목은 「분류 없음」 한 칸에 모임
|
||||
const company = tree[1];
|
||||
assert.equal(company.children?.[1].children?.[0].label, "분류 없음");
|
||||
assert.equal(tree[1].children?.[1].children?.[0].label, "분류 없음");
|
||||
|
||||
// 빈 그룹도 한 줄은 남음
|
||||
// 빈 그룹도 한 줄은 남음(회사 없는 사람의 회사 · 개인 그룹)
|
||||
const onlySystem = buildTree(
|
||||
rows.filter((r) => r.layer === "system"),
|
||||
labels,
|
||||
@@ -83,25 +133,28 @@ assert.deepEqual(
|
||||
["SS000004"],
|
||||
);
|
||||
assert.deepEqual(
|
||||
filterRows(rows, "돌기슭막이 개인").map((r) => r.key),
|
||||
["SS000201"],
|
||||
filterRows(rows, "돌기슭막이 1.5m").map((r) => r.key),
|
||||
["SS000002"],
|
||||
);
|
||||
assert.deepEqual(
|
||||
filterRows(rows, "돌기슭막이 도면").map((r) => r.key),
|
||||
["SS000001"],
|
||||
); // 서버가 준 이름(names)으로도 찾음
|
||||
assert.equal(filterRows(rows, "없는이름").length, 0);
|
||||
|
||||
// 돌려줄 summary_item — 마스터는 owner null · 회사 · 개인은 주인
|
||||
// 돌려줄 summary_item — 마스터는 owner null · 회사 · 개인은 주인 · 이름은 보이는 이름
|
||||
assert.deepEqual(toSummary(rows[0]), {
|
||||
layer: "system",
|
||||
owner: null,
|
||||
key: "SS000001",
|
||||
name: "돌기슭막이 메쌓기 1.2m 기초유",
|
||||
});
|
||||
const mine = rows.find((r) => r.layer === "personal");
|
||||
assert.ok(mine);
|
||||
const mine = rows[7];
|
||||
assert.deepEqual(toSummary(mine), {
|
||||
layer: "personal",
|
||||
owner: "샘플회사/사용자",
|
||||
key: "SS000201",
|
||||
name: "돌기슭막이 메쌓기 1.2m(개인)",
|
||||
name: "돌기슭막이 메쌓기 1.2m 기초유",
|
||||
});
|
||||
// layer 없는 줄(옛 서버)은 마스터로 봄
|
||||
assert.equal(toSummary({ key: "SS000009", 열: "임시" }).layer, "system");
|
||||
@@ -118,22 +171,19 @@ assert.deepEqual(pathIds(rows[0], labels), [
|
||||
"system|돌기슭막이|메쌓기",
|
||||
]);
|
||||
|
||||
// 폴더 모양 — 도면 · 면적산출 · 재료산출은 항목 이름 · 번호는 툴팁 · 값이 없으면 빈 글
|
||||
// 폴더 모양 — 다섯 줄 · 이름은 서버 names · 없으면 키만(작은 글) · 둘 다 없으면 빈 키
|
||||
const lines = folderLines(rows[0]);
|
||||
assert.deepEqual(
|
||||
lines.map((l) => l.kind),
|
||||
["drawing", "area", "material", "combo", "unitPrice"],
|
||||
);
|
||||
assert.equal(lines[0].text, "돌기슭막이 메쌓기 1.2m 기초유");
|
||||
assert.equal(lines[0].tip, "SD000001");
|
||||
assert.equal(folderLines({ key: "SS1", 열: "빈 항목" })[3].text, "");
|
||||
|
||||
// 가짜 복사 — 새 개인 줄이 생기고 키가 겹치지 않음
|
||||
const before = fakeItems();
|
||||
const copied = fakeCopy(before[0]);
|
||||
const after = fakeItems();
|
||||
assert.equal(after.length, before.length + 1);
|
||||
assert.equal(copied.layer, "personal");
|
||||
assert.equal(new Set(after.map(rowId)).size, after.length);
|
||||
assert.deepEqual(lines[0], { kind: "drawing", name: "돌기슭막이 도면", key: "SD01010100" });
|
||||
assert.deepEqual(lines[3], { kind: "combo", name: null, key: "UM000001" }); // names 에 없음
|
||||
assert.deepEqual(folderLines(rows[1])[0], { kind: "drawing", name: null, key: "SD01010100" }); // names 자체가 없음
|
||||
assert.deepEqual(folderLines({ key: "SS1", 열: "x" })[4], {
|
||||
kind: "unitPrice",
|
||||
name: null,
|
||||
key: "",
|
||||
});
|
||||
|
||||
console.log("항목 고르기 자료 시험 통과");
|
||||
|
||||
Reference in New Issue
Block a user