style: 저장소 전체 포맷터 일괄 적용 (prettier·biome·ruff)

파일마다 포맷 폭이 달라(≈80 대 100) 한 줄만 고쳐도 포맷터가 무관한 줄을 대량
재포맷했음. 사용자 지시로 전체를 한 번에 맞춤. 코드 동작 변경 없음 — 포맷만.

- 프론트엔드 `.ts/.css/.html` → 저장소 prettier (`.prettierrc`, printWidth 100)
- `B07_DesignDetail/openwebcad/**` → 자체 biome (tab 들여쓰기·single quote·lineWidth 100).
  `biome format` 만 사용 — `biome lint --write` 는 포맷 아닌 코드 수정까지 하므로 제외
- 파이썬 → `ruff format` (엔진 코드는 이미 정합, resources·scratch 스크립트 24개만 변경)

두 포맷터가 서로 되돌리지 않도록 `.prettierignore` 신규 — openwebcad 와 빌드·산출물
폴더를 prettier 대상에서 뺌. `.prettierrc` 에 `endOfLine: "auto"` 추가 — 기본값 `lf` 가
`core.autocrlf=true` 로 받은 CRLF 파일을 매번 전부 다시 써서 `--list-different` 가
실제 포맷 차이를 가리고 있었음.

검증: `tsc --noEmit` 통과(루트·openwebcad 둘 다), pytest 349 passed / 17 skipped /
0 failed, CAD vitest 87건 중 81 passed / 6 failed(laptop-sub 기준선과 동일, 회귀 없음).
포맷터 재실행 시 prettier·biome 모두 변경 0건.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-02 07:08:24 +09:00
co-authored by Claude Opus 5
parent 43f23c38ef
commit 4cb9b15939
143 changed files with 4133 additions and 4103 deletions
+12 -46
View File
@@ -6,14 +6,8 @@
* 갱신하고, 화면 갱신은 호출측이 넘긴 콜백으로만 한다 — 이 파일은 DOM 구조를 모른다.
* ========================================================================== */
import {
PROGRESS_UPDATE_INTERVAL_MS,
UPLOAD_CHUNK_SIZE_MB,
} from "@config/config_frontend";
import {
fetchWorkflowState,
type WorkflowState,
} from "../A00_Common/b_workflow_nav";
import { PROGRESS_UPDATE_INTERVAL_MS, UPLOAD_CHUNK_SIZE_MB } from "@config/config_frontend";
import { fetchWorkflowState, type WorkflowState } from "../A00_Common/b_workflow_nav";
import { createButton } from "@ui/ui_template_elements";
import { fileFingerprint } from "./B03_FileInput_Fingerprint";
import { currentLanguageIndex, ui_locales } from "@ui/ui_template_locale";
@@ -24,10 +18,7 @@ import {
uploadFileChunk,
type UploadedFileResult,
} from "./B03_FileInput_Api_Fetch";
import {
saveB03UploadedFile,
updateB03AnalysisState,
} from "./B03_FileInput_State";
import { saveB03UploadedFile, updateB03AnalysisState } from "./B03_FileInput_State";
import {
makeSessionKey,
type FileSlotState,
@@ -42,10 +33,7 @@ function L(key: keyof typeof ui_locales): string {
* 완료된 슬롯 재업로드 확인 모달 — 기존 파일·분석 결과가 교체된다는 경고에 사용자의
* 명시적 확인을 받는다(2026-08-04 사용자 지시). 확인 시에만 resolve(true).
*/
export function confirmReplaceUpload(
slotLabel: string,
fileName: string,
): Promise<boolean> {
export function confirmReplaceUpload(slotLabel: string, fileName: string): Promise<boolean> {
return new Promise((resolve) => {
const backdrop = document.createElement("div");
backdrop.className = "b03-file__modal-backdrop";
@@ -120,9 +108,7 @@ export async function uploadOneFile(
const chunkSizeBytes = UPLOAD_CHUNK_SIZE_MB * 1024 * 1024;
// 같은 파일을 다시 고른 경우 전송을 통째로 건너뛴다 — 라이다는 한 번에 몇 분씩 걸린다.
const fingerprint = state.uploadSessionId
? null
: await fileFingerprint(file);
const fingerprint = state.uploadSessionId ? null : await fileFingerprint(file);
let session = state.uploadSessionId;
if (!session) {
const created = await createUploadSession(
@@ -156,22 +142,11 @@ export async function uploadOneFile(
const start = chunkIndex * chunkSizeBytes;
const end = Math.min(file.size, start + chunkSizeBytes);
const chunkStartedAt = performance.now();
await uploadFileChunk(
projectId,
session,
chunkIndex,
file.slice(start, end),
);
const elapsedSec = Math.max(
0.001,
(performance.now() - chunkStartedAt) / 1000,
);
await uploadFileChunk(projectId, session, chunkIndex, file.slice(start, end));
const elapsedSec = Math.max(0.001, (performance.now() - chunkStartedAt) / 1000);
state.progressBytes = end;
state.speedMbs = (end - start) / 1024 / 1024 / elapsedSec;
state.etaSeconds =
state.speedMbs > 0
? (file.size - end) / 1024 / 1024 / state.speedMbs
: null;
state.etaSeconds = state.speedMbs > 0 ? (file.size - end) / 1024 / 1024 / state.speedMbs : null;
const stored: StoredUploadSession = {
key: storageKey,
@@ -188,10 +163,7 @@ export async function uploadOneFile(
localStorage.setItem(storageKey, JSON.stringify(stored));
const now = performance.now();
if (
now - lastPaintAt > PROGRESS_UPDATE_INTERVAL_MS ||
chunkIndex === totalChunks - 1
) {
if (now - lastPaintAt > PROGRESS_UPDATE_INTERVAL_MS || chunkIndex === totalChunks - 1) {
lastPaintAt = now;
onProgress();
}
@@ -213,10 +185,7 @@ export async function uploadOneFile(
});
state.progressBytes = file.size;
state.speedMbs =
file.size /
1024 /
1024 /
Math.max(0.001, (performance.now() - startedAt) / 1000);
file.size / 1024 / 1024 / Math.max(0.001, (performance.now() - startedAt) / 1000);
state.etaSeconds = 0;
state.uploadStatus = "completed";
onProgress();
@@ -237,12 +206,9 @@ export async function uploadOneFile(
*
* 전처리가 실패했으면 더 기다릴 게 없으므로 잠금을 푼다.
*/
export function isInitialPipelineRunning(
state: WorkflowState | undefined,
): boolean {
export function isInitialPipelineRunning(state: WorkflowState | undefined): boolean {
if (!state?.stages?.length) return false;
const stageAt = (stageNo: number) =>
state.stages.find((stage) => stage.stage_no === stageNo);
const stageAt = (stageNo: number) => state.stages.find((stage) => stage.stage_no === stageNo);
const fileInput = stageAt(0);
const preprocess = stageAt(1);
const section = stageAt(3);