Files
Pier_v1/src/core/validate.ts
T
ypshimandClaude Haiku 5.5 e297db1251 fix(core): replace abolished E04 with I02 in the unimplemented list
E04 (fck 미입력 차단) was abolished on 2026-10-22; fck and fy are now inputs
with assumed defaults, reported as I02 in the rebar stage (spec §10, §13 Q8).

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-22 11:03:14 +09:00

93 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { DIM, type PierModel } from './geometry';
import type { Issue, PierInput, PierType } from './types';
const EXPECTED_COLUMNS: Record<PierType, number> = { 'T형': 1, '2주형': 2, '3주형': 3 };
/** Rules from spec §10 that are not implemented in this stage. Shown to the user, never silently skipped. */
export const NOT_IMPLEMENTED_RULES = [
'I02 fck·fy가 기본값(가정) 그대로 (③ 배근 단계, 3단계)',
'W06 속성 복사 건너뜀 (2단계)',
'W08 솔플레이트 T1−T2 검사 (2단계)',
] as const;
/** Input-level checks (spec §10 E01, E02). Returns false when the pier must not be built. */
export function validateInput(input: PierInput, issues: Issue[]): boolean {
let ok = true;
if (input.columnCount !== EXPECTED_COLUMNS[input.type]) {
issues.push({
code: 'E01',
level: 'E',
pier: input.name,
message: `교각형식 ${input.type}과 기둥갯수 ${input.columnCount}개가 맞지 않습니다. 기둥 ${EXPECTED_COLUMNS[input.type]}개로 맞추세요.`,
});
ok = false;
}
const front = input.bearings.filter((b) => b.row === '전열').length;
const back = input.bearings.filter((b) => b.row === '후열').length;
if (front !== back) {
issues.push({ code: 'E02', level: 'E', pier: input.name, message: `전열 받침 ${front}개, 후열 받침 ${back}개로 수가 다릅니다.` });
ok = false;
}
return ok;
}
/** Geometry-level checks (spec §10 W01–W05, W07, I01) on a built model. */
export function validatePier(input: PierInput, model: PierModel, issues: Issue[]): void {
const ip2Gap = Math.hypot(model.ip2Input.e - model.ip2Calc.e, model.ip2Input.n - model.ip2Calc.n);
if (ip2Gap > 0.001) {
issues.push({
code: 'W01',
level: 'W',
pier: input.name,
message: `IP2 입력과 재계산값이 ${(ip2Gap * 1000).toFixed(1)} mm 다릅니다. 재계산값을 사용합니다.`,
});
}
const minBlock = Math.min(model.derived.blockHeightFront, model.derived.blockHeightBack);
if (minBlock <= 0) {
issues.push({ code: 'W02', level: 'W', pier: input.name, message: '받침블럭 콘크리트 높이가 0 이하입니다. 블럭을 생략합니다.' });
}
// W03: bearing centre closer than half a block width to a step boundary (interior boundaries only).
const halfBlock = DIM.blockSize / 2;
const stepBounds = model.segments.slice(1).map((seg) => seg.s0);
for (const b of model.bearings) {
const nearest = Math.min(...stepBounds.map((s) => Math.abs(b.g - s)));
if (nearest < halfBlock) {
issues.push({
code: 'W03',
level: 'W',
pier: input.name,
message: `${b.row} 받침 ${b.no}번 중심이 계단 경계에서 ${(nearest * 1000).toFixed(0)} mm 떨어져 블럭 폭의 절반(${(halfBlock * 1000).toFixed(0)} mm)보다 가깝습니다.`,
});
}
}
// W04: block footprint extends beyond the coping plan (s in [0, L], n in [−B/2, B/2]).
const planHalfB = model.copingB / 2;
const outside = model.blocks.some(
(b) =>
b.g - halfBlock < 0 ||
b.g + halfBlock > model.copingL ||
b.n - halfBlock < -planHalfB ||
b.n + halfBlock > planHalfB,
);
if (outside) {
issues.push({ code: 'W04', level: 'W', pier: input.name, message: '받침블럭이 코핑 평면 밖으로 나갑니다.' });
}
if (input.foundationType !== '현장타설말뚝' && model.footings.some((f) => f.top > input.groundEl)) {
issues.push({ code: 'W05', level: 'W', pier: input.name, message: '확대기초 상면이 지반고보다 높습니다.' });
}
if (model.derived.frontBackDiffSpread > DIM.lateralTolerance) {
issues.push({ code: 'W07', level: 'I', pier: input.name, message: '전열·후열 EL 차이가 받침마다 다릅니다 (정보).' });
}
// I01: block concrete below cover + bar diameter (cover 100 mm, S1·S2 H19 from spec §6.3).
const cover = 0.1;
const barDia = 0.019;
if (minBlock < cover + barDia) {
issues.push({
code: 'I01',
level: 'I',
pier: input.name,
message: `받침블럭 높이 ${(minBlock * 1000).toFixed(0)} mm가 피복 + 철근 지름(${((cover + barDia) * 1000).toFixed(0)} mm)보다 작습니다. 블럭 철근은 코핑 안에 묻힙니다.`,
});
}
}