@simplysm/sd-claude 14.0.80 → 14.0.81

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.
Files changed (88) hide show
  1. package/claude/references/sd-requirement-source-handling.md +17 -17
  2. package/claude/references/sd-simplysm14/README.md +58 -58
  3. package/claude/references/sd-simplysm14/manuals/client-component.md +739 -739
  4. package/claude/references/sd-simplysm14/manuals/client-crud.md +1 -1
  5. package/claude/references/sd-simplysm14/manuals/client-demo.md +1 -1
  6. package/claude/references/sd-simplysm14/manuals/client-setup.md +2 -2
  7. package/claude/references/sd-simplysm14/manuals/client-tab.md +2 -2
  8. package/claude/references/sd-simplysm14/manuals/logging.md +3 -3
  9. package/claude/references/sd-simplysm14/manuals/orm-union.md +7 -7
  10. package/claude/references/sd-simplysm14/manuals/orm.md +75 -75
  11. package/claude/references/sd-simplysm14/manuals/test.md +8 -8
  12. package/claude/rules/sd-base-rules.md +306 -293
  13. package/claude/rules/sd-design-rules.md +44 -44
  14. package/claude/skills/sd-commit/SKILL.md +17 -17
  15. package/claude/skills/sd-config/SKILL.md +4 -4
  16. package/claude/skills/sd-demo/SKILL.md +40 -48
  17. package/claude/skills/sd-demo/evals/fixtures/inventory-list/.specs/inventory/spec.md +99 -0
  18. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/package.json +12 -0
  19. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/index.ts +3 -0
  20. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/inbound/inbound.list.ts +150 -0
  21. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/inventory/inventory-master.list.ts +143 -0
  22. package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/outbound/outbound.list.ts +150 -0
  23. package/claude/skills/sd-demo/evals/fixtures/inventory-list/pnpm-workspace.yaml +2 -0
  24. package/claude/skills/sd-demo/evals/fixtures/inventory-list/sd.config.ts +12 -0
  25. package/claude/skills/sd-demo/evals/golden.jsonl +1 -5
  26. package/claude/skills/sd-dev/SKILL.md +49 -22
  27. package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/package.json +8 -0
  28. package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/src/.gitkeep +0 -0
  29. package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/tests/.gitkeep +0 -0
  30. package/claude/skills/sd-dev/evals/fixtures/{case-modify → minimal-ts-pkg}/tsconfig.json +1 -3
  31. package/claude/skills/sd-dev/evals/golden.jsonl +1 -3
  32. package/claude/skills/sd-docs/SKILL.md +8 -8
  33. package/claude/skills/sd-impl/SKILL.md +172 -82
  34. package/claude/skills/sd-impl/evals/fixtures/case-a-new-screen/.specs/260513120000_warehouse/spec.md +101 -0
  35. package/claude/skills/sd-impl/evals/fixtures/case-b-update-with-demo/.specs/260513120000_warehouse/spec.md +101 -0
  36. package/claude/skills/sd-impl/evals/fixtures/case-b-update-with-demo/packages/app/src/screens/box-register/box-register.view.ts +46 -0
  37. package/claude/skills/sd-impl/evals/fixtures/case-c-new-cross/.specs/260513120000_warehouse/spec.md +89 -0
  38. package/claude/skills/sd-impl/evals/fixtures/case-d-spec-modify/.specs/260513120000_warehouse/spec.md +101 -0
  39. package/claude/skills/sd-impl/evals/golden.jsonl +4 -6
  40. package/claude/skills/sd-review/SKILL.md +33 -0
  41. package/claude/skills/sd-review/evals/fixtures/code-review/src/foo.ts +7 -0
  42. package/claude/skills/sd-review/evals/fixtures/doc-review/docs/foo.md +4 -0
  43. package/claude/skills/sd-review/evals/golden.jsonl +2 -0
  44. package/claude/skills/sd-skill/SKILL.md +99 -91
  45. package/claude/skills/sd-skill/evals/fixtures/existing-skill/.claude/skills/todo-format/SKILL.md +14 -0
  46. package/claude/skills/sd-skill/evals/fixtures/new-skill/.gitkeep +0 -0
  47. package/claude/skills/sd-skill/evals/golden.jsonl +2 -0
  48. package/claude/skills/sd-spec/SKILL.md +251 -246
  49. package/claude/skills/sd-spec/references/example-spec.md +1 -1
  50. package/claude/skills/sd-unpack/SKILL.md +83 -83
  51. package/claude/skills/sd-use/SKILL.md +4 -4
  52. package/package.json +1 -1
  53. package/claude/skills/sd-demo/evals/fixtures/empty/.specs/260513120000_warehouse/spec.md +0 -45
  54. package/claude/skills/sd-demo/evals/fixtures/with-existing-screen/.specs/260513120000_warehouse/spec.md +0 -42
  55. package/claude/skills/sd-demo/evals/fixtures/with-existing-screen/packages/app/src/screens/dashboard/dashboard.view.ts +0 -33
  56. package/claude/skills/sd-demo/evals/fixtures/with-master-screen/.specs/260513120000_warehouse/spec.md +0 -45
  57. package/claude/skills/sd-demo/evals/fixtures/with-master-screen/packages/app/src/screens/dashboard/dashboard.view.ts +0 -33
  58. package/claude/skills/sd-demo/evals/fixtures/with-modal/.specs/260513120000_warehouse/spec.md +0 -75
  59. package/claude/skills/sd-demo/evals/fixtures/with-modal/packages/app/src/screens/dashboard/dashboard.view.ts +0 -33
  60. package/claude/skills/sd-demo/evals/fixtures/with-screens/.specs/260513120000_warehouse/spec.md +0 -45
  61. package/claude/skills/sd-demo/evals/fixtures/with-screens/packages/app/src/screens/dashboard/dashboard.view.ts +0 -33
  62. package/claude/skills/sd-dev/evals/fixtures/case-add/package.json +0 -13
  63. package/claude/skills/sd-dev/evals/fixtures/case-add/src/index.ts +0 -10
  64. package/claude/skills/sd-dev/evals/fixtures/case-add/tests/index.test.ts +0 -11
  65. package/claude/skills/sd-dev/evals/fixtures/case-add/tsconfig.json +0 -12
  66. package/claude/skills/sd-dev/evals/fixtures/case-bug/package.json +0 -13
  67. package/claude/skills/sd-dev/evals/fixtures/case-bug/src/index.ts +0 -10
  68. package/claude/skills/sd-dev/evals/fixtures/case-bug/tests/index.test.ts +0 -11
  69. package/claude/skills/sd-dev/evals/fixtures/case-bug/tsconfig.json +0 -12
  70. package/claude/skills/sd-dev/evals/fixtures/case-modify/package.json +0 -13
  71. package/claude/skills/sd-dev/evals/fixtures/case-modify/src/index.ts +0 -10
  72. package/claude/skills/sd-dev/evals/fixtures/case-modify/tests/index.test.ts +0 -11
  73. package/claude/skills/sd-impl/evals/fixtures/case-001-new-screen/spec.md +0 -55
  74. package/claude/skills/sd-impl/evals/fixtures/case-002-auto-process/spec.md +0 -55
  75. package/claude/skills/sd-impl/evals/fixtures/case-003-update-screen/packages/client/src/pages/book-list.ts +0 -22
  76. package/claude/skills/sd-impl/evals/fixtures/case-003-update-screen/spec.md +0 -57
  77. package/claude/skills/sd-impl/evals/fixtures/case-004-ambiguous-spec/spec.md +0 -58
  78. package/claude/skills/sd-impl/evals/fixtures/case-005-id-mismatch/spec.md +0 -52
  79. package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/packages/client/src/pages//352/261/260/353/236/230/354/262/230//352/261/260/353/236/230/354/262/230-/353/252/251/353/241/235.test.ts +0 -10
  80. package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/packages/client/src/pages//352/261/260/353/236/230/354/262/230//352/261/260/353/236/230/354/262/230-/353/252/251/353/241/235.ts +0 -11
  81. package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/packages/server/src/data-access//352/261/260/353/236/230/354/262/230-/354/240/221/352/267/274.ts +0 -12
  82. package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/packages/server/src/models//352/261/260/353/236/230/354/262/230.ts +0 -8
  83. package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/spec.md +0 -77
  84. package/claude/skills/sd-impl/evals/fixtures/case-new/.specs/260514120000_/352/261/260/353/236/230/354/262/230/spec.md +0 -101
  85. package/claude/skills/sd-impl/evals/fixtures/case-update/.specs/260514120000_/352/261/260/353/236/230/354/262/230/spec.md +0 -101
  86. package/claude/skills/sd-impl/evals/fixtures/case-update/src//352/261/260/353/236/230/354/262/230//352/261/260/353/236/230/354/262/230-/353/252/250/353/215/270.txt +0 -1
  87. package/claude/skills/sd-impl/evals/fixtures/case-update/src//352/261/260/353/236/230/354/262/230//352/261/260/353/236/230/354/262/230-/353/252/251/353/241/235.txt +0 -1
  88. package/claude/skills/sd-impl/references/spec-cross-check.md +0 -82
@@ -1,44 +1,44 @@
1
- # 코드 설계·변경 규칙
2
-
3
- Claude 에이전트가 코드 작성·설계·변경 시 따라야 할 행동 지침이다.
4
-
5
- ## 인터페이스 설계 시
6
-
7
- - 산출물 소비자 표면(공개 API·props·옵션·UI·출력 등)의 단순함이 내부 구현 단순함보다 우선:
8
- - 복잡도는 내부로 흡수
9
- - 불가능할 경우 사용자 보고 후 결정
10
- - 내부 구현 난이도 회피를 위해 소비자 요구 완화·근사화 금지:
11
- - 난이도는 내부로 흡수
12
- - 불가능할 경우 사용자 보고 후 결정
13
- - 명시 정의 자체를 임의로 단순화하여 처리 금지:
14
- - 정확 구현 부담이 크면 단순화안을 사용자에 보고 후 합의
15
-
16
- ## 변경 전 기존 패턴 조사
17
-
18
- 변경 전, 변경 영역의 기존 코드 패턴과 개발 매뉴얼을 먼저 조사한다.
19
-
20
- - `@simplysm/*` 14.x 패키지 변경 시 → `.claude/references/sd-simplysm14/README.md` 참조
21
-
22
- ## 라이브러리 우회 금지
23
-
24
- - 의존 라이브러리 동작 이상 → 우회 코드 작성 전 라이브러리 측 원인 먼저 조사
25
- - 라이브러리 버그·누락 판단 시 → 사용자에게 보고 후 수정 경로 혹은 이슈 발행 제안
26
- - 우회 코드 작성 금지:
27
- - 불가피할 경우, 사용자 보고 후 결정
28
-
29
- ## 에러 처리 시 throw 원칙
30
-
31
- 문제 발생 시 throw:
32
-
33
- - silent skip 금지 — 예외 캐치 후 대안 없이 진행하면 후속 프로세스가 결손된 채 동작
34
- - **자동 복구** (예: 의존 미설치 → 설치·재시도 = 완전 동작 회복) 는 silent skip 아님
35
-
36
- ## 사용자 표면 알림 작성 시 심각도 분류
37
-
38
- 사용자 표면 알림(로그·토스트·다이얼로그 등)의 심각도 분류 기준:
39
-
40
- - `error` (danger): 문제 발생. catch·무시·재시도 여부와 무관하게 "문제가 일어난 사실" 이면 전부 해당
41
- - `warn`: 문제는 아니지만 사용자가 인지해야 할 중요 알림
42
- - `info`: 알면 좋은 일반 알림
43
- - `success`: 정상 완료 알림
44
- - 안티패턴: 무중단·복구 처리되었다는 이유로 `error` 대신 `warn` 선택 — 분류 기준 오용
1
+ # 코드 설계·변경 규칙
2
+
3
+ Claude 에이전트가 코드 작성·설계·변경 시 따라야 할 행동 지침.
4
+
5
+ ## 인터페이스 설계 시
6
+
7
+ - 산출물 소비자 표면(공개 API·props·옵션·UI·출력 등)의 단순함이 내부 구현 단순함보다 우선:
8
+ - 복잡도는 내부로 흡수.
9
+ - 불가능할 경우 사용자 보고 후 결정.
10
+ - 내부 구현 난이도 회피를 위해 소비자 요구 완화·근사화 금지:
11
+ - 난이도는 내부로 흡수.
12
+ - 불가능할 경우 사용자 보고 후 결정.
13
+ - 명시 정의 자체를 임의로 단순화하여 처리 금지:
14
+ - 정확 구현 부담이 크면 단순화안을 사용자에 보고 후 합의.
15
+
16
+ ## 변경 전 기존 패턴 조사
17
+
18
+ 변경 전, 변경 영역의 기존 코드 패턴과 개발 매뉴얼을 먼저 조사.
19
+
20
+ - `@simplysm/*` 14.x 패키지 변경 시 → `.claude/references/sd-simplysm14/README.md` 참조.
21
+
22
+ ## 라이브러리 우회 금지
23
+
24
+ - 의존 라이브러리 동작 이상 → 우회 코드 작성 전 라이브러리 측 원인 먼저 조사.
25
+ - 라이브러리 버그·누락 판단 시 → 사용자에게 보고 후 수정 경로 혹은 이슈 발행 제안.
26
+ - 우회 코드 작성 금지:
27
+ - 불가피할 경우, 사용자 보고 후 결정.
28
+
29
+ ## 에러 처리 시 throw 원칙
30
+
31
+ 문제 발생 시 throw:
32
+
33
+ - silent skip 금지 — 예외 캐치 후 대안 없이 진행하면 후속 프로세스가 결손된 채 동작.
34
+ - **자동 복구** (예: 의존 미설치 → 설치·재시도 = 완전 동작 회복) 는 silent skip 아님.
35
+
36
+ ## 사용자 표면 알림 작성 시 심각도 분류
37
+
38
+ 사용자 표면 알림(로그·토스트·다이얼로그 등)의 심각도 분류 기준:
39
+
40
+ - `error` (danger): 문제 발생. catch·무시·재시도 여부와 무관하게 "문제가 일어난 사실" 이면 전부 해당.
41
+ - `warn`: 문제는 아니지만 사용자가 인지해야 할 중요 알림.
42
+ - `info`: 알면 좋은 일반 알림.
43
+ - `success`: 정상 완료 알림.
44
+ - 안티패턴: 무중단·복구 처리되었다는 이유로 `error` 대신 `warn` 선택 — 분류 기준 오용.
@@ -1,40 +1,40 @@
1
1
  ---
2
2
  name: sd-commit
3
- description: 워크스페이스의 모든 변경을 단일 커밋으로 묶는 스킬. Use when 여러 변경 사항을 한 번에 커밋해야 할
3
+ description: 워크스페이스의 모든 변경을 단일 커밋으로 묶는 스킬. Use when 여러 변경 사항을 한 번에 커밋해야 할 때.
4
4
  model: haiku
5
5
  ---
6
6
 
7
7
  # 총괄 커밋
8
8
 
9
- system prompt 의 "Committing changes with git" 절차를 따르되, 아래만 적용한다.
9
+ system prompt 의 "Committing changes with git" 절차를 따르되, 아래만 적용함.
10
10
 
11
11
  ## git 호출 prefix
12
12
 
13
- - 대상: 모든 git 호출 (`status`·`diff`·`log`·`add`·`commit`)
13
+ - 대상: 모든 git 호출 (`status`·`diff`·`log`·`add`·`commit`).
14
14
  - 목적: Pre-tool 훅의 전역 git 조회 차단 우회 마커. `add`·`commit` 도 일관성으로 동일 prefix.
15
15
  - **도구별 prefix** — 사용 도구에 맞는 문법 1개만 선택:
16
- - Bash 도구 → `SDGIT=1 git ...`
17
- - PowerShell 도구 → `$env:SDGIT='1'; git ...`
16
+ - Bash 도구 → `SDGIT=1 git ...`.
17
+ - PowerShell 도구 → `$env:SDGIT='1'; git ...`.
18
18
  - 금지:
19
- - Bash 도구에 `$env:...` 사용 — PowerShell 문법
20
- - PowerShell 도구에 `SDGIT=1 git ...` 사용 — bash inline env 문법, PowerShell 파서 에러
19
+ - Bash 도구에 `$env:...` 사용 — PowerShell 문법.
20
+ - PowerShell 도구에 `SDGIT=1 git ...` 사용 — bash inline env 문법, PowerShell 파서 에러.
21
21
 
22
22
  ## staging
23
23
 
24
- - `git add -A` 사용
25
- - 본 스킬 호출 = 사용자가 `-A` 위험(민감 파일 staging) 인지·동의
24
+ - `git add -A` 사용.
25
+ - 본 스킬 호출 = 사용자가 `-A` 위험(민감 파일 staging) 인지·동의.
26
26
 
27
27
  ## 커밋 메시지
28
28
 
29
- - 언어: 사용자 응답 언어와 일치
30
- - 단일 갈래: 제목 1
29
+ - 언어: 사용자 응답 언어와 일치.
30
+ - 단일 갈래: 제목 1줄.
31
31
  - 복수 갈래:
32
- - 제목: 갈래를 `및`·`,` 로 한 줄 병합
33
- - 본문 (빈 줄 후): 갈래별로 아래 블록 반복, 블록 간 빈 줄 분리
34
- - 헤더: `[<type>]: <갈래 요약>`
35
- - 변경 항목 bullet (`-`)
36
- - `<type>`: conventional commits — `fix`·`feat`·`refactor`·`docs`·`chore`·`test`·`build`·`ci`·`style`·`perf`
32
+ - 제목: 갈래를 `및`·`,` 로 한 줄 병합.
33
+ - 본문 (빈 줄 후): 갈래별로 아래 블록 반복, 블록 간 빈 줄 분리.
34
+ - 헤더: `[<type>]: <갈래 요약>`.
35
+ - 변경 항목 bullet (`-`).
36
+ - `<type>`: conventional commits — `fix`·`feat`·`refactor`·`docs`·`chore`·`test`·`build`·`ci`·`style`·`perf`.
37
37
 
38
38
  ## 푸시
39
39
 
40
- - 수행 X
40
+ - 수행 X.
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: sd-config
3
- description: sd-* 스킬 사용에 필요/권장되는 프로젝트 설정을 항목별로 사용자와 확인하며 적용하는 스킬. Use when sd-* 를 쓰기 전 환경을 점검하거나 누락 항목을 채울
3
+ description: sd-* 스킬 사용에 필요/권장되는 프로젝트 설정을 항목별로 사용자와 확인하며 적용하는 스킬. Use when sd-* 를 쓰기 전 환경을 점검하거나 누락 항목을 채울 때.
4
4
  ---
5
5
 
6
- 각 항목을 차례로 점검한다. 이미 값이 있으면 변경할지 묻고, 비어 있으면 추가 여부를 묻는다. 동의하면 값을 묻거나 기본값을 제안한 뒤 파일에 기록한다. 파일이 없으면 새로 만든다.
6
+ 각 항목을 차례로 점검. 이미 값이 있으면 변경할지 묻고, 비어 있으면 추가 여부를 물음. 동의하면 값을 묻거나 기본값을 제안한 뒤 파일에 기록. 파일이 없으면 새로 만듦.
7
7
 
8
8
  - **python (필수)** — 프로젝트 루트 `mise.toml` 의 `[tools] python`.
9
- sd-* 스크립트가 python 을 사용한다. 없으면 `python = "3"` 을 추가할지 묻는다.
9
+ sd-* 스크립트가 python 을 사용함. 없으면 `python = "3"` 을 추가할지 물음.
10
10
 
11
11
  - **tmpdir (권장)** — `.claude/simplysm.json` 의 `tmpdir`.
12
- 지정 시 sd-* 임시파일이 그 폴더에 생성된다. 없으면 OS tmp 를 쓴다. 추가 여부를 묻고, 동의 시 경로를 묻는다.
12
+ 지정 시 sd-* 임시파일이 그 폴더에 생성됨. 없으면 OS tmp 를 씀. 추가 여부를 묻고, 동의 시 경로를 물음.
@@ -1,18 +1,18 @@
1
1
  ---
2
2
  name: sd-demo
3
- description: spec.md 의 화면 1개를 클라이언트 패키지의 화면 컴포넌트 자리에 인터랙티브 데모 골격으로 만든다. Use when "데모 만들기", "화면 데모", "spec 의 화면을 시각화" 를 요청할
3
+ description: spec.md 의 화면 1개를 클라이언트 패키지의 화면 컴포넌트 자리에 인터랙티브 데모 골격으로 만들기. Use when "데모 만들기", "화면 데모", "spec 의 화면을 시각화" 를 요청할 때.
4
4
  ---
5
5
 
6
6
  # sd-demo
7
7
 
8
- spec.md 화면 1개를 클라이언트 패키지의 화면 컴포넌트 자리에 데모로 만든다. 와이어프레임 상의 배치·라벨·동작 흐름이 일치하는 클릭 가능 UI. 후속 단계에서 같은 자리에 실제 로직을 채워 진화한다.
8
+ spec.md 화면 1개를 클라이언트 패키지의 화면 컴포넌트 자리에 데모로 만듦. 와이어프레임 상의 배치·라벨·동작 흐름이 일치하는 클릭 가능 UI. 후속 단계에서 같은 자리에 실제 로직을 채워 진화함.
9
9
 
10
10
  ## 본질: UI 가 1순위
11
11
 
12
- 소비자는 시연 받는 사용자. 사용자는 화면만 본다. 코드는 후속 단계가 다시 짠다.
12
+ 소비자는 시연 받는 사용자. 사용자는 화면만 봄. 코드는 후속 단계가 다시 짬.
13
13
 
14
- - **주의·시간의 90% template 쓴다.** 와이어프레임을 시각적으로 정확·정돈되게 복원하는 게 본 작업의 본질.
15
- - 코드 골격(시그널·effect·DI·핸들러)은 **코드베이스에서 분석해 따라간다** — 본 스킬은 framework 처방을 박아두지 않는다.
14
+ - **본 작업의 주력 = template 복원.** 와이어프레임을 시각적으로 정확·정돈되게.
15
+ - 코드 골격(시그널·effect·DI·핸들러)은 **코드베이스에서 분석해 따라감** — 본 스킬은 라이브러리 규약을 박아두지 않음.
16
16
  - 데이터 변경 시뮬레이션 금지. 저장·삭제 핸들러는 마커만. 클릭은 받되 결과 반영 X.
17
17
  - 모달 띄우기는 실제로 작동시켜 시연 가치 확보.
18
18
 
@@ -22,44 +22,46 @@ spec.md 화면 1개를 클라이언트 패키지의 화면 컴포넌트 자리
22
22
 
23
23
  호출에 다음 필요:
24
24
 
25
- - 대상 spec.md 경로
26
- - 만들 화면 식별자 — `[화면.X]` 또는 §4.x
27
- - 산출 위치 — 클라이언트 패키지 + 화면 폴더. client 타겟이 1개면 자동, 여러 개면 후보 제시 후 사용자 확정. **3단계-C 도메인 인접 화면이 명확히 식별되면 그 위치(같은 도메인 폴더)로 자동 채택** (1단계 초안을 인접 위치로 갱신).
25
+ - 대상 spec.md 경로.
26
+ - 만들 화면 식별자 — `[화면.X]` 또는 §4.x.
27
+ - 산출 위치 초안 — 클라이언트 패키지 + 화면 폴더. client 타겟이 1개면 자동, 여러 개면 후보 제시 후 사용자 확정. (3단계-C 끝에서 도메인 인접 결과로 갱신)
28
28
 
29
29
  없으면 묻기. spec.md 에 식별자 매칭이 안 되면 §4 화면 목록 표에서 후보 제시 후 확정.
30
30
 
31
- **[gate] 3단계 A (라이브러리 문서) 진입 전엔 3단계 이후 출력 금지**
32
-
33
- - 3단계 진입 시 A 부터 Read (B·C 보다 먼저).
34
- - 스킵 안티패턴 — "참고 코드 부재" 신호 (빈 패키지·답습 화면 없음·client 타겟 비어있음 등) 로 A 건너뛰고 B(본체 소스 grep)·C(부위별 수집) 점프
35
- - A 미진입 → 3단계 이후 모든 출력 보류
31
+ **충돌 확인**: 대상 화면(또는 동반 모달 §4.x) 파일이 이미 있으면 묻기 ① 덮어쓰기 / ② spec 변경분만 보강 / ③ 취소. 호출자 발화에 명시 분기가 있으면 묻지 않고 그 분기로 진행.
36
32
 
37
33
  ### 2단계: spec §4.x 분석
38
34
 
39
35
  §4.x 에서 추출:
40
36
 
41
- - 헤더 인덱스(Actor · 관련 섹션 · 장치)
42
- - 기능 개요 · 와이어프레임 · 항목표 · 동작 · 도메인 규칙(해당 시)
43
- - §동작에 등장하는 모달 호출 `→ [화면.Y] 을 모달로 띄움` 모두 수집
37
+ - 헤더 인덱스(Actor · 관련 섹션 · 장치).
38
+ - 기능 개요 · 와이어프레임 · 항목표 · 동작 · 도메인 규칙(해당 시).
39
+ - §동작에 등장하는 모달 호출 `→ [화면.Y] 을 모달로 띄움` 모두 수집.
44
40
 
45
41
  ### 3단계: 분석 자료 확보
46
42
 
47
- 산출물을 만들기 전, 다음을 분석해 framework 처방을 확보한다.
43
+ **[gate] 3단계 A (라이브러리 문서) 진입 전엔 3단계 이후 출력 금지**.
44
+
45
+ - 3단계 진입 시 A 부터 Read (B·C 보다 먼저).
46
+ - 스킵 안티패턴 — "참고 코드 부재" 신호 (빈 패키지·답습 화면 없음·client 타겟 비어있음 등) 로 A 건너뛰고 B(본체 소스 grep)·C(부위별 수집) 점프.
47
+ - A 미진입 → 3단계 이후 모든 출력 보류.
48
+
49
+ 산출물을 만들기 전, 다음을 분석해 라이브러리 규약을 확보함.
48
50
 
49
51
  **A. 라이브러리 문서**
50
52
 
51
- 코드베이스에 권위 규약/매뉴얼 문서가 있으면 1순위로 따른다.
53
+ 코드베이스에 권위 규약/매뉴얼 문서가 있으면 1순위로 따름.
52
54
 
53
55
  - `@simplysm/*` 14.x 사용 시 — [.claude/references/sd-simplysm14/README.md](../../references/sd-simplysm14/README.md) Read 후 "개발 매뉴얼" 항목 진입. 클라이언트 화면은 `client-component.md`, 화면 컨트롤은 `client-tab.md` 등.
54
56
  - 그 외 framework 는 코드베이스 안의 동등 위치 문서를 찾아 Read.
55
57
 
56
58
  **B. 라이브러리 컴포넌트 소스**
57
59
 
58
- 쓰려는 컴포넌트(예: `sd-form`, `sd-crud-list`)가 있으면 **본체 소스를 직접 Read** 해 input/output·동작을 정확히 파악. 사용처 grep 만으로는 누락된 prop 을 놓친다.
60
+ 쓰려는 컴포넌트(예: `sd-form`, `sd-crud-list`)가 있으면 **본체 소스를 직접 Read** 해 input/output·동작을 정확히 파악. 사용처 grep 만으로는 누락된 prop 을 놓침.
59
61
 
60
62
  **C. 부위별 패턴 레퍼런스 수집**
61
63
 
62
- 코드베이스의 클라이언트 화면 전반에서 **부위(부분)별로 공통 패턴**을 수집한다. "구성 똑같은 화면 1개를 골라 통째 답습" 모델이 아니다. 일치 화면이 있어도, 부위별 종합 결과 위에 추가로 얹는다.
64
+ 코드베이스의 클라이언트 화면 전반에서 **부위(부분)별로 공통 패턴**을 수집함. "구성 똑같은 화면 1개를 골라 통째 답습" 모델이 아님. 일치 화면이 있어도, 부위별 종합 결과 위에 추가로 얹음.
63
65
 
64
66
  **수집 대상 부위** (대상 화면이 사용하는 것만 골라 수집):
65
67
 
@@ -73,7 +75,6 @@ spec.md 화면 1개를 클라이언트 패키지의 화면 컴포넌트 자리
73
75
  | 폼 | 필드 그리드·라벨/입력 배치·필수 표시·버튼 푸터 |
74
76
  | 모달 | 헤더·본문·푸터·확인/취소 버튼·크기 |
75
77
  | 빈 상태 | 아이콘·여백·문구 |
76
- | 도메인 위치 | 같은 sub-app·같은 도메인 폴더 후보(산출 위치 자동 채택용) |
77
78
 
78
79
  **절차**:
79
80
 
@@ -82,26 +83,19 @@ spec.md 화면 1개를 클라이언트 패키지의 화면 컴포넌트 자리
82
83
  3. 부위별 공통 패턴(자주 쓰는 슬롯·클래스·요소 구조) 메모화. 1회만 쓰인 변종은 채택 후보에서 배제, 다수에서 반복되는 것을 채택.
83
84
  4. 부위별 패턴이 화면마다 갈라지면 (예: 리스트가 테이블·카드 두 갈래) 대상 화면의 와이어프레임이 어느 쪽인지로 선택.
84
85
 
85
- **도메인 인접 후보**: 같은 sub-app·같은 도메인 폴더에 화면이 1개 이상 있으면 그 폴더를 산출 위치 자동 채택 근거로 쓴다. 0개면 라우팅·메뉴 등록 위치를 사용자에게 1회 질문.
86
-
87
- LLM 단독 판단 한계: 동일 구성 화면이 한 곳도 없다고 framework 처방만으로 그리면 안 된다. **반드시 부위별로 수집한 패턴을 근거로** 그려야 한다. 부위별 후보가 0개인 부위가 있으면 그 부위만 사용자에게 1회 질문 (그 화면의 그 부위 어떻게 처리할지).
88
-
89
- ### 4단계: 충돌 확인
90
-
91
- 대상 화면(또는 동반 모달 §4.x) 파일이 이미 있으면 묻기:
92
-
93
- - ① 덮어쓰기 / ② spec 변경분만 보강 / ③ 취소
86
+ **도메인 인접 후보 → 산출 위치 확정**: 같은 sub-app·같은 도메인 폴더에 화면이 1개 이상 있으면 그 폴더로 1단계 산출 위치 초안 갱신 (자동 채택). 0개면 라우팅·메뉴 등록 위치를 사용자에게 1회 질문.
94
87
 
95
- 호출자 발화에 명시 분기가 있으면 묻지 않고분기로 진행.
88
+ LLM 단독 판단 한계: 동일 구성 화면이 한 곳도 없다고 라이브러리 규약만으로 그리면 안 됨. **반드시 부위별로 수집한 패턴을 근거로** 그려야 함. 부위별 후보가 0개인 부위가 있으면 부위만 사용자에게 1회 질문 (화면의 그 부위 어떻게 처리할지).
96
89
 
97
- ### 5단계: 생성
90
+ ### 4단계: 생성
98
91
 
99
- 3단계 분석 자료(A/B/C)를 1순위 근거로, **template 부터** 채운다.
92
+ 3단계 분석 자료(A/B/C)를 1순위 근거로, **template 부터** 채움.
100
93
 
101
94
  - 파일명·selector·시그널·DI 명명 등은 라이브러리 문서(A) 가 정한 형식 그대로.
102
- - 슬롯·영역 분할·클래스 패턴은 3단계-C 부위별 패턴 채택분 그대로. 부위별로 다른 화면을 참조했더라도 각 부위 채택분을 그대로 옮긴다.
103
- - 부위별 채택분이 코드베이스 어느 화면에서 왔는지 출처를 머릿속에 두고 비교 가능 상태로 유지(6단계 점검용).
104
- - 모달 호출 화면이면 동반 모달 §4.x 도 같은 단계로 생성.
95
+ - 슬롯·영역 분할·클래스 패턴은 3단계-C 부위별 패턴 채택분 그대로. 부위별로 다른 화면을 참조했더라도 각 부위 채택분을 그대로 옮김.
96
+ - 부위별 채택분의 출처(레퍼런스 화면 파일 경로)를 메모해 5단계 점검 입력으로 사용.
97
+ - 모달 호출 화면이면 동반 모달 §4.x 도 같은 단계로 생성. 모달 띄우기는 실제 작동시켜 시연 가치 확보.
98
+ - 저장·삭제 등 데이터 변경 핸들러는 마커(`// sd-demo: 미구현 — 동작 자리`)만. 클릭은 받되 결과 반영 X.
105
99
 
106
100
  **표식 마커 (고정)**
107
101
 
@@ -110,31 +104,29 @@ LLM 단독 판단 한계: 동일 구성 화면이 한 곳도 없다고 framework
110
104
  | 더미 데이터 선언 위 | `// sd-demo: 더미 — 구현 단계에서 교체` |
111
105
  | 미구현 핸들러 본문 | `// sd-demo: 미구현 — 동작 자리` |
112
106
  | 더미 타입 인라인 선언 위 | `// sd-demo: 더미 타입 — 구현 단계에서 @모델/X 로 교체` |
113
- | 종류 매핑 임의 추정 | `// sd-demo: 종류 매핑 임의 — 확인 필요` |
114
- | 권한 path 임의 추정 | `// sd-demo: 권한 path 임의 — 확인 필요` |
107
+ | 임의 추정값 선언/사용 | `// sd-demo: 임의 추정값 — 확인 필요` |
115
108
 
116
- 다른 변형 사용 금지. 후속 단계가 grep 으로 추적한다.
109
+ 다른 변형 사용 금지. 후속 단계가 grep 으로 추적함.
117
110
 
118
- ### 6단계: 자체 점검
111
+ ### 5단계: 자체 점검
119
112
 
120
113
  **패스 1: 부위별 패턴 일치** — 3단계-C 에서 부위마다 채택한 레퍼런스 화면을 다시 Read 해 부위별로 비교:
121
114
 
122
- - 헤더/툴바: 도구 버튼 배치·라벨 형식·간격·클래스 동일
123
- - 영역 분할: split/탭/sheet/dock 사용 동일
124
- - 리스트: 헤더 셀·행 셀 마크업·정렬/선택 슬롯 동일
125
- - 폼: 필드 그리드·라벨/입력 배치·푸터 버튼 동일
126
- - 모달: 헤더·본문·푸터 구조 동일
127
- - 빈 상태: 아이콘·여백·문구 동일
115
+ - 헤더/툴바: 도구 버튼 배치·라벨 형식·간격·클래스 동일.
116
+ - 영역 분할: split/탭/sheet/dock 사용 동일.
117
+ - 리스트: 헤더 셀·행 셀 마크업·정렬/선택 슬롯 동일.
118
+ - 폼: 필드 그리드·라벨/입력 배치·푸터 버튼 동일.
119
+ - 모달: 헤더·본문·푸터 구조 동일.
120
+ - 빈 상태: 아이콘·여백·문구 동일.
128
121
 
129
122
  부위 중 한 곳이라도 채택 패턴과 어긋나면(임의 변형·새 클래스 발명·새 슬롯 사용) 수정. "비슷한 화면이 없어서 알아서 그렸다"는 자기 합리화 금지 — 그 부위 채택분이 비어 있다는 뜻이므로 3단계-C 로 돌아가 수집·재선택.
130
123
 
131
124
  **패스 2: 라이브러리 문서 위배 점검** — 3단계-A 의 매뉴얼 문서 항목별 일치 확인. 위배 항목이 있으면 수정 후 재점검.
132
125
 
133
- ### 7단계: 완료 보고
126
+ ### 6단계: 완료 보고
134
127
 
135
128
  만든 파일 목록 보고 후 종료.
136
129
 
137
130
  ## 운용
138
131
 
139
132
  - 결정 근거: `sd-base-rules.md` "결정 근거" 적용.
140
- - 본 스킬은 framework 처방을 박아두지 않는다. 매 호출 시 3단계에서 분석한 라이브러리 문서·컴포넌트 소스·답습 화면을 근거로 산출.
@@ -0,0 +1,99 @@
1
+ # 재고 관리 요구 분석서
2
+
3
+ ## 1. 개요
4
+
5
+ ### 1.1 핵심 목적 [확정: 2026-05-26]
6
+
7
+ 창고별 품목 재고 현황 조회 시스템
8
+
9
+ ### 1.2 주요 목표 [확정: 2026-05-26]
10
+
11
+ - 창고별·품목별 재고 현황 조회
12
+
13
+ ### 1.3 최종 사용자/이해관계자 [확정: 2026-05-26]
14
+
15
+ - 창고 관리자: PC 로 재고 현황 조회
16
+
17
+ ### 1.4 환경/장치 [확정: 2026-05-26]
18
+
19
+ ```
20
+ ┌─────────┐
21
+ │ PC │
22
+ └────┬────┘
23
+
24
+
25
+ ┌──────────┐
26
+ │ WMS 서버 │
27
+ └──────────┘
28
+ ```
29
+
30
+ - PC — 창고 관리자가 재고 화면 조회에 사용
31
+ - OS: Windows 11
32
+ - Browser: Chrome 최신
33
+ - 해상도: 1920 x 1080
34
+
35
+ ## 4. 화면
36
+
37
+ | § | 분류 | 화면 | 유형 | 장치 |
38
+ | --- | ---- | --------- | ---- | ---- |
39
+ | 4.1 | 재고 | 재고 조회 | 조회 | PC |
40
+
41
+ ### 4.1 재고 조회 (PC) [확정: 2026-05-26]
42
+
43
+ Actor: 창고 관리자
44
+ 관련 섹션: [모델.재고]
45
+
46
+ 기능 개요:
47
+
48
+ - 창고별·품목별 재고 현황 조회
49
+
50
+ #### 와이어프레임
51
+
52
+ ```
53
+ ┌────────────────────────────────────────────────────────────────────┐
54
+ │ 재고 조회 │
55
+ │ [조회] <필터> │
56
+ ├────────────────────────────────────────────────────────────────────┤
57
+ │ <재고 목록 시트> │
58
+ └────────────────────────────────────────────────────────────────────┘
59
+ ```
60
+
61
+ #### 항목
62
+
63
+ **필터**
64
+
65
+ | 항목 | 종류 | 필수 | 비고 |
66
+ | --------- | --------- | ---- | ------------------------ |
67
+ | 창고 | 정적 선택 | X | 전체·창고 목록 |
68
+ | 품목 검색 | 텍스트 | X | 코드 또는 명칭 부분 일치 |
69
+
70
+ **재고 목록 시트**
71
+
72
+ | 컬럼 | 종류 | 필수 | 도메인 매핑 | 비고 |
73
+ | ------ | ---- | ---- | -------------------- | --------- |
74
+ | 창고 | 문자 | - | [모델.재고.창고] | |
75
+ | 품목 | 문자 | - | [모델.재고.품목명] | |
76
+ | 재고량 | 숫자 | - | [모델.재고.수량] | 우측 정렬 |
77
+ | 갱신일 | 날짜 | - | [모델.재고.갱신일] | |
78
+
79
+ #### 동작
80
+
81
+ - `[조회]` 클릭: 검색 필터 조건으로 목록 갱신
82
+
83
+ #### 빈 상태
84
+
85
+ - 검색 결과 없음: "조회된 재고가 없습니다." 표시
86
+
87
+ ## 8. 도메인 모델
88
+
89
+ ### 8.1 재고 [확정: 2026-05-26]
90
+
91
+ 필드:
92
+
93
+ | 필드 | 타입 | 필수 | 비고 |
94
+ | ------ | ---- | ---- | ---------------- |
95
+ | ID | 숫자 | O | 자동 부여 |
96
+ | 창고 | 문자 | O | 창고명 |
97
+ | 품목명 | 문자 | O | 품목명 |
98
+ | 수량 | 숫자 | O | 재고 수량 |
99
+ | 갱신일 | 날짜 | O | 마지막 갱신 일자 |
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "@demo/client",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "dependencies": {
7
+ "@angular/core": "^21.0.0",
8
+ "@ng-icons/core": "^32.0.0",
9
+ "@ng-icons/tabler-icons": "^32.0.0",
10
+ "@simplysm/angular": "^14.0.0"
11
+ }
12
+ }
@@ -0,0 +1,3 @@
1
+ export { InventoryMasterListComponent } from "./screens/inventory/inventory-master.list";
2
+ export { OutboundListComponent } from "./screens/outbound/outbound.list";
3
+ export { InboundListComponent } from "./screens/inbound/inbound.list";
@@ -0,0 +1,150 @@
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ ViewEncapsulation,
5
+ effect,
6
+ inject,
7
+ signal,
8
+ untracked,
9
+ } from "@angular/core";
10
+ import {
11
+ injectPermsSignal,
12
+ mark,
13
+ SdCrudListComponent,
14
+ SdSheetColumnDirective,
15
+ SdTextfieldComponent,
16
+ SdToastProvider,
17
+ } from "@simplysm/angular";
18
+
19
+ interface IInboundItem {
20
+ id: number;
21
+ receiptNo: string;
22
+ supplierName: string;
23
+ itemName: string;
24
+ quantity: number;
25
+ receivedAt: string;
26
+ }
27
+
28
+ interface IFilter {
29
+ searchText: string;
30
+ }
31
+
32
+ @Component({
33
+ selector: "app-inbound-list",
34
+ changeDetection: ChangeDetectionStrategy.OnPush,
35
+ encapsulation: ViewEncapsulation.None,
36
+ standalone: true,
37
+ imports: [SdCrudListComponent, SdSheetColumnDirective, SdTextfieldComponent],
38
+ template: `
39
+ <div class="flex-column fill">
40
+ <sd-crud-list
41
+ title="입고 내역 조회"
42
+ [(ready)]="ready"
43
+ [initialized]="initialized()"
44
+ [(busyCount)]="busyCount"
45
+ [items]="items()"
46
+ [(selectedKeys)]="selectedKeys"
47
+ [(page)]="page"
48
+ [totalPageCount]="pageLength()"
49
+ [(sorts)]="sortingDefs"
50
+ [trackByFn]="trackByFn"
51
+ [restricted]="!perms().includes('use')"
52
+ (filterSubmit)="onFilterSubmit()"
53
+ >
54
+ <ng-template #filterTpl>
55
+ <div class="form-box-inline">
56
+ <div>
57
+ <label>검색</label>
58
+ <sd-textfield [(value)]="filter().searchText" (valueChange)="mark(filter)" />
59
+ </div>
60
+ </div>
61
+ </ng-template>
62
+
63
+ <sd-sheet-column [key]="'receiptNo'" [header]="'입고 번호'">
64
+ <ng-template [cell]="items()" let-item="item">
65
+ <div class="p-xs-sm">{{ item.receiptNo }}</div>
66
+ </ng-template>
67
+ </sd-sheet-column>
68
+
69
+ <sd-sheet-column [key]="'supplierName'" [header]="'공급처'">
70
+ <ng-template [cell]="items()" let-item="item">
71
+ <div class="p-xs-sm">{{ item.supplierName }}</div>
72
+ </ng-template>
73
+ </sd-sheet-column>
74
+
75
+ <sd-sheet-column [key]="'itemName'" [header]="'품목'">
76
+ <ng-template [cell]="items()" let-item="item">
77
+ <div class="p-xs-sm">{{ item.itemName }}</div>
78
+ </ng-template>
79
+ </sd-sheet-column>
80
+
81
+ <sd-sheet-column [key]="'quantity'" [header]="'수량'">
82
+ <ng-template [cell]="items()" let-item="item">
83
+ <div class="p-xs-sm tx-right">{{ item.quantity }}</div>
84
+ </ng-template>
85
+ </sd-sheet-column>
86
+ </sd-crud-list>
87
+
88
+ @if (initialized() && items().length === 0) {
89
+ <div class="p-default tx-center tx-theme-gray-default">조회된 입고 내역이 없습니다.</div>
90
+ }
91
+ </div>
92
+ `,
93
+ })
94
+ export class InboundListComponent {
95
+ private readonly _sdToast = inject(SdToastProvider);
96
+
97
+ perms = injectPermsSignal(["inbound"], ["use"]);
98
+
99
+ ready = signal(false);
100
+ initialized = signal(false);
101
+ busyCount = signal(0);
102
+
103
+ items = signal<IInboundItem[]>([]);
104
+ selectedKeys = signal<number[]>([]);
105
+ page = signal(0);
106
+ pageLength = signal(0);
107
+ sortingDefs = signal<{ key: string; desc: boolean }[]>([]);
108
+
109
+ filter = signal<IFilter>({ searchText: "" });
110
+ lastFilter = signal<IFilter>({ searchText: "" });
111
+
112
+ trackByFn = (item: IInboundItem) => item.id;
113
+
114
+ protected readonly mark = mark;
115
+
116
+ constructor() {
117
+ effect(() => {
118
+ if (!this.perms().includes("use") || !this.ready()) {
119
+ this.initialized.set(true);
120
+ return;
121
+ }
122
+
123
+ this.lastFilter();
124
+ this.page();
125
+ this.sortingDefs();
126
+
127
+ void untracked(async () => {
128
+ this.busyCount.update((v) => v + 1);
129
+ await this._sdToast.try(async () => {
130
+ await this._refresh();
131
+ });
132
+ this.busyCount.update((v) => v - 1);
133
+ this.initialized.set(true);
134
+ });
135
+ });
136
+ }
137
+
138
+ onFilterSubmit(): void {
139
+ this.page.set(0);
140
+ this.lastFilter.set({ ...this.filter() });
141
+ }
142
+
143
+ doRefresh(): void {
144
+ if (!this.perms().includes("use")) return;
145
+ mark(this.lastFilter);
146
+ }
147
+
148
+ private async _refresh(): Promise<void> {
149
+ }
150
+ }