feat(parse): join pier, IP, and bearing tables across sheets by 교각명

- one workbook may hold the three tables on separate sheets (user decision,
  recorded in DOC/03_설계); spec 2.2 one-sheet-per-pier is superseded
- E05 for rows whose 교각명 has no matching 교각 정보 row, or a pier missing IP/받침
- helper sheets (IP only, 받침 only) are shown as 보조 표 시트, not selectable
- test: three-sheet workbook built from the P1 sheet

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-21 17:59:26 +09:00
1 parent 4f21bd63bf
commit 727cd3b2e2
4 files changed
+161 -106

No files matched your search

+32
View File
@@ -1,3 +1,4 @@
import * as XLSX from 'xlsx';
import { describe, expect, it } from 'vitest';
import { parseWorkbook } from '../src/core/parseWorkbook';
import { loadP1, loadWorkbook } from './helpers';
@@ -60,3 +61,34 @@ describe('tables split across sheets (spec §2.2: 시트 1장 = 교각 1기)', (
expect(sheets[0].ok).toBe(false);
});
});
describe('three-sheet input (교각 · IP · 받침 on separate sheets, joined by 교각명)', () => {
/** Splits the P1 sheet into the three sheets the user prepares: rows 22–23, 25–29, 31–41 (1-based). */
function threeSheets(): XLSX.WorkBook {
const src = loadWorkbook();
const grid = XLSX.utils.sheet_to_json<(string | number | null)[]>(src.Sheets['intent.PR'], {
header: 1,
raw: true,
defval: null,
});
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(grid.slice(21, 23)), '교각');
XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(grid.slice(24, 29)), 'IP');
XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(grid.slice(30, 41)), '받침');
return wb;
}
it('joins the three sheets into one pier with 4 IP points and 10 bearings', () => {
const { piers, issues, sheets } = parseWorkbook(threeSheets());
expect(issues).toEqual([]);
expect(piers).toHaveLength(1);
expect(piers[0]).toMatchObject({ name: 'P1', sheet: '교각' });
expect(piers[0].ips).toHaveLength(4);
expect(piers[0].bearings).toHaveLength(10);
expect(sheets.map((s) => [s.name, s.ok, s.piers])).toEqual([
['교각', true, 1],
['IP', true, 0],
['받침', true, 0],
]);
});
});