feat(B06): 구조물 전체를 B06 에서 넣게 (B군 종단배수·F군 생태/녹화 열림)

PLAN 3-6 (2026-09-07 사용자 지시 5 「A군뿐 아니라 구조물 전체를 넣을 수 있어야 함」).

원인은 「B06 이 A군만 받는다」가 아니라 **레지스트리의 `enabled:false`** 였음 — B군 6종·
F군 2종·G군 1종이 목록에서 통째로 빠져 있었고, 두 화면이 같은 목록을 쓰므로 B05·B06 이
똑같이 A/C/D/E/G/기타 여섯 군만 보였음. 레지스트리 주석(2026-08-17)이 그 셋을 「B05
선택지에서 빼고 **B06 개별 횡단도 옵션으로 재사용**」이라 적어 둔 자리임.

- `fetchStructureTypes(includeDisabled)` 로 갈래를 둠. B06 만 참으로 부름 — B05 는 종전대로.
- 함께: 3-5 ⓑ 되돌릴 자리 주석(단 2개 이상일 때만 이어 붙이는 한 줄) 표시.

자체검증 — 공용 브라우저에서 두 화면 군 목록 대조:
  B06 A·**B**·C·D·E·**F**·G·기타 (8) / B05 A·C·D·E·G·기타 (6, 그대로)
  B06 에서 B군 6종(측구·산마루측구·소단측구·도수로·절토사면 배수로·맹암거)과
  F군 2종(야생동물 이동통로·비탈면 녹화)이 실제로 목록에 뜸. tsc 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-07 07:57:15 +09:00
co-authored by Claude Opus 5
parent e9ad8cdfaf
commit a811286e52
3 changed files with 21 additions and 4 deletions
+13 -3
View File
@@ -129,18 +129,28 @@ async function requestJson<T>(path: string, init: RequestInit = {}): Promise<T>
/** 타입 레지스트리는 서버 배포 중에 바뀌지 않으므로 탭 수명 동안 한 번만 받는다. */
let typesCache: Promise<StructureType[]> | null = null;
export function fetchStructureTypes(): Promise<StructureType[]> {
/**
* 구조물 타입 목록.
*
* `includeDisabled` 를 주면 `enabled:false` 타입(B군 종단배수·F군 생태/녹화·G군 일부)도
* 함께 준다. 레지스트리 주석(2026-08-17)이 「B05 선택지에서 빼고 **B06 개별 횡단도
* 옵션으로 재사용**」이라 적어 둔 그 자리다 — 2026-09-07 사용자 지시 「A군뿐 아니라
* 구조물 전체를 넣을 수 있어야 함」으로 B06 이 그 목록을 쓴다. B05 는 종전대로 켜진 것만.
*/
export function fetchStructureTypes(includeDisabled = false): Promise<StructureType[]> {
if (!typesCache) {
typesCache = requestJson<StructureTypesResponse>("/projects/structure-types", {
method: "GET",
})
.then((payload) => payload.types.filter((type) => type.enabled))
.then((payload) => payload.types)
.catch((error) => {
typesCache = null; // 실패한 약속을 남겨 두면 다시 시도할 수 없다.
throw error;
});
}
return typesCache;
return typesCache.then((types) =>
includeDisabled ? types : types.filter((type) => type.enabled),
);
}
export async function fetchStructures(projectId: string): Promise<StructureListResponse> {
@@ -653,6 +653,10 @@ export function computeCulvertLayout(
result.segments
.filter((segment) => segment.kind !== "cut")
.flatMap((segment) => segment.points);
// ↓ 되돌릴 자리(2026-09-07) — 「단이 2개 이상일 때만 반영」으로 좁히려면 아래 두 줄의
// `drawnFillPoints(extras)` 를 `extras.walls.length ? drawnFillPoints(extras) : []` 로
// 바꾸면 된다(basinExtras 도 같은 꼴). 다만 그러면 화면이 그리는 성토부선과 면적이
// 다시 어긋난다 — 사용자 판단 대기 중인 항목임(PLAN 3-5 ⓑ).
const extendTrimSlope = (points: OffsetPoint[], outward: number): void => {
if (!points.length) return;
if (outward > 0) {
@@ -313,7 +313,10 @@ export function createB06StructuresPanel(deps: B06StructuresPanelDeps): B06Struc
const projectId = deps.projectId;
try {
const [types, stored, pipeResponse] = await Promise.all([
fetchStructureTypes(),
// B06 은 **구조물 전체**를 넣을 수 있어야 한다(2026-09-07 사용자 지시 5). B05 목록에서
// 빠져 있던 B군 종단배수·F군 생태/녹화도 여기서는 고를 수 있다 — 레지스트리 주석이
// 「B06 개별 횡단도 옵션으로 재사용」이라 적어 둔 그 자리다.
fetchStructureTypes(true),
fetchStructures(projectId),
fetchDetailPipePoints(projectId),
]);