Files
networkSetup/.claude/rules/frontend.md
T
jychoi4andClaude Opus 5.5 905e6d4eaa chore: add Claude Code guidelines, rules and skills
- CLAUDE.md: product principles, crate layering, common commands, commits.
- .claude/rules: common, Rust, frontend, Tauri IPC, docs and security rules.
- .claude/skills: check, add-tauri-command, project-model-change,
  change-record, msix-integration-test, backlog-status.

Refs #16

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:09:05 +09:00

3.7 KiB
Raw Blame History

paths
paths
src/apps/desktop/src/**
src/apps/desktop/tests/**
src/apps/desktop/index.html
src/apps/desktop/package.json
src/apps/desktop/tsconfig.json

프런트엔드(TypeScript · CSS) 규칙

프레임워크 없는 TypeScript. 화면은 문자열 템플릿으로 만들고 root.innerHTML에 넣은 뒤 data-action/data-field 속성으로 이벤트를 연결한다. tsc --noEmit strict와 node --test를 통과해야 한다.

모듈 구조

  • main.ts는 상태와 조정(invoke 호출, render, action 분기)만 둔다. 화면 조각과 순수 로직은 별도 모듈로 뺀다: start-screen.ts, registry-editor.ts, signing-editor.ts, project-transition.ts, window-chrome.ts.
  • 새 탭·편집기는 render<Name>(data, disabled): string을 export하는 모듈로 만들고, main.ts에서는 import와 action 분기만 추가한다.
  • 테스트는 tests/<module>.test.mjs에서 .ts를 직접 import한다. Node의 --experimental-strip-types로 실행되므로 enum, namespace, 매개변수 프로퍼티, 데코레이터를 쓰지 않는다. 타입은 type 별칭과 import type으로.
  • 순수 함수(그룹화, 경로 표시, 전환 판단)는 DOM 없이 호출 가능해야 테스트할 수 있다. document를 쓰는 코드와 분리한다.

보안 · 렌더링

  • 템플릿에 들어가는 모든 동적 값은 esc()/escape()를 거친다. 프로젝트 이름, 경로, 오류 메시지, ID도 예외 없다. 테스트는 <img src=x onerror=...> 같은 값이 이스케이프되는지 확인한다.
  • tauri.conf.json의 CSP는 'self'만 허용한다. 인라인 <script>, 인라인 style=, 외부 폰트·CDN을 추가하지 않는다.
  • innerHTML을 쓰는 곳은 render 함수 안에서만. 이벤트 핸들러는 addEventListener로 붙이고 onclick= 속성을 쓰지 않는다.
  • any를 새로 쓰지 않는다. 경로 기반 필드 갱신이 필요하면 Record<string, unknown>과 단계별 검사로.

상태와 IPC

  • invoke<T>('command', args)의 T는 Rust 반환 DTO와 필드 단위로 일치하는 type이어야 한다. Rust 쪽 #[serde(default)] Option<T>는 TS에서 field?: T | null.
  • isTauri()가 false인 미리보기 모드에서는 파일 작업을 시도하지 않고 안내 문구를 보여준다.
  • 모든 action은 busy 플래그로 중복 실행을 막고, cancel만 busy 중에 허용한다.
  • 저장 안 된 변경(dirty)이 있을 때 프로젝트를 바꾸는 모든 경로는 allowProjectTransition을 거친다. 저장 실패 시 전환하지 않는다.
  • 변경 후에는 invalidate()로 report/plan을 무효화한다. 오래된 검증 결과를 화면에 남기지 않는다.

접근성 · 문구

  • 버튼은 텍스트 또는 aria-label을 가진다. 아이콘 전용 버튼(×)에는 aria-label과 title.
  • 상태 메시지 영역은 role="status" 또는 aria-live="polite".
  • 사용자 문구는 한국어, 조치 중심: "변경 사항을 저장한 뒤 다시 검사하세요." 기술 코드는 문장 뒤에 덧붙인다.
  • "배포 가능", "설치 완료", "검증됨" 같은 단어는 실제 상태 필드(deploymentReady, installationTest)가 그렇게 말할 때만 쓴다.

CSS

  • 색상은 theme.css의 var(--color-*)만 사용한다. 새 색이 필요하면 토큰을 먼저 추가한다. hex 하드코딩 금지(.primary의 #fff는 기존 예외).
  • 선택자는 클래스 기반. ID 선택자와 !important 금지.
  • 반응형 분기는 기존 1200px, 1050px 중단점을 재사용한다.
  • style.css는 한 줄 압축 형식이 섞여 있다. 새 규칙은 파일 끝에 사람이 읽을 수 있는 형식으로 추가하고, 기존 압축 블록을 재포맷하지 않는다.