fix(parse): reject split pier tables and block sheets that fail to build

- E05: a sheet whose pier, IP, or bearing table is not on the same sheet is
  not selectable (spec 2.2: one sheet per pier)
- a sheet is selectable only if every pier in it builds; the reason is shown
  next to the sheet instead of a selectable sheet with an unchecked pier

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-21 17:55:46 +09:00
1 parent 69922cfa35
commit 4f21bd63bf
3 files changed
+36

No files matched your search

+19
View File
@@ -78,9 +78,28 @@ function parseSheet(grid: Grid, sheet: string, issues: Issue[]): PierInput[] {
}
const piers: PierInput[] = [];
if (pierHeaders.length === 0 && (ipHeaders.length > 0 || bearingHeaders.length > 0)) {
issues.push({
code: 'E05',
level: 'E',
message: `${sheet}: 교각 정보 표가 이 시트에 없습니다. 교각 1기의 세 표(교각 정보·IP·받침)를 한 시트에 두세요 (시트 1장 = 교각 1기).`,
});
}
for (const h of pierHeaders) {
for (const { cells, index } of readBlock(grid, h)) {
const name = String(cells[0]);
const pierIps = ips.filter((p) => p.pier === name);
const pierBearings = bearings.filter((b) => b.pier === name);
if (pierIps.length === 0 || pierBearings.length === 0) {
const missing = [pierIps.length === 0 ? 'IP' : null, pierBearings.length === 0 ? '받침' : null].filter(Boolean).join('·');
issues.push({
code: 'E05',
level: 'E',
pier: name,
message: `${index + 1}행: ${missing} 표가 이 시트에 없습니다. 교각 1기의 세 표를 한 시트에 두세요 (시트 1장 = 교각 1기).`,
});
continue;
}
const bad = bearings.find((b) => b.pier === name && !b.azimuthOk);
if (bad) {
issues.push({