@simplysm/sd-claude 14.0.81 → 14.0.83

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 (87) hide show
  1. package/claude/references/sd-requirement-source-handling.md +20 -20
  2. package/claude/references/sd-simplysm14/README.md +13 -13
  3. package/claude/references/sd-simplysm14/manuals/client-component.md +92 -92
  4. package/claude/references/sd-simplysm14/manuals/client-crud.md +11 -11
  5. package/claude/references/sd-simplysm14/manuals/client-demo.md +28 -28
  6. package/claude/references/sd-simplysm14/manuals/client-rules.md +1 -1
  7. package/claude/references/sd-simplysm14/manuals/client-setup.md +21 -21
  8. package/claude/references/sd-simplysm14/manuals/client-tab.md +3 -3
  9. package/claude/references/sd-simplysm14/manuals/logging.md +15 -15
  10. package/claude/references/sd-simplysm14/manuals/orm-union.md +6 -6
  11. package/claude/references/sd-simplysm14/manuals/orm.md +19 -19
  12. package/claude/references/sd-simplysm14/manuals/test.md +33 -33
  13. package/claude/rules/sd-base-rules.md +44 -43
  14. package/claude/rules/sd-design-rules.md +18 -18
  15. package/claude/skills/sd-commit/SKILL.md +10 -10
  16. package/claude/skills/sd-config/SKILL.md +2 -2
  17. package/claude/skills/sd-demo/SKILL.md +45 -45
  18. package/claude/skills/sd-dev/SKILL.md +15 -15
  19. package/claude/skills/sd-docs/SKILL.md +7 -7
  20. package/claude/skills/sd-docs/references/subagent-prompt.md +33 -33
  21. package/claude/skills/sd-impl/SKILL.md +60 -60
  22. package/claude/skills/sd-review/SKILL.md +9 -9
  23. package/claude/skills/sd-skill/SKILL.md +74 -74
  24. package/claude/skills/sd-skill/evals/fixtures/existing-skill/.claude/skills/todo-format/SKILL.md +1 -1
  25. package/claude/skills/sd-spec/SKILL.md +355 -319
  26. package/claude/skills/sd-spec/references/example-spec.md +104 -104
  27. package/claude/skills/sd-unpack/SKILL.md +34 -34
  28. package/claude/skills/sd-use/SKILL.md +4 -4
  29. package/package.json +1 -1
  30. package/claude/references/sd-simplysm14/apis/angular/README.md +0 -37
  31. package/claude/references/sd-simplysm14/apis/angular/app-structure.md +0 -92
  32. package/claude/references/sd-simplysm14/apis/angular/buttons.md +0 -88
  33. package/claude/references/sd-simplysm14/apis/angular/crud.md +0 -100
  34. package/claude/references/sd-simplysm14/apis/angular/forms.md +0 -200
  35. package/claude/references/sd-simplysm14/apis/angular/infrastructure.md +0 -231
  36. package/claude/references/sd-simplysm14/apis/angular/kanban.md +0 -80
  37. package/claude/references/sd-simplysm14/apis/angular/layout.md +0 -92
  38. package/claude/references/sd-simplysm14/apis/angular/modal.md +0 -115
  39. package/claude/references/sd-simplysm14/apis/angular/routing.md +0 -107
  40. package/claude/references/sd-simplysm14/apis/angular/select-dropdown.md +0 -35
  41. package/claude/references/sd-simplysm14/apis/angular/selection-managers.md +0 -82
  42. package/claude/references/sd-simplysm14/apis/angular/shared-data.md +0 -134
  43. package/claude/references/sd-simplysm14/apis/angular/sheet.md +0 -127
  44. package/claude/references/sd-simplysm14/apis/angular/toast.md +0 -97
  45. package/claude/references/sd-simplysm14/apis/angular/visual.md +0 -167
  46. package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +0 -79
  47. package/claude/references/sd-simplysm14/apis/capacitor-plugin-file-system/README.md +0 -83
  48. package/claude/references/sd-simplysm14/apis/capacitor-plugin-intent/README.md +0 -91
  49. package/claude/references/sd-simplysm14/apis/capacitor-plugin-usb-storage/README.md +0 -49
  50. package/claude/references/sd-simplysm14/apis/core-browser/README.md +0 -143
  51. package/claude/references/sd-simplysm14/apis/core-common/README.md +0 -58
  52. package/claude/references/sd-simplysm14/apis/core-common/extensions.md +0 -88
  53. package/claude/references/sd-simplysm14/apis/core-common/features.md +0 -51
  54. package/claude/references/sd-simplysm14/apis/core-common/types.md +0 -88
  55. package/claude/references/sd-simplysm14/apis/core-common/utils.md +0 -189
  56. package/claude/references/sd-simplysm14/apis/core-node/README.md +0 -12
  57. package/claude/references/sd-simplysm14/apis/core-node/consola.md +0 -59
  58. package/claude/references/sd-simplysm14/apis/core-node/cpx.md +0 -44
  59. package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +0 -42
  60. package/claude/references/sd-simplysm14/apis/core-node/fsx.md +0 -53
  61. package/claude/references/sd-simplysm14/apis/core-node/pathx.md +0 -24
  62. package/claude/references/sd-simplysm14/apis/core-node/worker.md +0 -65
  63. package/claude/references/sd-simplysm14/apis/excel/README.md +0 -193
  64. package/claude/references/sd-simplysm14/apis/lint/README.md +0 -94
  65. package/claude/references/sd-simplysm14/apis/orm-common/README.md +0 -58
  66. package/claude/references/sd-simplysm14/apis/orm-common/db-context.md +0 -77
  67. package/claude/references/sd-simplysm14/apis/orm-common/executable.md +0 -20
  68. package/claude/references/sd-simplysm14/apis/orm-common/expr.md +0 -92
  69. package/claude/references/sd-simplysm14/apis/orm-common/queryable.md +0 -98
  70. package/claude/references/sd-simplysm14/apis/orm-common/schema-builders.md +0 -128
  71. package/claude/references/sd-simplysm14/apis/orm-node/README.md +0 -69
  72. package/claude/references/sd-simplysm14/apis/sd-claude/README.md +0 -32
  73. package/claude/references/sd-simplysm14/apis/sd-cli/README.md +0 -80
  74. package/claude/references/sd-simplysm14/apis/sd-cli/sd-config.md +0 -155
  75. package/claude/references/sd-simplysm14/apis/service-client/README.md +0 -131
  76. package/claude/references/sd-simplysm14/apis/service-common/README.md +0 -29
  77. package/claude/references/sd-simplysm14/apis/service-common/app-structure.md +0 -63
  78. package/claude/references/sd-simplysm14/apis/service-common/messages.md +0 -56
  79. package/claude/references/sd-simplysm14/apis/service-common/protocol.md +0 -64
  80. package/claude/references/sd-simplysm14/apis/service-common/service-types.md +0 -43
  81. package/claude/references/sd-simplysm14/apis/service-server/README.md +0 -13
  82. package/claude/references/sd-simplysm14/apis/service-server/auth.md +0 -39
  83. package/claude/references/sd-simplysm14/apis/service-server/builtin-services.md +0 -71
  84. package/claude/references/sd-simplysm14/apis/service-server/define-service.md +0 -55
  85. package/claude/references/sd-simplysm14/apis/service-server/internals.md +0 -82
  86. package/claude/references/sd-simplysm14/apis/service-server/server.md +0 -57
  87. package/claude/references/sd-simplysm14/apis/storage/README.md +0 -71
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: sd-unpack
3
- description: 메일·문서(eml/msg/pdf/docx/pptx/xlsx/xlsb, 레거시 doc/ppt/xls)를 첨부 포함 재귀적으로 풀어 평문 트리로 펼치기. Use when 위 형식 파일의 본문·첨부 전반을 훑어야 할 때 (분석·요약·정리·검토 등). 단순 단답 조회(특정 값/셀 확인)나 옆에 이미 펼친 `<basename>_<ext>/` 폴더가 있으면 호출 X.
3
+ description: 메일·문서(eml/msg/pdf/docx/pptx/xlsx/xlsb, 레거시 doc/ppt/xls)를 첨부 포함 재귀적으로 풀어 평문 트리로 펼치기. Use when 위 형식 파일의 본문·첨부 전반을 훑어야 할 때 (분석·요약·정리·검토 등). 단순 단답 조회(특정 값/셀 확인)나 옆에 이미 펼친 `<basename>_<ext>/` 폴더가 있으면 호출 금지.
4
4
 
5
5
  ---
6
6
 
@@ -12,21 +12,21 @@ description: 메일·문서(eml/msg/pdf/docx/pptx/xlsx/xlsb, 레거시 doc/ppt/x
12
12
  python .claude/skills/sd-unpack/scripts/unpack.py <입력파일 절대경로>
13
13
  ```
14
14
 
15
- 스크립트가 형식 분기·재귀 풀이·README 생성까지 알아서 처리함. stdout 으로 결과 폴더 절대경로가 출력됨.
15
+ 스크립트가 형식 분기·재귀 풀이·README 생성까지 처리. stdout 으로 결과 폴더 절대경로 출력.
16
16
 
17
- 여러 파일을 풀어달라는 요청이 오면 단일 파일 단위로 반복 호출함.
17
+ 여러 파일을 풀어달라는 요청이 오면 단일 파일 단위로 반복 호출.
18
18
 
19
19
  ## 환경
20
20
 
21
- Windows + MS Office 필요 (docx/pptx/xlsx 변환). Python 패키지 의존은 `ensure_pip` 가 자동 처리. COM 의존 미충족 시 해당 형식 핸들러는 throw.
21
+ Windows + MS Office 필요 (docx/pptx/xlsx 변환용). Python 패키지 의존은 `ensure_pip` 가 자동 처리. COM(Component Object Model) 의존 미충족 시 해당 형식 핸들러는 throw.
22
22
 
23
23
  ## 결과 폴더
24
24
 
25
- 입력 파일 옆에 `<basename>_<ext>/` 생김. 컨테이너 첨부는 같은 패턴으로 재귀적으로 풀림. 폴더 안 `_source.<ext>` + `README.md` 가 풀린 폴더의 식별 마커.
25
+ 입력 파일 옆에 `<basename>_<ext>/` 폴더 생성. 컨테이너 첨부는 같은 패턴으로 재귀적으로 풀림. 폴더 안 `_source.<ext>` + `README.md` 가 풀린 폴더의 식별 마커.
26
26
 
27
- 동일 입력 재호출 시 기존 결과 폴더는 사전 삭제 후 재생성 (이전 산출 잔존물 섞이지 않게).
27
+ 동일 입력 재호출 시 기존 결과 폴더는 사전 삭제 후 재생성 (이전 산출 잔존물이 섞이지 않게).
28
28
 
29
- 시각은 PNG, 텍스트/구조는 JSONL/JSON/MD 로 분리해 출력함.
29
+ 시각은 PNG, 텍스트·구조는 JSONL/JSON/MD 로 분리 출력.
30
30
 
31
31
  ```
32
32
  meeting_eml/
@@ -65,23 +65,23 @@ meeting_eml/
65
65
  | pdf | `pages/<NNN>.png` | `pages/<NNN>.jsonl` (블록 bbox + 표 셀 단위) | `images/p<NNN>_b<bid>.<ext>`, `attachments/` (PDF 임베드) |
66
66
  | eml/msg | — | `body.md` (평문 본문), `headers.json`, `images.rels.json` | `body.html` (원본), `attachments/` (컨테이너면 재귀) |
67
67
 
68
- `attachments/` 안 컨테이너 첨부는 같은 패턴으로 `<basename>_<ext>/` 폴더로 재귀 풀이.
68
+ `attachments/` 안 컨테이너 첨부는 같은 패턴의 `<basename>_<ext>/` 폴더로 재귀 풀이.
69
69
 
70
70
  ## JSONL 공통 규약
71
71
 
72
72
  모든 jsonl 출력은 **한 줄 = 한 노드 (또는 한 행/셀)**. 빈 키 생략. JSON 네이티브 타입 보존. datetime → ISO 8601 문자열.
73
73
 
74
74
  조회 패턴:
75
- - 좌표·인덱스 직격 grep (`"r":11`·`"slide":5`·`"node":42`).
75
+ - 좌표·인덱스로 직접 grep (`"r":11`·`"slide":5`·`"node":42`).
76
76
  - 키 grep (`"type":"heading"`·`"_f"` 수식 행만).
77
77
  - Read offset = 행/노드 인덱스 1:1 (빈 노드도 한 줄 유지).
78
78
 
79
79
  ## xlsx jsonl 규약
80
80
 
81
- 시트별 `.jsonl` — 분석 핵심 (값·number_format·수식·merges·hyperlinks·comments). 시각 표시 (바탕색·border·폰트)·frozen·dims 는 미보존 (PNG 가 시각 보조, 필요 시 `_source.xlsx` 직접 추출).
81
+ 시트별 `.jsonl` — 분석 핵심 (값·number_format·수식·merges·hyperlinks·comments) 보존. 시각 표시 (바탕색·border·폰트)·frozen·dims 는 미보존 (PNG 가 시각 보조 역할, 필요 시 `_source.xlsx` 직접 추출).
82
82
 
83
83
  - 첫 줄: `{"_meta":{"merges":["A1:C1",...], "number_formats":{"E1":"yyyy-mm-dd",...}, "hyperlinks":{"D5":"http://..."}, "comments":{"E3":"메모"}}}`.
84
- - `merges`: 머지된 셀 영역 (셀 좌표 해석에 필수 — 머지 영역 안 빈 셀 오해 차단).
84
+ - `merges`: 머지된 셀 영역 (셀 좌표 해석에 필수 — 머지 영역 안 빈 셀 오해 방지).
85
85
  - `number_formats`: General(기본) 외 셀 표시 형식 — Date·통화·% 등 셀 값 의미 단서.
86
86
  - `hyperlinks`: 셀 URL (URL 자체가 셀 정보).
87
87
  - `comments`: 셀 메모.
@@ -90,17 +90,17 @@ meeting_eml/
90
90
  - `r`: 1-based 행번호 (Excel 동일).
91
91
  - 열문자 키 (`A`·`B`·...·`AA`·...): 셀 값. 빈 셀은 키 생략.
92
92
  - `_f`: 같은 행 수식 맵 `{열문자: 수식문자열}`. 수식 없는 행은 키 생략.
93
- - 빈 행도 `{"r":N}` 한 줄 유지 → Read offset = 행번호 (오프바이원 차단).
93
+ - 빈 행도 `{"r":N}` 한 줄 유지 → Read offset = 행번호 (오프바이원 방지).
94
94
  - 값 타입: JSON 네이티브 (`int`·`float`·`bool`·`str`), datetime 은 ISO 8601 문자열.
95
95
 
96
96
  ### Chartsheet (시트 자체가 차트)
97
97
 
98
- xlsx 안 시트는 일반 Worksheet 외에 **Chartsheet** (셀 없이 차트 1) 도 있을 수 있음.
98
+ xlsx 안 시트는 일반 Worksheet 외에 **Chartsheet** (셀 없이 차트 1개만 있는 시트) 도 있을 수 있음.
99
99
 
100
100
  - Chartsheet 는 `sheets/<idx>_<name>.jsonl` 미생성 (셀 없음).
101
101
  - Chartsheet 의 차트 데이터: `charts/sheet<idx>_chart.data.json`.
102
- - README sheet_summaries `(chart sheet — "...")` 명시.
103
- - 일반 시트·Chartsheet 통합 시트 순서 (idx) 대로 보존.
102
+ - README sheet_summaries 항목에 `(chart sheet — "...")` 명시.
103
+ - 일반 시트·Chartsheet 통합한 시트 순서 (idx) 대로 보존.
104
104
 
105
105
  ### 워크북 단위 `workbook.meta.json`
106
106
 
@@ -112,7 +112,7 @@ xlsx 안 시트는 일반 Worksheet 외에 **Chartsheet** (셀 없이 차트 1
112
112
 
113
113
  ## pptx jsonl 규약
114
114
 
115
- 슬라이드별 `slides/<idx>_<title>.jsonl`. 원본 XML 순서 (shape_idx 순) 그대로. 시각 순서는 `pos` 좌표 기반으로 Claude 가 필요시 정렬.
115
+ 슬라이드별 `slides/<idx>_<title>.jsonl` 생성. 원본 XML 순서 (shape_idx 순) 그대로 유지. 시각 순서는 `pos` 좌표 기반으로 Claude 가 필요시 정렬.
116
116
 
117
117
  - 첫 줄: `{"_meta":{"slide":N, "title":"슬라이드 제목 또는 빈 문자열", "size":[w,h], "shapes":S}}`.
118
118
  - `size`: 슬라이드 폭/높이 (EMU 단위, python-pptx 원본).
@@ -139,14 +139,14 @@ paragraph 안 hyperlink 가 있으면 `hyperlinks`: `[{"text":"...", "url":"..."
139
139
 
140
140
  ## docx jsonl 규약
141
141
 
142
- 문서 단일 시퀀스 `content.jsonl`. 페이지 단위 폐기 (Word 렌더 산물). 원본 = python-docx 의 문단/표/이미지 시퀀스.
142
+ 문서 단일 시퀀스 `content.jsonl` 생성. 페이지 단위는 폐기 (Word 렌더 산물이라 원본 구조와 무관). 원본 시퀀스는 python-docx 의 문단·표·이미지 시퀀스를 따름.
143
143
 
144
144
  - 첫 줄: `{"_meta":{"paragraphs":P, "tables":T, "images":I}}`.
145
145
  - 노드 줄: `{"node":N, "type":"<type>", ...추가 키}`.
146
146
  - `node`: 0-based 시퀀스 인덱스 (Read offset = node).
147
147
 
148
148
  노드 type:
149
- - `heading`: 키 `text`·`level` (1·2·3·...) — docx Heading 스타일 기반만 (휴리스틱 추정 X).
149
+ - `heading`: 키 `text`·`level` (1·2·3·...) — docx Heading 스타일 기반만 (휴리스틱 추정 금지).
150
150
  - `para`: 키 `text` (빈 paragraph 도 노드로 보존, text="").
151
151
  - `bullet`: 키 `text`·`level` (0-based ilvl).
152
152
  - `table_cell`: 키 `table_idx`·`row`·`col` (1-based)·`text`. 머지 시 `colspan` 추가 (gridSpan>1 일 때만). vMerge='continue' cell 은 skip (origin 만).
@@ -157,11 +157,11 @@ paragraph 안 hyperlink 가 있으면 `hyperlinks`: `[{"text":"...", "url":"..."
157
157
  페이지 매핑 별도 `pages.meta.json`:
158
158
  - `{"001":{"text":"<페이지 평문>"}, "002":{...}, ...}` (PNG 페이지 ↔ fitz 추출 raw text).
159
159
  - PNG 는 fitz 페이지 분할 그대로 (시각 검증용).
160
- - 노드 인덱스 자동 매핑은 미적용 (fitz·python-docx 텍스트 분할 차이로 오매핑 위험) — Claude 가 페이지 text 와 content.jsonl 노드 text 를 직접 grep 비교.
160
+ - 노드 인덱스 자동 매핑은 미적용 (fitz·python-docx 텍스트 분할 차이로 오매핑 위험) — Claude 가 페이지 text 와 content.jsonl 노드 text 를 직접 grep 비교.
161
161
 
162
162
  ## pdf jsonl 규약
163
163
 
164
- 페이지별 `pages/<NNN>.jsonl`. PDF 페이지는 원본 단위.
164
+ 페이지별 `pages/<NNN>.jsonl` 생성. PDF 페이지는 원본 단위.
165
165
 
166
166
  - 첫 줄: `{"_meta":{"page":N, "size":[w,h], "blocks":B, "tables":T, "table_cells":C, "form_fields":F, "annotations":A}}`.
167
167
  - 노드 줄:
@@ -170,7 +170,7 @@ paragraph 안 hyperlink 가 있으면 `hyperlinks`: `[{"text":"...", "url":"..."
170
170
  - `table_cell`: `{"page":N, "type":"table_cell", "table_idx":T, "table_bbox":[...], "row":R, "col":C, "text":"..."}`.
171
171
  - `form_field`: `{"page":N, "type":"form_field", "name":"...", "field_type":"text", "value":"...", "bbox":[...]}` (PDF 양식 입력란).
172
172
  - `annotation`: `{"page":N, "type":"annotation", "subtype":"Highlight", "bbox":[...], "content":"...", "author":"..."}` (주석·highlight·sticky note).
173
- - 모든 블록 보존 (표 영역과 겹쳐도 skip 안 함) — find_tables 정확도 100% 가정 시 정보 손실 위험 회피. text_block·image_block·table_cell 노드가 동일 영역에 중복 출력될 수 있음. Claude 가 양쪽 비교 판단.
173
+ - 모든 블록 보존 (표 영역과 겹쳐도 skip 안 함) — find_tables 정확도 100% 가정 시 정보 손실 위험을 회피. text_block·image_block·table_cell 노드가 동일 영역에 중복 출력될 수 있음. Claude 가 양쪽을 비교하여 판단.
174
174
  - bbox 는 PDF 기준 좌표 (left-top, pt 단위, raw float).
175
175
 
176
176
  heading 추출은 미적용 (PDF 는 style 정보 없음). OCR 미적용 (스캔 PDF 는 image_block 만 추출).
@@ -179,41 +179,41 @@ heading 추출은 미적용 (PDF 는 style 정보 없음). OCR 미적용 (스캔
179
179
 
180
180
  본문 안 `<img cid:...>` 가 첨부의 어느 파일인지 추적.
181
181
 
182
- - `images.rels.json`: `{"<cid>":"attachments/image001.png", ...}` (HTML 본문 안 cid → 첨부 파일명).
183
- - HTML→평문 변환본 원래 `<img>` 위치에 `![image001.png](attachments/image001.png)` placeholder 삽입.
182
+ - `images.rels.json`: `{"<cid>":"attachments/image001.png", ...}` (HTML 본문 안 cid → 첨부 파일명 매핑).
183
+ - HTML→평문 변환본의 원래 `<img>` 위치에 `![image001.png](attachments/image001.png)` placeholder 삽입.
184
184
  - text/plain 만 있을 때 → `body.md` 자체가 변환본 → placeholder 포함.
185
185
  - text/plain·HTML 둘 다 있을 때 → `body.md` 는 plain (placeholder 없음), `body.from_html.md` 가 변환본 (placeholder 포함).
186
186
  - 인라인 이미지 없으면 `images.rels.json` 미생성.
187
187
 
188
188
  ## TNEF (winmail.dat) 풀이
189
189
 
190
- Outlook RTF 메일이 첨부를 `winmail.dat` 단일 binary (TNEF 형식) 로 패키징한 경우, `tnefparse` 로 내부 첨부 추출하여 `attachments/` 에 같이 풀어 둠. 원본 `winmail.dat` 도 유지 (원본 보존).
190
+ Outlook RTF 메일이 첨부를 `winmail.dat` 단일 binary (TNEF, Transport Neutral Encapsulation Format) 로 패키징한 경우, `tnefparse` 로 내부 첨부를 추출하여 `attachments/` 에 풀어 둠. 원본 `winmail.dat` 도 유지 (원본 보존).
191
191
 
192
- 내부 첨부도 컨테이너 (xlsx·pptx 등) 면 재귀 풀이 (다른 첨부와 동일).
192
+ 내부 첨부가 컨테이너 (xlsx·pptx 등) 면 재귀 풀이 (다른 첨부와 동일).
193
193
 
194
194
  ## eml/msg 본문 규약
195
195
 
196
- 본문 흐름 정확성(text/plain 우선) + 인라인 이미지 위치 단서(HTML→평문 변환본) 둘 다 보존:
196
+ 본문 흐름 정확성 (text/plain 우선) 인라인 이미지 위치 단서 (HTML→평문 변환본) 둘 다 보존:
197
197
 
198
198
  - `body.md`: 항상 별도 파일 (인라인 cutoff 폐기).
199
199
  - text/plain 있으면 우선 — 발신자가 의도한 평문, 변환 잡음 없음.
200
200
  - 없으면 text/html → 평문 추출.
201
201
  - `body.from_html.md`: text/plain·HTML 둘 다 있을 때만 별도 생성.
202
- - HTML→평문 변환 (이미지 위치 placeholder 포함).
203
- - body.md 가 plain 이라 잃은 위치 정보를 보완.
202
+ - HTML→평문 변환본 (이미지 위치 placeholder 포함).
203
+ - `body.md` 가 plain 이라 누락된 위치 정보를 보완.
204
204
  - `body.html`: 원본 HTML (있을 때).
205
- - `headers.json`: 모든 메일 헤더 원본 보존 (envelope + `X-Mailer`·`Authentication-Results` 등 모두). 동일 키 다수면 list 누적.
206
- - README 헤더 섹션에는 표준 envelope 키만 표기 (전체는 headers.json 직접 조회).
205
+ - `headers.json`: 모든 메일 헤더를 원본 그대로 보존 (envelope + `X-Mailer`·`Authentication-Results` 등 모두). 동일 키 다수면 list 누적.
206
+ - `README.md` 헤더 섹션에는 표준 envelope 키만 표기 (전체는 `headers.json` 직접 조회).
207
207
 
208
208
  ## xlsb 클린업
209
209
 
210
- - legacy → xlsx 변환 시 `_converted.xlsx` 는 임시 폴더에서만 처리 (산출 폴더에 미잔존).
211
- - VBA 매크로는 원본 코드 그대로 `macros/<모듈명>.vba` 저장 (변형 X).
212
- - VBA 시트 객체명↔raw 시트명 매핑은 `workbook.meta.json` 의 `sheet_code_map` (예: `{"Sheet1":"BOA","Sheet3":"Mapping"}`).
210
+ - legacy → xlsx 변환 시 `_converted.xlsx` 는 임시 폴더에서만 처리 (산출 폴더에 잔존시키지 않음).
211
+ - VBA(Visual Basic for Applications) 매크로는 원본 코드 그대로 `macros/<모듈명>.vba` 저장 (변형 금지).
212
+ - VBA 시트 객체명 ↔ raw 시트명 매핑은 `workbook.meta.json` 의 `sheet_code_map` 키에 저장 (예: `{"Sheet1":"BOA","Sheet3":"Mapping"}`).
213
213
 
214
214
  ## 산출물 사용
215
215
 
216
- 후속 스킬(sd-spec 등)은 결과 폴더의 `README.md` 한 번 Read 본문 위치·헤더·첨부 목록·손실 영역을 모두 파악할 있음. 컨테이너 첨부는 자체 `README.md` 를 가지므로 재귀적으로 같은 방식으로 들어감.
216
+ 후속 스킬 (sd-spec 등) 은 결과 폴더의 `README.md` 한 번 Read 하여 본문 위치·헤더·첨부 목록·손실 영역을 모두 파악 가능. 컨테이너 첨부는 자체 `README.md` 를 가지므로 같은 방식으로 재귀 진입.
217
217
 
218
218
  각 형식별 jsonl 의 grep 패턴:
219
219
  - xlsx: `"r":<행>` · `"_f"` (수식 행) · 열문자 키.
@@ -3,7 +3,7 @@ name: sd-use
3
3
  description: 사용자 요청을 분석해 워크스페이스의 sd-* 스킬 중 가장 적합한 스킬을 추천하는 스킬. Use when 어떤 sd-* 스킬을 써야 할지 모를 때.
4
4
  ---
5
5
 
6
- `/sd-use <요청>` 의 `<요청>` 에 적합한 sd-* 스킬을 추천만 하고 종료. 자동 실행·산출물 생성 금지.
7
- - 시스템 프롬프트내 sd-* 스킬의 프론트매터를 활용함.
8
- - 추천 후보에서 sd-use 자신은 제외 (회귀 방지).
9
- - 추천할 여러 스킬이 있다면, 추천순대로 나열하고 각각의 추천 이유를 출력함.
6
+ `/sd-use <요청>` 의 `<요청>` 에 적합한 sd-* 스킬을 추천만 출력하고 종료. 추천 대상 스킬의 자동 실행·산출물 생성 금지.
7
+ - 시스템 프롬프트 sd-* 스킬의 프론트매터(name·description)를 매칭 근거로 사용.
8
+ - 추천 후보에서 sd-use 자신은 제외 (자기 추천 방지).
9
+ - 적합한 스킬이 여러 개면, 적합도 높은 순으로 나열하고 스킬마다 추천 이유를 함께 출력.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/sd-claude",
3
- "version": "14.0.81",
3
+ "version": "14.0.83",
4
4
  "description": "심플리즘 패키지 - Claude Code 셋업",
5
5
  "author": "심플리즘",
6
6
  "license": "Apache-2.0",
@@ -1,37 +0,0 @@
1
- # @simplysm/angular
2
-
3
- Angular 기반 simplysm 공통 UI/상태/인프라 컴포넌트·디렉티브·서비스 모음. zoneless·signal 기반. 모든 컴포넌트 standalone.
4
-
5
- ## 사용 트리거 인덱스
6
-
7
- - **provideSdAngular / SdAngularConfigProvider** — 앱 부트스트랩 시 1회. 아래 "부트스트랩" 참조.
8
- - **버튼류** (`SdButton`/`SdAnchor`/`SdAdditionalButton`/`SdModalSelectButton`/`SdSelectModal`/`SdSelectModalInfo`) — 클릭 트리거 UI. 자세히: [buttons.md](./buttons.md)
9
- - **폼 입력류** (`SdTextfield`/`SdTextfieldTypes`/`sdTextfieldTypes`/`SdTextarea`/`SdNumpad`/`SdRange`/`SdDateRangePicker`/`SdSelect`/`SelectModeValue`/`SdSelectItem`/`SdSelectButton`/`SdCheckbox`/`SdSwitch`/`SdCheckboxGroup`/`SdCheckboxGroupItem`/`SdForm`/`SdDropdown`/`SdDropdownPopup`) — 값 입력·서밋. 자세히: [forms.md](./forms.md)
10
- - **모달** (`SdModalProvider`/`SdModal`/`SdActivatedModalProvider`/`SdModalContentDef`/`SdModalInfo`/`SdModalOptions`/`SdPromptModal`/`SdConfirmModal`/`SelectModalOutputResult`) — 프로그래밍 다이얼로그. 자세히: [modal.md](./modal.md)
11
- - **토스트·바쁨·프린트** (`SdToastProvider`/`SdToast`/`SdToastContainer`/`SdToastSeverity`/`SdToastTheme`/`SdToastContentDef`/`SdToastInput`/`SdBusyProvider`/`SdBusyContainer`/`SdBusyType`/`SdPrintProvider`/`SdPrint`/`SdPrintInput`) — 알림·로딩·인쇄. 자세히: [toast.md](./toast.md)
12
- - **앱 구조·권한** (`SdAppStructureProvider`/`SdAppStructureUtils`/`SdMenu`/`SdFlatMenu`/`SdPermission`/`injectPermsSignal`/`SdPermissionTable`) — 메뉴 트리·권한 매트릭스. 자세히: [app-structure.md](./app-structure.md)
13
- - **공유 데이터** (`SdSharedDataProvider`/`SharedDataBase`/`SharedDataInfo`/`SharedDataHandle`/`SdSharedDataChangeEvent`/`SdSharedDataSelect`/`SdSharedDataSelectButton`/`SdSharedDataSelectList`/`matchesSearchText`) — 서버 마스터데이터 캐시+선택 UI. 자세히: [shared-data.md](./shared-data.md)
14
- - **시트** (`SdSheet`/`SdSheetColumn`/`SdSheetColumnCellTemplate`/`SdSheetConfigModal`/`SdSheetCellContext`/`SdSheetColumnDef`/`SdSheetConfig`/`SdSheetHeaderDef`/`SdSheetItemKeydownEventParam`/`SdSheetCellKeydownEventParam`) — 표 그리드. 자세히: [sheet.md](./sheet.md)
15
- - **칸반** (`SdKanbanBoard`/`SdKanban`/`SdKanbanLane`/`SdKanbanBoardDropInfo`/`SdKanbanDragRef`/`SdKanbanDropTarget`) — 드래그 보드. 자세히: [kanban.md](./kanban.md)
16
- - **CRUD 화면 골격** (`SdBaseContainer`/`SdCrudList`/`SdCrudDetail`/`SdStatePreset`/`SdStatePresetDef`) — 목록/상세 페이지 컨테이너. 자세히: [crud.md](./crud.md)
17
- - **레이아웃** (`SdSidebarContainer`/`SdSidebar`/`SdSidebarMenu`/`SdSidebarUser`/`SdSidebarUserMenu`/`SdTopbarContainer`/`SdTopbar`/`SdTopbarMenu`/`SdTopbarUser`/`SdTopbarUserMenu`) — 사이드바·탑바 골격. 자세히: [layout.md](./layout.md)
18
- - **셀렉트/확장/정렬 매니저** (`useSelectionManager`/`useExpandingManager`/`useSortingManager`/`ExpandItemDef`/`SortingDef`) — 리스트 내부 상태 헬퍼. 자세히: [selection-managers.md](./selection-managers.md)
19
- - **라우팅** (`SdRouterLink`/`SdNavigateWindowProvider`/`injectCurrentPageCodeSignal`/`injectFullPageCodeSignal`/`injectViewTitleSignal`/`injectViewTypeSignal`/`SdViewType`/`setupCanDeactivate`/`getMenuRouterLinkOption`/`getIsMenuSelected`) — 라우터 보조. 자세히: [routing.md](./routing.md)
20
- - **인프라/유틸** (`SdSystemLogProvider`/`SdLocalStorageProvider`/`SdSystemConfigProvider`/`injectSdSystemConfigResource`/`SdServiceClientFactoryProvider`/`SdFileDialogProvider`/`SdGlobalErrorHandlerPlugin`/`SdThemeProvider`/`SdThemeSelector`/`FormatPipe`/`mark`/`setSafeStyle`/`setupBgTheme`/`setupModelHook`/`DirectiveInputSignals`/`UndefToOptional`/`WithOptional`/`SdEvents`/`SdOptionEventPlugin`/`SdResizeDirective`/`SdResizeEvent`/`SdIntersectionDirective`/`SdIntersectionEvent`/`SdCommandDirective`/`SdRipple`/`setupRipple`/`SdShowEffect`/`setupRevealOnShow`/`SdInvalid`/`setupInvalid`/`SdTypedTemplate`/`SdItemOfTemplate`/`SdItemOfTemplateContext`) — 자세히: [infrastructure.md](./infrastructure.md)
21
- - **시각 위젯** (`SdLabel`/`SdNote`/`SdProgress`/`SdCalendar`/`SdBarcode`/`BarcodeType`/`SdEcharts`/`SdTiptapEditor`/`SdAddressSearchModal`/`Address`/`SdCollapse`/`SdCollapseIcon`/`SdTab`/`SdTabItem`/`SdList`/`SdListItem`/`SdGap`/`SdPagination`) — 자세히: [visual.md](./visual.md)
22
-
23
- ## 부트스트랩
24
-
25
- ```ts
26
- provideSdAngular(opt: { clientName: string }): EnvironmentProviders
27
- ```
28
-
29
- - `clientName` — `SdAngularConfigProvider.clientName` 으로 저장. `SdLocalStorageProvider` 키 prefix, `SdServiceClientFactoryProvider` 의 `createServiceClient(clientName, …)`, `SdAppStructureProvider.initialize` 의 `itemsMap[clientName]` 조회에 사용.
30
- - 호출 부수효과: zoneless change detection 활성, `IMAGE_CONFIG` 경고 끔, ng-icons 기본(stroke 1.5/size 1.33em), `EVENT_MANAGER_PLUGINS` 에 `SdOptionEventPlugin` 추가, `ErrorHandler` 를 `SdGlobalErrorHandlerPlugin` 으로 교체, `unhandledrejection`·`error` 글로벌 리스너 등록, `SdThemeProvider.dark`/`fontSize` 를 `SdLocalStorageProvider` 와 양방향 sync(`sd-theme-dark`·`sd-theme-font-size` 키), `Router` 네비게이션 동안 `SdBusyProvider.globalBusyCount` 증감, `SwUpdate` 활성 시 5분~1시간 백오프로 업데이트 확인 후 사용자 컨펌 → reload.
31
-
32
- ```ts
33
- @Injectable({ providedIn: "root" }) class SdAngularConfigProvider { clientName!: string }
34
- ```
35
-
36
- - 직접 쓸 일은 거의 없음. 다른 simplysm 프로바이더가 inject 해 prefix·키로 사용.
37
- - 사용 예: `bootstrapApplication(App, { providers: [provideSdAngular({ clientName: "my-app" })] })`
@@ -1,92 +0,0 @@
1
- # @simplysm/angular — app-structure
2
-
3
- 서버 `AppStructureService` 에서 받은 메뉴·권한 트리(`AppStructureItem<TModule>[]`)를 클라이언트에서 사용 가능 형태로 변환·캐시.
4
-
5
- ## SdAppStructureProvider<TModule> (root)
6
-
7
- ```ts
8
- usableModules: WritableSignal<TModule[]|undefined>;
9
- permRecord: WritableSignal<Record<string, boolean>|undefined>;
10
- items: WritableSignal<AppStructureItem<TModule>[]>;
11
-
12
- usableMenus: Signal<SdMenu[]>; // items × modules × perms 필터된 트리 메뉴
13
- usableFlatMenus: Signal<SdFlatMenu<TModule>[]>; // 평탄화된 메뉴 리스트 (검색 등)
14
-
15
- initialize(serviceKey: string): Promise<void>;
16
- getPermissionsByStructure(items, codeChain?): SdPermission<TModule>[];
17
- getTitleByFullCode(fullCode: string): string; // 부모 chain 포함 타이틀("[A > B] C")
18
- getItemChainByFullCode(fullCode: string): AppStructureItem<TModule>[];
19
- getPermsByFullCode<K extends string>(fullCodes: string[], permKeys: K[]): K[];
20
- ```
21
-
22
- - `initialize` — `SdServiceClientFactoryProvider.get(serviceKey)` 에서 `AppStructureService.getItems()` 호출, `clientName` (`SdAngularConfigProvider`) 키로 트리 적재.
23
- - `usableModules` — 활성 모듈 식별자 배열. 메뉴/권한 필터링에 사용. 미세팅(`undefined`) 이면 모듈 체크 통과(전체 허용).
24
- - `permRecord` — `<fullCode>.<permKey>` (예: `sales.invoice.use`) → boolean. `undefined` 면 권한 체크 통과.
25
- - `usableMenus` — 그룹 메뉴는 표시 가능한 leaf 자식이 있어야 포함. leaf 는 `<code>.use` 권한 검사.
26
- - `usableFlatMenus` — leaf 만 평탄화. modulesChain 정보 포함.
27
- - `getPermsByFullCode` — 해당 화면들에 대해 사용자가 가진 권한키들 추출(`perms` 자체가 정의 안된 화면은 모든 permKey 통과).
28
-
29
- ## SdAppStructureUtils (abstract static class)
30
-
31
- ```ts
32
- static getTitleByFullCode/getPermsByFullCode/getItemChainByFullCode
33
- static getMenus(items, codeChain, usableModules, permRecord): SdMenu[]
34
- static getFlatMenus(items, usableModules, permRecord): SdFlatMenu<TModule>[]
35
- static getPermissions(items, codeChain, usableModules): SdPermission<TModule>[]
36
- static getFlatPermissions(items, usableModules) // service-common 의 동명 함수 위임
37
- ```
38
-
39
- - 프로바이더가 내부적으로 호출. 트리 변환 로직 직접 쓰고 싶으면 호출 가능.
40
-
41
- ## injectPermsSignal
42
-
43
- ```ts
44
- function injectPermsSignal<K extends string>(viewCodes: string[], keys: K[]): Signal<K[]>
45
- ```
46
-
47
- - 컴포넌트/페이지에서 자기 화면 코드들과 검사할 권한키 배열을 주면, 현재 사용자가 가진 키만 담은 signal 반환. 버튼 enable 조건 등에 사용.
48
-
49
- ```ts
50
- readonly perms = injectPermsSignal(["sales.invoice"], ["use", "edit"]);
51
- // 템플릿: @if (perms().includes("edit")) { <sd-button>편집</sd-button> }
52
- ```
53
-
54
- ## SdPermissionTable — `<sd-permission-table>`
55
-
56
- ```ts
57
- class SdPermissionTable<TModule>
58
- value = model<Record<string, boolean>>({}); // permRecord 형태(key: <fullCode>.<permKey>)
59
- items = input<SdPermission<TModule>[]>([]);
60
- disabled = input(false);
61
- ```
62
-
63
- - 권한 트리를 표 형태로 표시·편집. `value` 양방향. 관리자 권한 설정 화면용.
64
-
65
- ## 타입
66
-
67
- ```ts
68
- interface SdMenu {
69
- title: string; codeChain: string[]; url?: string; icon?: string; children?: SdMenu[];
70
- }
71
- interface SdFlatMenu<TModule = unknown> {
72
- titleChain: string[]; codeChain: string[]; modulesChain: TModule[][];
73
- }
74
- interface SdPermission<TModule = unknown> {
75
- title: string; codeChain: string[]; modules: TModule[]|undefined;
76
- perms: ("use"|"edit")[]|undefined;
77
- children: SdPermission<TModule>[]|undefined;
78
- }
79
- ```
80
-
81
- - `SdMenu` — `url` 또는 `children` 중 하나. 라우터 링크 분기는 `getMenuRouterLinkOption` 이 담당 ([routing.md](./routing.md)).
82
- - `SdFlatMenu.modulesChain` — 조상부터 자신까지 누적된 modules 배열 묶음. 모듈 활성 여부 검사 시 사용.
83
- - `SdPermission.perms` — 해당 화면이 정의한 권한 키들. undefined 면 권한 개념 없음(모두 허용).
84
-
85
- ## 부트스트랩 순서
86
-
87
- ```ts
88
- const sdAppStructure = inject(SdAppStructureProvider);
89
- sdAppStructure.usableModules.set(myActiveModules);
90
- sdAppStructure.permRecord.set(myPermRecord);
91
- await sdAppStructure.initialize("main"); // serviceKey = SdServiceClientFactoryProvider 의 등록 key
92
- ```
@@ -1,88 +0,0 @@
1
- # @simplysm/angular — buttons
2
-
3
- ## SdButton — `<sd-button>`
4
-
5
- ```ts
6
- type = input<"button" | "submit">("button");
7
- theme = input<"primary"|"secondary"|"info"|"success"|"warning"|"danger"|"gray"|"blue-gray"|"link"|"link-primary"|"link-secondary"|"link-info"|"link-success"|"link-warning"|"link-danger"|"link-gray"|"link-blue-gray"|"link-rev">();
8
- inline = input(false); inset = input(false); size = input<"sm"|"lg">();
9
- disabled = input(false); buttonStyle = input<string>(); buttonClass = input<string>();
10
- ```
11
-
12
- - `type` — 내부 `<button type>`. `submit` 이면 둘러싼 `<sd-form>`·`<form>` 의 서밋을 트리거.
13
- - `theme` — 색상·강조. `link-*` 는 배경 없는 텍스트 링크 룩. 미지정이면 디폴트 회색.
14
- - `inline` — true 면 인라인 블록 폭(콘텐츠 크기). false 면 부모 폭 채움.
15
- - `inset` — true 면 외곽 보더/그림자 제거(컨테이너 안에 박힌 룩).
16
- - `size` — `sm`/`lg` 만. 미지정 = 기본 크기.
17
- - `disabled` — true 면 클릭·포커스 차단.
18
- - `buttonStyle`/`buttonClass` — 내부 `<button>` 에 style/class 추가.
19
-
20
- ```html
21
- <sd-button theme="primary" (click)="onSave()">저장</sd-button>
22
- ```
23
-
24
- ## SdAnchor — `<sd-anchor>`
25
-
26
- ```ts
27
- disabled = input(false);
28
- theme = input<"primary"|"secondary"|"info"|"success"|"warning"|"danger"|"gray"|"blue-gray"|...>();
29
- ```
30
-
31
- - 링크 룩 클릭 영역. 버튼보다 강조 낮음. `theme` 미지정이면 현재 텍스트 색 상속.
32
- - `disabled` — 클릭·포커스 차단.
33
-
34
- ```html
35
- <sd-anchor (click)="onEdit()">수정</sd-anchor>
36
- ```
37
-
38
- ## SdAdditionalButton — `<sd-additional-button>`
39
-
40
- ```ts
41
- size = input<"sm"|"lg">(); inset = input(false);
42
- ```
43
-
44
- - 입력 컨트롤(`<sd-textfield>` 등) 옆에 붙이는 보조 버튼 슬롯. `<ng-content>` 로 아이콘/텍스트 투영. 키패드 등 입력 우측에 액션 붙일 때.
45
-
46
- ```html
47
- <sd-textfield type="text" [(value)]="q" /><sd-additional-button (click)="onSearch()">검색</sd-additional-button>
48
- ```
49
-
50
- ## SdModalSelectButton — `<sd-modal-select-button>`
51
-
52
- ```ts
53
- class SdModalSelectButton<M extends "single"|"multi", K, T extends SdSelectModal<K>>
54
- modal = input.required<SdSelectModalInfo<SdSelectModal<K>>>();
55
- value = model<SelectModeValue<K>[M]>();
56
- disabled = input(false); required = input(false); inset = input(false);
57
- size = input<"sm"|"lg">(); selectMode = input<M>("single" as M);
58
- modalOptions = input<SdModalOptions>();
59
- searchIcon = input(tablerSearch);
60
-
61
- interface SdSelectModal<TKey> extends SdModalContentDef<SelectModalOutputResult<TKey>> {
62
- selectMode: InputSignal<"single"|"multi"|undefined>;
63
- selectedKeys: InputSignal<TKey[]>;
64
- }
65
- type SdSelectModalInfo<T extends SdSelectModal<any>> = SdModalInfo<T, "selectMode"|"selectedKeys">;
66
- ```
67
-
68
- - 입력 옆에 검색 버튼이 붙은 모달 트리거 컨트롤. 검색 아이콘 클릭 → 지정 모달 표시 → 모달이 `SelectModalOutputResult<TKey>` emit → `value` 에 반영.
69
- - `modal` — 표시할 모달 컴포넌트 정의(`SdSelectModal` 구현). 필수.
70
- - `value` — `single` 모드면 단일 키, `multi` 면 키 배열. `model` 이므로 양방향.
71
- - `selectMode` — 모달에 전달되는 선택 모드. `single` 기본.
72
- - `required` — true 면 값이 있어도 지우개 아이콘 표시 안 함. false + 값 있음 → 우측에 지우개 아이콘 노출.
73
- - `inset` — 컨테이너 안에 박힌 룩(보더 제거).
74
- - `disabled` — 검색·지우개 버튼 모두 숨김.
75
- - `modalOptions` — `SdModalProvider.showAsync` 에 전달되는 옵션 ([modal.md](./modal.md)).
76
- - `searchIcon` — 우측 버튼 아이콘. 기본 `tablerSearch`.
77
- - `<ng-content>` — 좌측 값 표시 영역.
78
-
79
- ```html
80
- <sd-modal-select-button [(value)]="userId" [modal]="{ title: '직원선택', type: EmpSelectModal, inputs: {} }">
81
- {{ userName() }}
82
- </sd-modal-select-button>
83
- ```
84
-
85
- ## 공통 주의
86
-
87
- - 모든 버튼류는 standalone. 별도 NgModule 등록 불필요.
88
- - `theme` 의 같은 8개 baseline(`primary`~`blue-gray`)은 디자인 토큰 `--theme-<name>-default` 에 연결. `SdButton.theme` 만 `link-*` 변종 추가.
@@ -1,100 +0,0 @@
1
- # @simplysm/angular — crud
2
-
3
- CRUD 화면 골격. 공통 컨테이너(`SdBaseContainer`) + 리스트(`SdCrudList`) + 상세(`SdCrudDetail`) + 사용자 상태 프리셋(`SdStatePreset`).
4
-
5
- ## SdBaseContainer — `<sd-base-container>`
6
-
7
- ```ts
8
- ready = model(false);
9
- initialized = input(false);
10
- busyCount = model(0);
11
- restricted = input(false);
12
- viewType = input.required<SdViewType>(); // "page"|"modal"|"control" (routing.md)
13
-
14
- // content slots: #topbarTpl #commandTpl #contentTpl #bottomCommandTpl
15
- ```
16
-
17
- - 모든 simplysm 화면의 기본 컨테이너. 진입 시 `SdSharedDataProvider.wait()` 후 `ready` true.
18
- - `restricted=true` 면 권한 없음 안내 화면 표시(데이터 로드 스킵).
19
- - `viewType` — 보통 `injectViewTypeSignal()` 결과 바인딩.
20
- - 슬롯: `<ng-template #topbarTpl>` 상단 영역, `#commandTpl` 명령바, `#contentTpl` 본문, `#bottomCommandTpl` 하단.
21
-
22
- ## SdCrudList — `<sd-crud-list>`
23
-
24
- ```ts
25
- class SdCrudList<TItem, TKey>
26
- ready = model(false); initialized = input(false); busyCount = model(0);
27
- restricted = input(false); readonly = input(false);
28
- viewType = input.required<SdViewType>();
29
- selectMode = input<"single"|"multi">();
30
- key = input.required<string>(); // 시트/프리셋 key prefix
31
-
32
- filterSubmit = output(); submit = output();
33
- create = output(); delete = output<TItem[]>(); restore = output<TItem[]>();
34
-
35
- items = input<TItem[]>([]);
36
- selectedKeys = model<NonNullable<TKey>[]>([]);
37
- currDeletedItems = input<TItem[]>([]); // 삭제됨 표시(취소선) 대상
38
-
39
- currentPage = model(0); totalPageCount = input(0);
40
- itemsPerPage = input(0); visiblePageCount = input(10);
41
- sorts = model<SortingDef[]>([]);
42
- trackByFn = input.required<(item) => TKey>();
43
-
44
- // content slots: #commandTpl #filterTpl #toolTpl #bottomCommandTpl
45
- // + 자식: <sd-sheet-column> 들
46
- ```
47
-
48
- - 표준 리스트 화면: 필터 영역 + 시트 + 페이지바 + 명령(저장/추가/삭제/복원).
49
- - `filterSubmit` — 필터 폼 submit. 호출자가 데이터 fetch.
50
- - `submit` — 명령바의 저장 버튼.
51
- - `create`/`delete`/`restore` — 행 추가/선택 삭제/선택 복원.
52
- - `currDeletedItems` — soft-delete 표시. 해당 행 셀에 취소선 자동.
53
- - `readonly=true` 면 명령바·편집 차단.
54
- - 모달로 띄워서 선택 picker 로도 동작: 모달 confirm 시 `SdActivatedModalProvider.contentComponent.close.emit({ selectedKeys })`.
55
- - `key` — 자식 `<sd-sheet key>` 와 `SdStatePreset key` 가 이 값을 prefix 로 사용.
56
-
57
- ```html
58
- <sd-crud-list [viewType]="viewType()" key="invoice" [trackByFn]="trackById"
59
- [items]="items()" [(selectedKeys)]="sel" selectMode="multi"
60
- (filterSubmit)="reload()" (create)="onCreate()" (delete)="onDelete($event)">
61
- <ng-template #filterTpl>...필터 폼...</ng-template>
62
- <sd-sheet-column key="no" header="번호" />
63
- </sd-crud-list>
64
- ```
65
-
66
- ## SdCrudDetail — `<sd-crud-detail>`
67
-
68
- ```ts
69
- ready = model(false); initialized = input(false); busyCount = model(0);
70
- restricted = input(false); readonly = input(false);
71
- viewType = input.required<SdViewType>();
72
- submit = output();
73
-
74
- // content slots: #commandTpl #contentTpl #bottomCommandTpl
75
- ```
76
-
77
- - 상세 화면 골격. 내부에 `<sd-form>` 자동 배치. 저장 버튼 클릭 시 form submit → invalid 없으면 `submit` 발화.
78
-
79
- ## SdStatePreset — `<sd-state-preset>`
80
-
81
- ```ts
82
- key = input.required<string>();
83
- state = model<any>(); // 적용할 상태 객체 (필터 등)
84
- size = input<"sm"|"lg">();
85
-
86
- interface SdStatePresetDef { name: string; state: any; }
87
- ```
88
-
89
- - 사용자가 현재 `state` 를 이름 붙여 저장/불러오기. `SdSystemConfigProvider` 키 `key` 로 `SdStatePresetDef[]` 저장.
90
- - 별 아이콘 클릭 → 이름 입력(`SdPromptModal`) → 추가. 프리셋 클릭 → `state` 에 적용. 디스켓 아이콘 → 현재 state 덮어쓰기. X 아이콘 → 삭제.
91
-
92
- ```html
93
- <sd-state-preset key="invoice-filter" [(state)]="filter" />
94
- ```
95
-
96
- ## 주의
97
-
98
- - 모든 CRUD 컴포넌트의 `ready` 는 진입 후 데이터 준비 완료 시 true. 호출자가 `[ready]="ready()"` 로 자식 조건부 렌더링.
99
- - `key` 는 한 클라이언트 내 고유해야 함. 시트 컬럼 설정·프리셋·기타 영구 상태가 이 키로 충돌 없이 저장됨.
100
- - `SdCrudList` 의 selectMode 가 설정되었고 컨테이너가 모달 안에 있으면 자동으로 picker 모드로 동작.