feat(bearing): 일체 choice gated by the pair eccentricity rule (승인 2026-10-26)
- PierInput.bearingLayout: 분리 (default) or 일체, tracked for changes. - 일체 is selectable only when there is at least one pair and every pair is within 100 mm; otherwise the chip is disabled with the reason. - Validation: B01 (info) when 일체 is chosen and allowed, the block shape is still the 분리 shape; B02 (warning) when it is not allowed and the model falls back to 분리. - The 일체 block shape (2500 × 1200) is not modelled yet. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cd18665d6a
commit
2af5cfb144
7 files changed
+75
-7
No files matched your search
@@ -53,3 +53,13 @@ export function pairEccentricities(blocks: BlockModel[]): PairEccentricity[] {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 일체 is possible when there is at least one pair and every pair is within the limit (승인 2026-10-26).
|
||||
* Returns the pairs over the limit so the reason can be shown.
|
||||
*/
|
||||
export function integratedCheck(blocks: BlockModel[]): { allowed: boolean; overLimit: PairEccentricity[] } {
|
||||
const pairs = pairEccentricities(blocks);
|
||||
const overLimit = pairs.filter((p) => !p.allowed);
|
||||
return { allowed: pairs.length > 0 && overLimit.length === 0, overLimit };
|
||||
}
|
||||
+2
-1
@@ -23,7 +23,7 @@ export const EDITABLE_FIELDS = [
|
||||
] as const;
|
||||
|
||||
/** Inputs tracked for overrides and pending changes: the numeric cards plus 열별 본수 (an array, compared by value). */
|
||||
export const TRACKED_KEYS = [...EDITABLE_FIELDS.map((f) => f.key), 'pileRows', 'groundPosition', 'groundWaterOn', 'groundWaterEl', 'floodLevelEl', 'scourDepthM', 'highWaterEl', 'lowWaterEl', 'strataRows', 'bearingType'] as const;
|
||||
export const TRACKED_KEYS = [...EDITABLE_FIELDS.map((f) => f.key), 'pileRows', 'groundPosition', 'groundWaterOn', 'groundWaterEl', 'floodLevelEl', 'scourDepthM', 'highWaterEl', 'lowWaterEl', 'strataRows', 'bearingType', 'bearingLayout'] as const;
|
||||
|
||||
export type EditableKey = (typeof TRACKED_KEYS)[number];
|
||||
|
||||
@@ -52,6 +52,7 @@ export const FIELD_LABELS: Record<EditableKey, string> = {
|
||||
highWaterEl: '고조위 HWL',
|
||||
lowWaterEl: '저조위 LWL',
|
||||
bearingType: '받침 종류·용량',
|
||||
bearingLayout: '받침 배치',
|
||||
strataRows: '지층 행',
|
||||
};
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ const x = (label: string): ShapeOption => ({ label, isDefault: false });
|
||||
const ok = (label: string): ShapeOption => ({ label, isDefault: false, confirmed: true });
|
||||
|
||||
export const SHAPE_GROUPS: Record<MemberId, ShapeGroup[]> = {
|
||||
bearing: [{ title: '배치', options: [d('분리'), x('일체')] }],
|
||||
bearing: [{ title: '배치', options: [d('분리'), ok('일체')] }],
|
||||
coping: [
|
||||
{ title: '교좌면', options: [d('직각'), x('모따기'), x('라운드')] },
|
||||
{ title: '하면', options: [d('직선'), x('곡선 오목'), x('곡선 볼록')] },
|
||||
|
||||
@@ -70,6 +70,8 @@ export interface PierInput {
|
||||
lowWaterEl?: number;
|
||||
/** 받침 종류·용량 as text (승인 2026-10-26). Absent = 탄성받침 (the default). */
|
||||
bearingType?: string;
|
||||
/** 받침 배치 (승인 2026-10-26): 분리 (default) or 일체. 일체 is allowed only when every front–back pair is within 100 mm. */
|
||||
bearingLayout?: '분리' | '일체';
|
||||
strataRows?: StrataRow[];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { DIM, type PierModel } from './geometry';
|
||||
import type { Issue, PierInput, PierType } from './types';
|
||||
import { validateGround, validatePileEmbedment, validateStrataNValues } from './ground';
|
||||
import { integratedCheck } from './bearing-layout';
|
||||
|
||||
const EXPECTED_COLUMNS: Record<PierType, number> = { 'T형': 1, '2주형': 2, '3주형': 3 };
|
||||
|
||||
@@ -93,4 +94,14 @@ export function validatePier(input: PierInput, model: PierModel, issues: Issue[]
|
||||
validateGround(input, issues);
|
||||
validatePileEmbedment(input, model, issues);
|
||||
validateStrataNValues(input, issues);
|
||||
// 일체 (승인 2026-10-26): the block shape of 일체 is not modelled yet, so the model keeps 분리 and says so.
|
||||
if (input.bearingLayout === '일체') {
|
||||
const check = integratedCheck(model.blocks);
|
||||
if (!check.allowed) {
|
||||
const worst = check.overLimit.map((p) => `전열 ${p.frontNo}·후열 ${p.backNo} ${p.eccentricityMm.toFixed(0)} mm`).join(', ');
|
||||
issues.push({ code: 'B02', level: 'W', pier: input.name, message: `일체를 골랐지만 편심이 100 mm를 넘는 쌍이 있어 분리로 계산합니다 (${worst || '쌍 없음'}).` });
|
||||
} else {
|
||||
issues.push({ code: 'B01', level: 'I', pier: input.name, message: '일체 배치: 블록 형상은 아직 분리 기준으로 계산합니다 (일체 블록 모델은 다음 단계).' });
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user