@simplysm/sd-claude 14.0.73 → 14.0.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,6 +33,8 @@ ORM 호출, 파일 변환, 비즈니스 로직 등은 위 두 사유에 해당
33
33
  | 새 앱 부트스트랩 또는 새 서비스·마스터 데이터 추가 | [client-setup.md](./manuals/client-setup.md) |
34
34
  | DB 스키마 정의 또는 ORM 쿼리 작성 | [orm.md](./manuals/orm.md) |
35
35
  | 이종 엔티티를 한 목록으로 합쳐 표시 (UNION) | [orm-union.md](./manuals/orm-union.md) |
36
+ | 콘솔 로깅 코드 작성/수정 (모든 패키지) | [logging.md](./manuals/logging.md) |
37
+ | 패키지 테스트·통합 테스트 작성/추가 | [test.md](./manuals/test.md) |
36
38
 
37
39
  ## 패키지 인덱스
38
40
 
@@ -0,0 +1,64 @@
1
+ # 로깅 표준
2
+
3
+ `@simplysm/*` v14 모든 패키지(node·browser·capacitor)에 적용.
4
+
5
+ ## 원칙
6
+
7
+ - 모든 로그는 `consola.withTag(<tag>)` 인스턴스로 출력. `console.*` 직접 호출 금지.
8
+ - ESLint `no-console` 규칙은 의도된 게이트 — `eslint-disable`/`eslint-disable-next-line no-console` 우회 금지.
9
+ - 메시지에 `[패키지]` 같은 수동 prefix 금지. tag 가 그 역할.
10
+
11
+ ## 권장 패턴
12
+
13
+ ```ts
14
+ import consola from "consola";
15
+
16
+ const logger = consola.withTag("capacitor:auto-update");
17
+
18
+ // ...
19
+ logger.info("최신 버전 확인 중");
20
+ logger.warn("유효하지 않은 semver, 업데이트 건너뜀");
21
+ logger.error("checkPermissions 실패", err);
22
+ ```
23
+
24
+ - tag 형식: `<도메인>:<역할>` 또는 `<패키지명>` 단일 토큰. 짧고 일관.
25
+ - logger 변수는 모듈 최상단에서 1회 선언, 모듈 내부에서 그 변수 사용.
26
+
27
+ ## 금지 패턴
28
+
29
+ ```ts
30
+ // 1) LOG_TAG 수동 prefix + console 래퍼
31
+ const LOG_TAG = "[X]";
32
+ const logger = {
33
+ info: (msg: string, ...args: unknown[]) => {
34
+ console.info(`${LOG_TAG} ${msg}`, ...args);
35
+ },
36
+ };
37
+
38
+ // 2) eslint-disable + 수동 prefix
39
+ // eslint-disable-next-line no-console
40
+ console.error("[X] 실패:", err);
41
+ ```
42
+
43
+ → 모두 `consola.withTag("x")` 1줄로 대체.
44
+
45
+ ## 환경별 셋업
46
+
47
+ - **Node 진입점(서버·CLI)**: 진입점에서 `setupConsola()` 1회. 자세히 [apis/core-node/consola.md](../apis/core-node/consola.md).
48
+ - **Browser·Capacitor 진입점**: `setupConsola` 호출 X (Node 전용). consola 기본 reporter 가 브라우저 콘솔로 출력. tag/level/통일된 호출면 충족.
49
+
50
+ ## 모듈-레벨 logger 주의 (Node 진입점)
51
+
52
+ Node 진입점에서 `setupConsola` 호출 **전** 에 모듈 레벨에서 `consola.withTag()` 를 호출하면 호출 시점의 옵션(level/reporters)이 스냅샷으로 고정되어 이후 setupConsola 변경이 반영되지 않는다.
53
+
54
+ - 해결: `@simplysm/sd-cli` 의 `createLazyLogger(tag)` (`src/runtime/lazy-logger.ts`) 처럼 첫 접근 시점까지 `withTag` 생성을 지연.
55
+ - 브라우저·Capacitor 는 setupConsola 가 없어 이 문제 없음 — 그냥 모듈 레벨 `consola.withTag()` OK.
56
+
57
+ ## 예외 — `eslint-disable no-console` 가 정당화되는 자리
58
+
59
+ 다음 경우에 한해 `/* eslint-disable no-console */` 파일 헤더를 허용한다. 그 외는 모두 consola 로 교체.
60
+
61
+ - **CLI 도움말·yargs help 텍스트** 처럼 stdout 그 자체를 사용자 출력으로 쓰는 경우 (예: `packages/sd-cli/src/sd-cli-entry.ts` 의 `collectYargsHelp`).
62
+ - **ErrorHandler 마지막 안전망** 등 consola 자체가 죽었을 가능성이 있는 catch 블록 — 해당 자리만 `eslint-disable-next-line no-console` + 이유 주석.
63
+
64
+ 예외 적용 시 disable 주석 위에 사유를 1줄로 남긴다.
@@ -0,0 +1,81 @@
1
+ # 테스트 작성
2
+
3
+ `@simplysm/*` v14 모노레포의 패키지 테스트(`packages/<pkg>/tests/`)와 통합 테스트(`tests/<name>/`) 작성 시 따른다. Vitest project 구성·실행 명령은 루트 `CLAUDE.md` 의 "Vitest 프로젝트 구조" 참조 — 여기서는 작성 규약만 다룬다.
4
+
5
+ ## 파일 규약
6
+
7
+ - 위치
8
+ - 패키지: `packages/<pkg>/tests/**/*.spec.ts`
9
+ - 통합: `tests/<name>/src/**/*.spec.ts`
10
+ - 확장자
11
+ - `*.spec.ts` — vitest 실행 대상.
12
+ - `*.acc.spec.ts` — Acceptance 단위 spec. 동일 project 에서 함께 실행.
13
+ - `*.verify.md` — LLM 수동 검증 항목. vitest 실행 대상 아님. 자동화로 잡기 어려운 검증(JSDoc 표현·문서 일관성 등)에만.
14
+ - import 경로: 워크스페이스 패키지는 `@simplysm/<pkg>`. 검증 목적상 내부 구현이 필요하면 상대 경로(`../src/...`).
15
+ - 환경 변수: `vitest.config.ts` 진입 시 `process.env.DEV=true`/`VER=1.0.0-test` 및 동일 값의 `import.meta.env.*` define 자동 주입. 스펙에서 별도 설정 불필요.
16
+
17
+ ## Vitest project 매핑 (패키지 추가 시)
18
+
19
+ `vitest.config.ts` 의 `include`/`exclude` 가 어느 project 에서 도는지 결정. 새 패키지 추가 시:
20
+
21
+ - **Node 전용**: 기본 `node` project 가 자동 include — 추가 작업 없음.
22
+ - **브라우저 환경 필요** (DOM·`window`·Worker 등 사용): `node` project 의 `exclude` 에 해당 패키지 경로 추가. `browser` project 가 자동 include 함.
23
+ - **Angular**: `packages/angular` 전용 project (TestBed + AOT plugin + setupFile) — 다른 패키지에서 따라하지 말 것.
24
+
25
+ ## 통합 테스트 project 추가 절차
26
+
27
+ `tests/<name>/` 디렉토리 1개 = vitest project 1개. 추가 시:
28
+
29
+ 1. `tests/<name>/package.json` — `name: "@simplysm-test/<name>"`, `"private": true`, `"type": "module"`. 필요한 `@simplysm/*` 는 `workspace:*` 로 devDependency 등재.
30
+ 2. `tests/<name>/tsconfig.json` — `extends: "../../tsconfig.json"`, `compilerOptions.typeRoots: ["./node_modules/@types"]`.
31
+ 3. `tests/<name>/src/**/*.spec.ts` — 스펙.
32
+ 4. `vitest.config.ts` `projects[]` 에 entry 추가
33
+ - `name: "<name>"`, `include: ["tests/<name>/**/*.spec.ts"]`
34
+ - 외부 자원 기동 필요시 `globalSetup: "./tests/<name>/vitest.setup.ts"` + `setup`/`teardown` export.
35
+ - 외부 자원이 단일 인스턴스 공유면 `fileParallelism: false` (스펙 파일 직렬 실행).
36
+ - 브라우저 런타임 필요시 `browser: { provider: playwright(), enabled: true, headless: true, instances: [{ browser: "chromium", viewport: { width: 1920, height: 1080 } }] }`.
37
+
38
+ `pnpm-workspace.yaml` 은 이미 `tests/*` 를 포함하므로 `pnpm install` 만 하면 워크스페이스 인식.
39
+
40
+ ### globalSetup 패턴
41
+
42
+ `tests/<name>/vitest.setup.ts`:
43
+
44
+ - `setup({ provide })` 에서 외부 자원 기동(DB 컨테이너·테스트 서버 등). 동적 값(랜덤 포트 등)은 `provide("key", value)` 로 스펙에 전달.
45
+ - `teardown()` 에서 정리. 실패해도 다음 실행이 망가지지 않도록 best-effort.
46
+ - 타입 보강: 파일 상단에
47
+ ```ts
48
+ declare module "vitest" {
49
+ export interface ProvidedContext { key: T }
50
+ }
51
+ ```
52
+ 스펙에서 `inject("key")` 로 수신.
53
+
54
+ 기동 명령에 외부 도구(`docker compose`, `execa` 등) 사용 시 timeout 명시. 재시도가 필요한 자원(MSSQL 초기화 등)은 횟수 한정 retry, 한도 초과 시 throw — silent skip 금지.
55
+
56
+ ## 공통 패턴
57
+
58
+ ### Lint 룰 테스트
59
+
60
+ `@typescript-eslint/rule-tester` 는 vitest 직접 지원 안 함. `vitest.setup.ts` 에서 `RuleTester.describe`/`it`/`afterAll` 에 vitest 함수 바인딩. 스펙은 첫 줄에 `import "./vitest.setup"` 후 `new RuleTester().run(...)`.
61
+
62
+ ### Angular 테스트
63
+
64
+ - 스펙은 `import { TestBed }` 후 `TestBed.configureTestingModule(...)` 부터 시작.
65
+ - TestEnvironment 초기화 + `beforeEach` 의 `resetTestingModule` 은 project setupFile 이 이미 처리. 스펙에서 다시 하지 말 것.
66
+
67
+ ### ORM 다이얼렉트 매트릭스
68
+
69
+ - **단위** (`packages/orm-common/tests`): dialect 별 기대 SQL 비교. 패턴 — `dialects` 상수(`["mysql", "mssql", "postgresql"]`) + `it.each(dialects)` + 커스텀 `toMatchSql` matcher(whitespace 정규화). 기대 SQL 은 같은 폴더 `*.expected.ts` 에 dialect 키 객체로.
70
+ - **통합** (`tests/orm/src`): 실 DB 3종. `describe.each(dbCases)` 로 mysql/postgresql/mssql 반복. dialect 별 DDL 차이는 `tests/orm/src/setup/db-helpers.ts` 가 흡수 — 새 모델 추가 시 이 파일의 CREATE/DROP SQL 에 dialect 분기 추가.
71
+
72
+ ### Service 통합 테스트
73
+
74
+ `tests/service` globalSetup 이 `createServiceServer({ port: 0, ... }).listen()` 으로 랜덤 포트 서버 기동 → `provide("servicePort", port)`. 스펙은 `const TEST_PORT = inject("servicePort")` 로 받아 `createServiceClient` 연결.
75
+
76
+ ## 안티패턴
77
+
78
+ - 스펙 파일에 직접 외부 자원(DB·서버) 기동 코드 박기 — globalSetup 으로 옮길 것.
79
+ - `*.verify.md` 자리에 자동화 가능한 검증 작성 — 자동화 가능하면 `.spec.ts` 로.
80
+ - 통합 테스트 project 에서 `exclude` 로 단위 스펙 빼내기 — 단위는 패키지 `tests/` 에 두고 통합 project 가 절대 include 하지 못하게 분리.
81
+ - 같은 외부 자원을 여러 project 가 동시 점유 — `fileParallelism: false` + project 1개로 통합하거나, project 별로 자원 분리.
@@ -96,6 +96,33 @@ Claude 에이전트가 반드시 지켜야 할 행동 지침이다.
96
96
 
97
97
  질문·답변 프로토콜은 [질문/답변](#질문답변) 참조.
98
98
 
99
+ ## 정보 밀도
100
+
101
+ 응답·산출물 공통. caveman 원리 기반. 기본 강도 = **ultra**.
102
+
103
+ **압축 룰**:
104
+
105
+ - 한국어 어미·조사 압축 — "~할 수도 있을 것 같습니다" → "~ 가능" / "~함"
106
+ - 접속어 strip — 그래서·따라서·또한·하지만 제거. 인과는 화살표 (`X → Y`)
107
+ - 1단어 가능 시 1단어
108
+ - preamble/sign-off 금지 — 인사·작업 개시·마무리 안내
109
+ - 키워드+기호 구조 권장 — `원인: X → Y` / `해결: Z`
110
+ - 중복 bullet 병합 — 같은 의미 반복은 1개로
111
+
112
+ **절대 보존** (압축·약어화·재서술 X):
113
+
114
+ - 코드 심볼·함수명·API명·에러 문자열·URL·파일경로·명령어
115
+ - 기술 용어·고유명사·날짜·버전·숫자·환경변수
116
+ - 사용자 발언 verbatim 인용
117
+ - 도메인 어휘 (위 [대화](#대화) 룰)
118
+ - 구조 — 헤딩·bullet 계층·numbered·표·frontmatter·[질문/답변](#질문답변) `[맥락+선택지+추천+질문]`. 구조는 보존, 그 안 텍스트는 압축 룰 적용.
119
+
120
+ **중단 트리거** (caveman OFF — 표준 톤 복귀):
121
+
122
+ - 보안 경고·되돌릴 수 없는 작업 컨펌
123
+ - 다단계 시퀀스에서 압축이 오독 위험
124
+ - 압축 자체가 기술 모호함 생성
125
+
99
126
  ## Convention 굳히기 금지
100
127
 
101
128
  사용자 피드백을 글자 그대로 문서화하지 말 것. 본질 의도를 추출해 일반 표현으로.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/sd-claude",
3
- "version": "14.0.73",
3
+ "version": "14.0.75",
4
4
  "description": "심플리즘 패키지 - Claude Code 셋업",
5
5
  "author": "심플리즘",
6
6
  "license": "Apache-2.0",