@simplysm/sd-claude 14.0.50 → 14.0.52

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 (318) hide show
  1. package/claude/references/sd-frontend-design.md +10 -9
  2. package/claude/references/sd-simplysm-v14/angular/README.md +497 -0
  3. package/claude/references/sd-simplysm-v14/angular/bootstrap/provide-sd-angular.md +37 -0
  4. package/claude/references/sd-simplysm-v14/angular/bootstrap/sd-angular-config-provider.md +16 -0
  5. package/claude/references/sd-simplysm-v14/angular/directives/sd-command-directive.md +27 -0
  6. package/claude/references/sd-simplysm-v14/angular/directives/sd-events.md +25 -0
  7. package/claude/references/sd-simplysm-v14/angular/directives/sd-intersection-directive.md +36 -0
  8. package/claude/references/sd-simplysm-v14/angular/directives/sd-invalid.md +24 -0
  9. package/claude/references/sd-simplysm-v14/angular/directives/sd-resize-directive.md +42 -0
  10. package/claude/references/sd-simplysm-v14/angular/directives/sd-ripple.md +23 -0
  11. package/claude/references/sd-simplysm-v14/angular/directives/sd-router-link.md +38 -0
  12. package/claude/references/sd-simplysm-v14/angular/directives/sd-show-effect.md +18 -0
  13. package/claude/references/sd-simplysm-v14/angular/directives/sd-typed-template.md +69 -0
  14. package/claude/references/sd-simplysm-v14/angular/features/sd-address-search-modal.md +50 -0
  15. package/claude/references/sd-simplysm-v14/angular/features/sd-permission-table.md +20 -0
  16. package/claude/references/sd-simplysm-v14/angular/features/sd-shared-data-components.md +158 -0
  17. package/claude/references/sd-simplysm-v14/angular/features/sd-tiptap-editor.md +26 -0
  18. package/claude/references/sd-simplysm-v14/angular/pipes/format-pipe.md +41 -0
  19. package/claude/references/sd-simplysm-v14/angular/plugins/sd-global-error-handler.md +23 -0
  20. package/claude/references/sd-simplysm-v14/angular/plugins/sd-option-event-plugin.md +34 -0
  21. package/claude/references/sd-simplysm-v14/angular/provider-types/sd-menu.md +65 -0
  22. package/claude/references/sd-simplysm-v14/angular/provider-types/sd-modal-content-def.md +148 -0
  23. package/claude/references/sd-simplysm-v14/angular/provider-types/sd-toast-content-def.md +73 -0
  24. package/claude/references/sd-simplysm-v14/angular/provider-types/shared-data-base.md +59 -0
  25. package/claude/references/sd-simplysm-v14/angular/providers/sd-activated-modal-provider.md +34 -0
  26. package/claude/references/sd-simplysm-v14/angular/providers/sd-app-structure-provider.md +81 -0
  27. package/claude/references/sd-simplysm-v14/angular/providers/sd-busy-provider.md +18 -0
  28. package/claude/references/sd-simplysm-v14/angular/providers/sd-file-dialog-provider.md +40 -0
  29. package/claude/references/sd-simplysm-v14/angular/providers/sd-local-storage-provider.md +20 -0
  30. package/claude/references/sd-simplysm-v14/angular/providers/sd-modal-provider.md +67 -0
  31. package/claude/references/sd-simplysm-v14/angular/providers/sd-navigate-window-provider.md +18 -0
  32. package/claude/references/sd-simplysm-v14/angular/providers/sd-print-provider.md +25 -0
  33. package/claude/references/sd-simplysm-v14/angular/providers/sd-service-client-factory-provider.md +43 -0
  34. package/claude/references/sd-simplysm-v14/angular/providers/sd-shared-data-provider.md +64 -0
  35. package/claude/references/sd-simplysm-v14/angular/providers/sd-system-config-provider.md +46 -0
  36. package/claude/references/sd-simplysm-v14/angular/providers/sd-system-log-provider.md +18 -0
  37. package/claude/references/sd-simplysm-v14/angular/providers/sd-theme-provider.md +38 -0
  38. package/claude/references/sd-simplysm-v14/angular/providers/sd-toast-provider.md +65 -0
  39. package/claude/references/sd-simplysm-v14/angular/recipes/_common-rules.md +336 -0
  40. package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-a-edit-save.md +191 -0
  41. package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-b-delete-restore.md +103 -0
  42. package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-c-modal-view.md +198 -0
  43. package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-d-control-view.md +109 -0
  44. package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-e-auxiliary.md +87 -0
  45. package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail/extension-f-complex-detail.md +202 -0
  46. package/claude/references/sd-simplysm-v14/angular/recipes/crud-detail.md +280 -0
  47. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-a-inline-edit.md +386 -0
  48. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-b-selection.md +215 -0
  49. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-c-inline-delete.md +64 -0
  50. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-d-select-modal.md +193 -0
  51. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-e-readonly-modal.md +140 -0
  52. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-f-modal-edit.md +123 -0
  53. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list/extension-g-excel.md +145 -0
  54. package/claude/references/sd-simplysm-v14/angular/recipes/crud-list.md +377 -0
  55. package/claude/references/sd-simplysm-v14/angular/recipes/data-select-button.md +368 -0
  56. package/claude/references/sd-simplysm-v14/angular/recipes/page-modal-container.md +238 -0
  57. package/claude/references/sd-simplysm-v14/angular/styling/classes.md +149 -0
  58. package/claude/references/sd-simplysm-v14/angular/styling/mixins.md +100 -0
  59. package/claude/references/sd-simplysm-v14/angular/styling/themes.md +35 -0
  60. package/claude/references/sd-simplysm-v14/angular/styling/variables.md +147 -0
  61. package/claude/references/sd-simplysm-v14/angular/type-utilities/directive-input-signals.md +232 -0
  62. package/claude/references/sd-simplysm-v14/angular/ui-data/sd-list.md +37 -0
  63. package/claude/references/sd-simplysm-v14/angular/ui-data/sd-sheet.md +212 -0
  64. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-additional-button.md +26 -0
  65. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-anchor.md +31 -0
  66. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-button.md +103 -0
  67. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-checkbox-group.md +39 -0
  68. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-checkbox.md +81 -0
  69. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-date-range-picker.md +27 -0
  70. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-form.md +89 -0
  71. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-modal-select-button.md +54 -0
  72. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-numpad.md +26 -0
  73. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-range.md +26 -0
  74. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-select.md +68 -0
  75. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-shared-data-select.md +52 -0
  76. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-state-preset.md +37 -0
  77. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-switch.md +27 -0
  78. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-textarea.md +33 -0
  79. package/claude/references/sd-simplysm-v14/angular/ui-form/sd-textfield.md +145 -0
  80. package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-dock-container.md +64 -0
  81. package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-dock.md +37 -0
  82. package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-gap.md +26 -0
  83. package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-kanban-board.md +96 -0
  84. package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-kanban-lane.md +34 -0
  85. package/claude/references/sd-simplysm-v14/angular/ui-layout/sd-kanban.md +29 -0
  86. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-collapse.md +35 -0
  87. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-pagination.md +26 -0
  88. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-sidebar-container.md +49 -0
  89. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-sidebar-menu.md +22 -0
  90. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-sidebar-user.md +43 -0
  91. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-tab.md +51 -0
  92. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-topbar-container.md +97 -0
  93. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-topbar-menu.md +23 -0
  94. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-topbar-user.md +38 -0
  95. package/claude/references/sd-simplysm-v14/angular/ui-navigation/sd-topbar.md +30 -0
  96. package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-busy-container.md +69 -0
  97. package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-confirm-modal.md +30 -0
  98. package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-dropdown.md +40 -0
  99. package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-modal.md +34 -0
  100. package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-prompt-modal.md +30 -0
  101. package/claude/references/sd-simplysm-v14/angular/ui-overlay/sd-toast.md +35 -0
  102. package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-barcode.md +36 -0
  103. package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-calendar.md +34 -0
  104. package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-echarts.md +32 -0
  105. package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-label.md +24 -0
  106. package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-note.md +23 -0
  107. package/claude/references/sd-simplysm-v14/angular/ui-visual/sd-progress.md +23 -0
  108. package/claude/references/sd-simplysm-v14/angular/utils/inject-routing-signals.md +161 -0
  109. package/claude/references/sd-simplysm-v14/angular/utils/inject-sd-system-config-resource.md +35 -0
  110. package/claude/references/sd-simplysm-v14/angular/utils/mark.md +43 -0
  111. package/claude/references/sd-simplysm-v14/angular/utils/selection-managers.md +96 -0
  112. package/claude/references/sd-simplysm-v14/angular/utils/set-safe-style.md +19 -0
  113. package/claude/references/sd-simplysm-v14/angular/utils/setup-functions.md +93 -0
  114. package/claude/references/sd-simplysm-v14/capacitor-plugin-auto-update/README.md +38 -0
  115. package/claude/references/sd-simplysm-v14/capacitor-plugin-auto-update/apk-installer/apk-installer.md +115 -0
  116. package/claude/references/sd-simplysm-v14/capacitor-plugin-auto-update/auto-update/auto-update.md +113 -0
  117. package/claude/references/sd-simplysm-v14/capacitor-plugin-file-system/README.md +197 -0
  118. package/claude/references/sd-simplysm-v14/capacitor-plugin-intent/README.md +235 -0
  119. package/claude/references/sd-simplysm-v14/capacitor-plugin-usb-storage/README.md +251 -0
  120. package/claude/references/sd-simplysm-v14/core-browser/README.md +52 -0
  121. package/claude/references/sd-simplysm-v14/core-browser/extensions/copy-paste.md +59 -0
  122. package/claude/references/sd-simplysm-v14/core-browser/extensions/element-prototype-extensions.md +137 -0
  123. package/claude/references/sd-simplysm-v14/core-browser/extensions/get-bounds.md +84 -0
  124. package/claude/references/sd-simplysm-v14/core-browser/utils/download-blob.md +59 -0
  125. package/claude/references/sd-simplysm-v14/core-browser/utils/fetch-url-bytes.md +91 -0
  126. package/claude/references/sd-simplysm-v14/core-browser/utils/indexed-db-store.md +131 -0
  127. package/claude/references/sd-simplysm-v14/core-browser/utils/indexed-db-virtual-fs.md +121 -0
  128. package/claude/references/sd-simplysm-v14/core-browser/utils/open-file-dialog.md +60 -0
  129. package/claude/references/sd-simplysm-v14/core-common/README.md +179 -0
  130. package/claude/references/sd-simplysm-v14/core-common/errors/argument-error.md +26 -0
  131. package/claude/references/sd-simplysm-v14/core-common/errors/not-implemented-error.md +33 -0
  132. package/claude/references/sd-simplysm-v14/core-common/errors/sd-error.md +38 -0
  133. package/claude/references/sd-simplysm-v14/core-common/errors/timeout-error.md +36 -0
  134. package/claude/references/sd-simplysm-v14/core-common/extensions/array.md +125 -0
  135. package/claude/references/sd-simplysm-v14/core-common/extensions/map.md +43 -0
  136. package/claude/references/sd-simplysm-v14/core-common/extensions/set.md +35 -0
  137. package/claude/references/sd-simplysm-v14/core-common/features/debounce-queue.md +48 -0
  138. package/claude/references/sd-simplysm-v14/core-common/features/event-emitter.md +52 -0
  139. package/claude/references/sd-simplysm-v14/core-common/features/serial-queue.md +44 -0
  140. package/claude/references/sd-simplysm-v14/core-common/type-utils/common-types.md +100 -0
  141. package/claude/references/sd-simplysm-v14/core-common/type-utils/env.md +42 -0
  142. package/claude/references/sd-simplysm-v14/core-common/types/date-only.md +86 -0
  143. package/claude/references/sd-simplysm-v14/core-common/types/date-time.md +106 -0
  144. package/claude/references/sd-simplysm-v14/core-common/types/lazy-gc-map.md +59 -0
  145. package/claude/references/sd-simplysm-v14/core-common/types/time.md +62 -0
  146. package/claude/references/sd-simplysm-v14/core-common/types/uuid.md +41 -0
  147. package/claude/references/sd-simplysm-v14/core-common/utils/bytes.md +36 -0
  148. package/claude/references/sd-simplysm-v14/core-common/utils/dt.md +60 -0
  149. package/claude/references/sd-simplysm-v14/core-common/utils/err.md +26 -0
  150. package/claude/references/sd-simplysm-v14/core-common/utils/json.md +58 -0
  151. package/claude/references/sd-simplysm-v14/core-common/utils/num.md +56 -0
  152. package/claude/references/sd-simplysm-v14/core-common/utils/obj.md +107 -0
  153. package/claude/references/sd-simplysm-v14/core-common/utils/path.md +30 -0
  154. package/claude/references/sd-simplysm-v14/core-common/utils/primitive.md +28 -0
  155. package/claude/references/sd-simplysm-v14/core-common/utils/str.md +63 -0
  156. package/claude/references/sd-simplysm-v14/core-common/utils/template-strings.md +49 -0
  157. package/claude/references/sd-simplysm-v14/core-common/utils/transfer.md +35 -0
  158. package/claude/references/sd-simplysm-v14/core-common/utils/wait.md +35 -0
  159. package/claude/references/sd-simplysm-v14/core-common/utils/xml.md +49 -0
  160. package/claude/references/sd-simplysm-v14/core-common/utils/zip-archive.md +77 -0
  161. package/claude/references/sd-simplysm-v14/core-node/README.md +59 -0
  162. package/claude/references/sd-simplysm-v14/core-node/features/fs-watcher.md +110 -0
  163. package/claude/references/sd-simplysm-v14/core-node/logging/create-file-reporter.md +78 -0
  164. package/claude/references/sd-simplysm-v14/core-node/logging/pretty-reporter.md +38 -0
  165. package/claude/references/sd-simplysm-v14/core-node/logging/setup-consola.md +77 -0
  166. package/claude/references/sd-simplysm-v14/core-node/utils/cpx.md +128 -0
  167. package/claude/references/sd-simplysm-v14/core-node/utils/fsx.md +168 -0
  168. package/claude/references/sd-simplysm-v14/core-node/utils/pathx.md +73 -0
  169. package/claude/references/sd-simplysm-v14/core-node/worker/create-worker.md +85 -0
  170. package/claude/references/sd-simplysm-v14/core-node/worker/worker.md +160 -0
  171. package/claude/references/sd-simplysm-v14/excel/README.md +66 -0
  172. package/claude/references/sd-simplysm-v14/excel/core-classes/excel-cell.md +79 -0
  173. package/claude/references/sd-simplysm-v14/excel/core-classes/excel-col.md +36 -0
  174. package/claude/references/sd-simplysm-v14/excel/core-classes/excel-row.md +34 -0
  175. package/claude/references/sd-simplysm-v14/excel/core-classes/excel-workbook.md +93 -0
  176. package/claude/references/sd-simplysm-v14/excel/core-classes/excel-worksheet.md +147 -0
  177. package/claude/references/sd-simplysm-v14/excel/types/excel-address-point.md +33 -0
  178. package/claude/references/sd-simplysm-v14/excel/types/excel-style-options.md +57 -0
  179. package/claude/references/sd-simplysm-v14/excel/types/excel-value-type.md +28 -0
  180. package/claude/references/sd-simplysm-v14/excel/types/excel-xml-content-type-data.md +23 -0
  181. package/claude/references/sd-simplysm-v14/excel/types/excel-xml-drawing-data.md +29 -0
  182. package/claude/references/sd-simplysm-v14/excel/types/excel-xml-relationship-data.md +39 -0
  183. package/claude/references/sd-simplysm-v14/excel/types/excel-xml-shared-string-data.md +42 -0
  184. package/claude/references/sd-simplysm-v14/excel/types/excel-xml-style-data.md +97 -0
  185. package/claude/references/sd-simplysm-v14/excel/types/excel-xml-workbook-data.md +22 -0
  186. package/claude/references/sd-simplysm-v14/excel/types/excel-xml-worksheet-data.md +68 -0
  187. package/claude/references/sd-simplysm-v14/excel/types/excel-xml.md +15 -0
  188. package/claude/references/sd-simplysm-v14/excel/utilities/excel-utils.md +101 -0
  189. package/claude/references/sd-simplysm-v14/excel/wrapper/excel-wrapper.md +108 -0
  190. package/claude/references/sd-simplysm-v14/lint/README.md +183 -0
  191. package/claude/references/sd-simplysm-v14/orm-common/README.md +156 -0
  192. package/claude/references/sd-simplysm-v14/orm-common/core/db-context.md +208 -0
  193. package/claude/references/sd-simplysm-v14/orm-common/core/db-transaction-error.md +64 -0
  194. package/claude/references/sd-simplysm-v14/orm-common/expression/expr-unit.md +62 -0
  195. package/claude/references/sd-simplysm-v14/orm-common/expression/expr.md +198 -0
  196. package/claude/references/sd-simplysm-v14/orm-common/models/migration.md +37 -0
  197. package/claude/references/sd-simplysm-v14/orm-common/query-builder/create-query-builder.md +80 -0
  198. package/claude/references/sd-simplysm-v14/orm-common/queryable-executable/executable.md +54 -0
  199. package/claude/references/sd-simplysm-v14/orm-common/queryable-executable/parse-search-query.md +75 -0
  200. package/claude/references/sd-simplysm-v14/orm-common/queryable-executable/queryable.md +238 -0
  201. package/claude/references/sd-simplysm-v14/orm-common/schema-builders/column-builder.md +63 -0
  202. package/claude/references/sd-simplysm-v14/orm-common/schema-builders/foreign-key-builder.md +137 -0
  203. package/claude/references/sd-simplysm-v14/orm-common/schema-builders/index-builder.md +54 -0
  204. package/claude/references/sd-simplysm-v14/orm-common/schema-builders/procedure.md +67 -0
  205. package/claude/references/sd-simplysm-v14/orm-common/schema-builders/table.md +95 -0
  206. package/claude/references/sd-simplysm-v14/orm-common/schema-builders/view.md +71 -0
  207. package/claude/references/sd-simplysm-v14/orm-common/types/data-type.md +146 -0
  208. package/claude/references/sd-simplysm-v14/orm-common/types/dialect.md +151 -0
  209. package/claude/references/sd-simplysm-v14/orm-common/types/expr.md +175 -0
  210. package/claude/references/sd-simplysm-v14/orm-common/types/parse-query-result.md +58 -0
  211. package/claude/references/sd-simplysm-v14/orm-common/types/query-def.md +224 -0
  212. package/claude/references/sd-simplysm-v14/orm-node/README.md +65 -0
  213. package/claude/references/sd-simplysm-v14/orm-node/connections/mssql-db-conn.md +85 -0
  214. package/claude/references/sd-simplysm-v14/orm-node/connections/mysql-db-conn.md +83 -0
  215. package/claude/references/sd-simplysm-v14/orm-node/connections/postgresql-db-conn.md +86 -0
  216. package/claude/references/sd-simplysm-v14/orm-node/core/create-db-conn.md +62 -0
  217. package/claude/references/sd-simplysm-v14/orm-node/core/create-orm.md +107 -0
  218. package/claude/references/sd-simplysm-v14/orm-node/core/node-db-context-executor.md +50 -0
  219. package/claude/references/sd-simplysm-v14/orm-node/types/db-conn-config.md +91 -0
  220. package/claude/references/sd-simplysm-v14/orm-node/types/db-conn-constants.md +33 -0
  221. package/claude/references/sd-simplysm-v14/orm-node/types/db-conn.md +60 -0
  222. package/claude/references/sd-simplysm-v14/orm-node/types/get-dialect-from-config.md +17 -0
  223. package/{README.md → claude/references/sd-simplysm-v14/sd-claude/README.md} +85 -84
  224. package/{docs → claude/references/sd-simplysm-v14/sd-claude}/assets.md +2 -2
  225. package/{docs → claude/references/sd-simplysm-v14/sd-claude}/hooks.md +15 -1
  226. package/claude/references/sd-simplysm-v14/sd-cli/README.md +138 -0
  227. package/claude/references/sd-simplysm-v14/sd-cli/angular-vite-plugin/sd-angular-plugin.md +60 -0
  228. package/claude/references/sd-simplysm-v14/sd-cli/config/build-target.md +31 -0
  229. package/claude/references/sd-simplysm-v14/sd-cli/config/npm-config.md +27 -0
  230. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-browser-support-config.md +19 -0
  231. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-build-package-config.md +21 -0
  232. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-capacitor-config.md +109 -0
  233. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-client-package-config.md +33 -0
  234. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-config.md +78 -0
  235. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-electron-config.md +27 -0
  236. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-package-config.md +18 -0
  237. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-post-publish-script-config.md +19 -0
  238. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-publish-config.md +72 -0
  239. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-pwa-config.md +41 -0
  240. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-scripts-package-config.md +19 -0
  241. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-server-package-config.md +32 -0
  242. package/claude/references/sd-simplysm-v14/sd-cli/config/sd-watch-hook-config.md +19 -0
  243. package/claude/references/sd-simplysm-v14/sd-cli/ts-compiler/sd-ts-compiler.md +158 -0
  244. package/claude/references/sd-simplysm-v14/service-client/README.md +74 -0
  245. package/claude/references/sd-simplysm-v14/service-client/features/event-client.md +93 -0
  246. package/claude/references/sd-simplysm-v14/service-client/features/file-client.md +63 -0
  247. package/claude/references/sd-simplysm-v14/service-client/features/orm-client-connector.md +89 -0
  248. package/claude/references/sd-simplysm-v14/service-client/features/orm-client-db-context-executor.md +31 -0
  249. package/claude/references/sd-simplysm-v14/service-client/main/service-client.md +206 -0
  250. package/claude/references/sd-simplysm-v14/service-client/protocol/client-protocol-wrapper.md +64 -0
  251. package/claude/references/sd-simplysm-v14/service-client/transport/service-transport.md +68 -0
  252. package/claude/references/sd-simplysm-v14/service-client/transport/socket-provider.md +100 -0
  253. package/claude/references/sd-simplysm-v14/service-client/types/blob-input.md +7 -0
  254. package/claude/references/sd-simplysm-v14/service-client/types/browser-worker.md +47 -0
  255. package/claude/references/sd-simplysm-v14/service-client/types/file-collection.md +21 -0
  256. package/claude/references/sd-simplysm-v14/service-client/types/service-connection-options.md +22 -0
  257. package/claude/references/sd-simplysm-v14/service-client/types/service-progress.md +39 -0
  258. package/claude/references/sd-simplysm-v14/service-common/README.md +161 -0
  259. package/claude/references/sd-simplysm-v14/service-common/app-structure/app-structure-item.md +107 -0
  260. package/claude/references/sd-simplysm-v14/service-common/app-structure/get-flat-permissions.md +57 -0
  261. package/claude/references/sd-simplysm-v14/service-common/app-structure/is-usable-modules-chain.md +23 -0
  262. package/claude/references/sd-simplysm-v14/service-common/app-structure/is-usable-modules.md +42 -0
  263. package/claude/references/sd-simplysm-v14/service-common/events/define-event.md +68 -0
  264. package/claude/references/sd-simplysm-v14/service-common/protocol/create-service-protocol.md +93 -0
  265. package/claude/references/sd-simplysm-v14/service-common/protocol/protocol-config.md +21 -0
  266. package/claude/references/sd-simplysm-v14/service-common/protocol/service-add-event-listener-message.md +23 -0
  267. package/claude/references/sd-simplysm-v14/service-common/protocol/service-auth-message.md +17 -0
  268. package/claude/references/sd-simplysm-v14/service-common/protocol/service-emit-event-message.md +21 -0
  269. package/claude/references/sd-simplysm-v14/service-common/protocol/service-error-message.md +29 -0
  270. package/claude/references/sd-simplysm-v14/service-common/protocol/service-event-message.md +21 -0
  271. package/claude/references/sd-simplysm-v14/service-common/protocol/service-get-event-listener-infos-message.md +19 -0
  272. package/claude/references/sd-simplysm-v14/service-common/protocol/service-message.md +52 -0
  273. package/claude/references/sd-simplysm-v14/service-common/protocol/service-progress-message.md +21 -0
  274. package/claude/references/sd-simplysm-v14/service-common/protocol/service-remove-event-listener-message.md +19 -0
  275. package/claude/references/sd-simplysm-v14/service-common/protocol/service-request-message.md +17 -0
  276. package/claude/references/sd-simplysm-v14/service-common/protocol/service-response-message.md +17 -0
  277. package/claude/references/sd-simplysm-v14/service-common/service-types/app-structure-service.md +15 -0
  278. package/claude/references/sd-simplysm-v14/service-common/service-types/auto-update-service.md +20 -0
  279. package/claude/references/sd-simplysm-v14/service-common/service-types/orm-service.md +61 -0
  280. package/claude/references/sd-simplysm-v14/service-common/types/service-upload-result.md +19 -0
  281. package/claude/references/sd-simplysm-v14/service-server/README.md +162 -0
  282. package/claude/references/sd-simplysm-v14/service-server/auth/auth-token-payload.md +18 -0
  283. package/claude/references/sd-simplysm-v14/service-server/auth/sign-jwt.md +30 -0
  284. package/claude/references/sd-simplysm-v14/service-server/auth/verify-jwt.md +35 -0
  285. package/claude/references/sd-simplysm-v14/service-server/core/auth.md +64 -0
  286. package/claude/references/sd-simplysm-v14/service-server/core/define-service.md +81 -0
  287. package/claude/references/sd-simplysm-v14/service-server/core/execute-service-method.md +43 -0
  288. package/claude/references/sd-simplysm-v14/service-server/core/service-context.md +79 -0
  289. package/claude/references/sd-simplysm-v14/service-server/legacy/handle-v1-connection.md +25 -0
  290. package/claude/references/sd-simplysm-v14/service-server/main/create-service-server.md +32 -0
  291. package/claude/references/sd-simplysm-v14/service-server/main/service-server.md +113 -0
  292. package/claude/references/sd-simplysm-v14/service-server/protocol/server-protocol-wrapper.md +35 -0
  293. package/claude/references/sd-simplysm-v14/service-server/services/app-structure-service.md +59 -0
  294. package/claude/references/sd-simplysm-v14/service-server/services/auto-update-service.md +34 -0
  295. package/claude/references/sd-simplysm-v14/service-server/services/orm-service.md +43 -0
  296. package/claude/references/sd-simplysm-v14/service-server/transport-http/handle-http-request.md +33 -0
  297. package/claude/references/sd-simplysm-v14/service-server/transport-http/handle-static-file.md +29 -0
  298. package/claude/references/sd-simplysm-v14/service-server/transport-http/handle-upload.md +33 -0
  299. package/claude/references/sd-simplysm-v14/service-server/transport-socket/service-socket.md +64 -0
  300. package/claude/references/sd-simplysm-v14/service-server/transport-socket/websocket-handler.md +57 -0
  301. package/claude/references/sd-simplysm-v14/service-server/types/service-server-options.md +36 -0
  302. package/claude/references/sd-simplysm-v14/service-server/utils/get-config.md +29 -0
  303. package/claude/references/sd-simplysm-v14/storage/README.md +99 -0
  304. package/claude/references/sd-simplysm-v14/storage/clients/ftp-storage-client.md +99 -0
  305. package/claude/references/sd-simplysm-v14/storage/clients/sftp-storage-client.md +108 -0
  306. package/claude/references/sd-simplysm-v14/storage/factory/storage-factory.md +114 -0
  307. package/claude/references/sd-simplysm-v14/storage/types/file-info.md +32 -0
  308. package/claude/references/sd-simplysm-v14/storage/types/storage-client.md +55 -0
  309. package/claude/references/sd-simplysm-v14/storage/types/storage-conn-config.md +34 -0
  310. package/claude/rules/sd-claude-rules.md +8 -8
  311. package/claude/rules/sd-simplysm-v14.md +33 -0
  312. package/claude/skills/sd-claude-docs/SKILL.md +41 -24
  313. package/claude/skills/sd-claude-docs/references/package-docs.md +240 -116
  314. package/claude/skills/sd-inner-debug/SKILL.md +1 -1
  315. package/claude/skills/sd-inner-review/SKILL.md +4 -2
  316. package/package.json +2 -3
  317. /package/{docs → claude/references/sd-simplysm-v14/sd-claude}/cli.md +0 -0
  318. /package/{docs → claude/references/sd-simplysm-v14/sd-claude}/scripts.md +0 -0
@@ -0,0 +1,87 @@
1
+ ← [CRUD 상세폼 레시피 진입점](../crud-detail.md)
2
+
3
+ # 확장 E: 보조 기능 영역
4
+
5
+ > **선행:** [확장 A: 편집/저장](./extension-a-edit-save.md)
6
+
7
+ 확장 A(편집/저장)를 전제로, 메인 폼의 submit과 **별개인 보조 기능**(예: 다른 사용자로부터 권한 복사, 출력, 엑셀 다운로드 등)을 추가한다. 과거 `#toolTpl` 슬롯이 담당하던 역할을 소비 화면에 직접 인라인한다. 보조 영역은 control 뷰 상단 `<sd-dock>` 내부 / modal 뷰 하단 바 옆 / main 영역 내 별도 `<sd-form>` 중 하나에 배치한다. 뷰별 UI 배치 본문은 [확장 C](./extension-c-modal-view.md) / [확장 D](./extension-d-control-view.md)에서 처리한다.
8
+
9
+ **이 확장이 도입하는 요소:**
10
+
11
+ - **imports:** `SdSharedDataSelect` (`@simplysm/angular`), 앱 공용 `useSharedSignal` (예: `@adtek/client-common` — `SdSharedDataProvider` 위에 각 앱이 정의하는 공용 훅)
12
+ - **상태:** 예시 — `permCopySourceId = signal<number | undefined>(undefined)`, `sharedUsers = useSharedSignal("사용자")`
13
+ - **메서드:** 예시 — `onImportFormSubmit` (권한·busy 가드 + 메인 폼 변경 보호 호출 + 앱별 ORM 조회·병합)
14
+ - **템플릿 추가:** 보조 `<sd-form (formSubmit)="onImportFormSubmit()">` 블록을 배치(아래 예시는 control 뷰 `<sd-dock>` 내부). 메인 `<sd-form #formCtrl>`과 **별도** 인스턴스
15
+ - **공유 데이터 대기:** 본 확장이 `useSharedSignal`을 도입하므로 `_refresh()` 선두에 `await this._sdSharedData.wait();`가 필요해진다 → [공통 규칙: `_sdSharedData.wait()`](../_common-rules.md#공유-데이터-사용-화면은-_refresh-선두에서-_sdshareddatawait를-호출한다)
16
+
17
+ > 상세: [`<sd-shared-data-select>`](../../ui-form/sd-shared-data-select.md)
18
+
19
+ > **아래 코드 블록은 diff 조각이다.** 독립 실행 가능한 완성 클래스가 아니며, 선행 확장(A) 위에 번호 순서대로 삽입할 지점을 나타낸다. 그대로 컴파일되지 않는다.
20
+
21
+ ```typescript
22
+ // 1) imports 추가
23
+ import { SdSharedDataSelect } from "@simplysm/angular";
24
+ // 앱 공용 훅 — @simplysm/angular 소유 아님. 각 앱이 SdSharedDataProvider 위에 정의.
25
+ import { useSharedSignal } from "@adtek/client-common";
26
+
27
+ // 2) 클래스에 상태 추가
28
+ protected readonly permCopySourceId = signal<number | undefined>(undefined);
29
+ protected readonly sharedUsers = useSharedSignal("사용자");
30
+
31
+ // 3) template — 보조 form 블록을 배치한다. 아래는 control 뷰 <sd-dock>(상단 바) 내부 예시.
32
+ // modal 뷰는 하단 바(<sd-dock [position]="'bottom'">) 옆, main 영역은 메인 form 옆이나 아래에 배치할 수 있다.
33
+ @if (viewType() === "control" && canEdit()) {
34
+ <sd-dock class="p-default flex-row gap-default bdb bdb-theme-gray-lightest">
35
+ <!-- 기본 저장/삭제 버튼 (확장 D) -->
36
+ <!-- ... -->
37
+
38
+ <!-- 보조 기능: 다른 사용자로부터 가져오기 -->
39
+ <sd-form (formSubmit)="onImportFormSubmit()">
40
+ <div class="form-box-inline">
41
+ <div class="form-box-item">
42
+ <label>가져오기</label>
43
+ <sd-shared-data-select
44
+ [items]="sharedUsers.items()"
45
+ [(value)]="permCopySourceId"
46
+ [inset]="true"
47
+ [size]="'sm'"
48
+ />
49
+ </div>
50
+ <div class="form-box-item">
51
+ <sd-button [type]="'submit'" [disabled]="permCopySourceId() == null">
52
+ 가져오기
53
+ </sd-button>
54
+ </div>
55
+ </div>
56
+ </sd-form>
57
+ </sd-dock>
58
+ }
59
+
60
+ // 4) 메서드 추가
61
+ protected async onImportFormSubmit(): Promise<void> {
62
+ if (this.busyCount() > 0 || !this.perms().includes("edit")) return;
63
+ if (this.permCopySourceId() == null) return;
64
+ // 메인 폼의 미저장 변경사항 보호 — 확장 A가 제공하는 _checkIgnoreChanges() 재호출
65
+ if (!this._checkIgnoreChanges()) return;
66
+
67
+ this.busyCount.update((v) => v + 1);
68
+ await this._sdToast.try(async () => {
69
+ // 앱별 서버 호출로 다른 사용자의 데이터를 조회·병합 — 예:
70
+ // const src = await this._appOrm.connectAsync(async (db) =>
71
+ // (await db.customer.where((it) => [expr.eq(it.id, this.permCopySourceId())]).single())!
72
+ // );
73
+ // this.data.set({ ...this.data(), ...src });
74
+ });
75
+ this.busyCount.update((v) => v - 1);
76
+ }
77
+ ```
78
+
79
+ **포인트:**
80
+
81
+ - **보조 `<sd-form>`은 메인 `<sd-form #formCtrl>`과 별도 인스턴스**다. `SdCommandDirective.sdSaveCommand` → `formCtrl()?.requestSubmit()` 경로는 메인 form 한 곳에만 연결된다(확장 A). 보조 form의 submit 버튼은 Ctrl+S와 연동되지 않고 버튼 클릭(또는 submit 버튼에서 Enter 제출)만 발동한다. 보조 form에는 `#formCtrl` template 변수를 부여하지 않는다.
82
+ - **보조 작업 전에도 `_checkIgnoreChanges()`를 호출**하여 메인 폼의 미저장 변경사항을 보호한다. 보조 form이 메인 `data()`를 덮어쓰는 경우(권한 복사 등) 필수. `_checkIgnoreChanges`는 확장 A가 제공하므로 재정의하지 않는다.
83
+ - **공유 데이터 도입으로 `_refresh()` 선두에 `await this._sdSharedData.wait();`가 필요해진다.** 판정 기준·코드 예시는 [공통 규칙: `_sdSharedData.wait()`](../_common-rules.md#공유-데이터-사용-화면은-_refresh-선두에서-_sdshareddatawait를-호출한다) 참조.
84
+ - **`<sd-shared-data-select>`에 `[inset]="true" [size]="'sm'"`을 명시**한다. `<sd-dock>` 도구 바 내부 치수와 `form-box-inline` 간격이 sm 기준으로 정합하므로 인셋·사이즈를 생략하면 컨트롤 높이가 들쭉날쭉해진다.
85
+ - **배치 위치 선택:** control 뷰는 상단 `<sd-dock>` 안, modal 뷰는 하단 바(`<sd-dock [position]="'bottom'">`) 옆, main 영역에서는 메인 form과 나란한 별도 블록. 뷰 분기 본문 UI는 [확장 C](./extension-c-modal-view.md) / [확장 D](./extension-d-control-view.md)에서 정의한다.
86
+ - **읽기 전용 보조(출력·엑셀 다운로드 등)는 `<sd-form>` 래핑 없이 버튼 `(click)`으로 직접 처리 가능**하다. 입력 값을 수집하지 않는 단일 액션은 form submit 절차가 불필요하다. 이 경우 `_checkIgnoreChanges()` 호출도 상황에 맞게 판단한다(읽기 전용이라 메인 변경 보호가 불필요할 수 있음).
87
+ - **`useSharedSignal`은 `@simplysm/angular` 제공이 아님** — `SdSharedDataProvider`(`packages/angular/src/core/shared-data/sd-shared-data.provider.ts`) 위에서 각 앱이 정의하는 공용 훅이다. 배포 패키지 소속이 다르므로 import 경로 혼동에 주의한다.
@@ -0,0 +1,202 @@
1
+ ← [CRUD 상세폼 레시피 진입점](../crud-detail.md)
2
+
3
+ # 확장 F: 복합 상세 (내부 `<sd-sheet>`)
4
+
5
+ > **선행:** [확장 A: 편집/저장](./extension-a-edit-save.md)
6
+
7
+ 확장 A(편집/저장)를 전제로, 상세 폼 안에 **하위 컬렉션**(박스 목록, 품목 라인 등)을 편집하는 구조를 도입한다. `<sd-form>` 본문 내부에 `<sd-sheet>`를 중첩하고, 하위 컬렉션의 행 추가·수정·삭제는 `item.isDeleted = true` 플래그로 표현하여 `oneWayDiffs` 기반 일괄 저장에 포함시킨다.
8
+
9
+ **이 확장이 도입하는 요소:**
10
+
11
+ - **imports:** `SdSheet`, `SdSheetColumn`, `SdSheetColumnCellTemplate`, `SdAnchor`(하위 행 삭제/복구 아이콘 호스트), `Uuid`, `oneWayDiffs`(side-effect import), 아이콘 `tablerCirclePlus` / `tablerEraser` / `tablerRestore` (`mark`는 확장 A에서 이미 도입)
12
+ - **데이터 타입 확장:** `ICustomer.boxes: ICustomerBox[]` + `interface ICustomerBox { id: string; seq: number; note: string; isDeleted: boolean; }`
13
+ - **data 초기값:** `boxes: []` 필드 추가
14
+ - **시트 함수 (클래스 필드):** `boxTrackByFn`, `getBoxCellStyleFn`
15
+ - **메서드:** `onAddBoxButtonClick`, `onToggleDeleteBoxButtonClick`
16
+ - **템플릿:** main 영역 `<sd-form>` 내부를 [상단 단일 필드 블록 + 하위 컬렉션 도구 dock(`<sd-button>` "박스 추가") + 하위 `<sd-sheet>` 중첩] 구조로 교체
17
+ - **onSubmit 변경:** `_sdToast.try(...)` 블록 내부를 diff 계산(`data().boxes.oneWayDiffs(_dataSnapshot?.boxes, "id")`) + 일괄 제출로 교체
18
+
19
+ > 상세: [`<sd-sheet>`](../../ui-data/sd-sheet.md) · [`<sd-sheet-column>`](../../ui-data/sd-sheet.md#sdsheetcolumn) · [`[cell]`](../../ui-data/sd-sheet.md#sdsheetcolumncelltemplate) · [`<sd-anchor>`](../../ui-form/sd-anchor.md)
20
+
21
+ > **아래 코드 블록은 diff 조각이다.** 독립 실행 가능한 완성 클래스가 아니며, 선행 확장(A) 위에 번호 순서대로 삽입·교체할 지점을 나타낸다. 그대로 컴파일되지 않는다.
22
+
23
+ ```typescript
24
+ // 1) imports 추가 — @simplysm/angular에 {SdSheet, SdSheetColumn, SdSheetColumnCellTemplate, SdAnchor} 추가.
25
+ // @simplysm/core-common에서 {Uuid} 추가 + 프로토타입 확장 활성화용 side-effect import.
26
+ // 아이콘에 tablerCirclePlus / tablerEraser / tablerRestore 추가. (mark는 확장 A에서 이미 import됨)
27
+ import { SdSheet, SdSheetColumn, SdSheetColumnCellTemplate, SdAnchor } from "@simplysm/angular";
28
+ import { Uuid } from "@simplysm/core-common";
29
+ import { tablerCirclePlus, tablerEraser, tablerRestore } from "@ng-icons/tabler-icons";
30
+ import "@simplysm/core-common"; // Array.prototype.oneWayDiffs 활성화 (side-effect import)
31
+
32
+ // 2) 데이터 타입 확장 — 진입점 3.1 최소 뼈대의 ICustomer에 boxes 필드만 추가, ICustomerBox 신설
33
+ // (확장 B를 함께 적용하면 ICustomer.isDeleted 필드가 별도로 들어가며, 본 확장 단독 적용에는 포함되지 않는다)
34
+ interface ICustomer {
35
+ id: number | undefined;
36
+ name: string;
37
+ phone: string;
38
+ lastModifiedAt: DateTime | undefined;
39
+ lastModifiedBy: string | undefined;
40
+ boxes: ICustomerBox[]; // 하위 컬렉션 추가
41
+ }
42
+
43
+ interface ICustomerBox {
44
+ id: string; // 클라이언트 생성 UUID (서버 저장 시 교체 가능)
45
+ seq: number;
46
+ note: string;
47
+ isDeleted: boolean;
48
+ }
49
+
50
+ // 3) data 초기값에 boxes: [] 추가 — 진입점 3.1 최소 뼈대의 data = signal<ICustomer>({ ... }) 초기값에 포함
51
+
52
+ // 4) template — main 영역(<sd-dock-container> 안쪽 <sd-form> 내부)을
53
+ // [단일 필드 + 도구 dock + 시트]로 교체. 최종수정 표시 블록은 최소 뼈대와 동일.
54
+ <div class="flex-column fill">
55
+ <sd-form #formCtrl (formSubmit)="onSubmit()" class="flex-fill flex-column">
56
+ <!-- 상단 단일 필드 -->
57
+ <div class="p-default">
58
+ <table class="form-table">
59
+ <tbody>
60
+ <tr>
61
+ <th>명칭</th>
62
+ <td>
63
+ <sd-textfield
64
+ [type]="'text'"
65
+ [required]="true"
66
+ [disabled]="!canEdit()"
67
+ [(value)]="data().name"
68
+ />
69
+ </td>
70
+ </tr>
71
+ </tbody>
72
+ </table>
73
+ </div>
74
+
75
+ <!-- 하위 컬렉션 도구 영역 -->
76
+ @if (canEdit()) {
77
+ <div class="flex-row gap-sm p-xs-default">
78
+ <sd-button [size]="'sm'" [theme]="'link-primary'" (click)="onAddBoxButtonClick()">
79
+ <ng-icon [svg]="tablerCirclePlus" />
80
+ 박스 추가
81
+ </sd-button>
82
+ </div>
83
+ }
84
+
85
+ <!-- 하위 컬렉션 시트 -->
86
+ <div class="flex-fill">
87
+ <sd-sheet
88
+ [items]="data().boxes"
89
+ [trackByFn]="boxTrackByFn"
90
+ [getItemCellStyleFn]="getBoxCellStyleFn"
91
+ >
92
+ @if (canEdit()) {
93
+ <sd-sheet-column [fixed]="true" [key]="'_isDeleted'">
94
+ <ng-template #headerTpl>
95
+ <div class="p-xs-sm tx-center">
96
+ <ng-icon [svg]="tablerEraser" />
97
+ </div>
98
+ </ng-template>
99
+ <ng-template [cell]="data().boxes" let-item="item">
100
+ <div class="p-xs-sm tx-center">
101
+ <sd-anchor
102
+ [theme]="'danger'"
103
+ (click)="onToggleDeleteBoxButtonClick(item)"
104
+ >
105
+ <ng-icon [svg]="item.isDeleted ? tablerRestore : tablerEraser" />
106
+ </sd-anchor>
107
+ </div>
108
+ </ng-template>
109
+ </sd-sheet-column>
110
+ }
111
+ <sd-sheet-column [key]="'seq'" [header]="'박스#'">
112
+ <ng-template [cell]="data().boxes" let-item="item">
113
+ <sd-textfield
114
+ [type]="'number'"
115
+ [required]="true"
116
+ [disabled]="!canEdit()"
117
+ [(value)]="item.seq"
118
+ [inset]="true"
119
+ [size]="'sm'"
120
+ />
121
+ </ng-template>
122
+ </sd-sheet-column>
123
+ <sd-sheet-column [key]="'note'" [header]="'비고'">
124
+ <ng-template [cell]="data().boxes" let-item="item">
125
+ <sd-textfield
126
+ [type]="'text'"
127
+ [disabled]="!canEdit()"
128
+ [(value)]="item.note"
129
+ [inset]="true"
130
+ [size]="'sm'"
131
+ />
132
+ </ng-template>
133
+ </sd-sheet-column>
134
+ </sd-sheet>
135
+ </div>
136
+ </sd-form>
137
+ <!-- 최종수정 표시는 최소 뼈대와 동일 -->
138
+ </div>
139
+
140
+ // 5) 시트 함수 (클래스 필드) 추가
141
+ protected readonly boxTrackByFn = (item: ICustomerBox): string => item.id;
142
+
143
+ protected readonly getBoxCellStyleFn = (item: ICustomerBox): string | undefined =>
144
+ item.isDeleted ? "text-decoration: line-through;" : undefined;
145
+
146
+ // 6) 메서드 추가
147
+ protected onAddBoxButtonClick(): void {
148
+ const newBox: ICustomerBox = {
149
+ id: Uuid.generate().toString(),
150
+ seq: (this.data().boxes.at(-1)?.seq ?? 0) + 1,
151
+ note: "",
152
+ isDeleted: false,
153
+ };
154
+ this.data().boxes.push(newBox);
155
+ mark(this.data);
156
+ }
157
+
158
+ protected onToggleDeleteBoxButtonClick(item: ICustomerBox): void {
159
+ item.isDeleted = !item.isDeleted;
160
+ mark(this.data);
161
+ }
162
+
163
+ // 7) onSubmit의 _sdToast.try(...) 블록 내부 교체 — diff 계산 + 일괄 제출
164
+ await this._sdToast.try(async () => {
165
+ // 삭제 플래그가 섞여 있으면 사용자 확인
166
+ if (this.data().boxes.some((b) => b.isDeleted)) {
167
+ if (!confirm("삭제 표시된 박스가 있습니다. 정말 저장하시겠습니까?")) return;
168
+ }
169
+
170
+ // 하위 컬렉션 diff 계산 — 반환 type은 "create" | "update" | "same" 3종
171
+ const snapshotBoxes = this._dataSnapshot?.boxes ?? [];
172
+ const boxDiffs = this.data().boxes.oneWayDiffs(snapshotBoxes, "id");
173
+
174
+ // 앱별 ORM 호출:
175
+ // await this._appOrm.connectAsync(async (db) => {
176
+ // await db.customer().where((c) => [expr.eq(c.id, this.data().id)])
177
+ // .upsert(() => ({ name: this.data().name, phone: this.data().phone }));
178
+ // for (const d of boxDiffs) {
179
+ // if (d.type === "create") {
180
+ // await db.customerBox().insert({ ...d.item, customerId: this.data().id! });
181
+ // } else if (d.type === "update") {
182
+ // await db.customerBox().where((c) => [expr.eq(c.id, d.item.id)])
183
+ // .update(() => d.item);
184
+ // }
185
+ // }
186
+ // });
187
+
188
+ this._sdToast.success("저장되었습니다.");
189
+ // 확장 C(modal 뷰)가 함께 적용된 경우에만 존재: this.close.emit(true); — modal 호출 측에 결과 전달
190
+ await this._refresh();
191
+ });
192
+ ```
193
+
194
+ **포인트:**
195
+
196
+ - **하위 컬렉션의 삭제는 `isDeleted: true` 플래그로 표현한다.** 이것은 상위 테이블의 삭제 방식([공통 규칙: 삭제 방식](../_common-rules.md#삭제-방식은-db-스키마에-따라-결정한다))과 **무관**하게, `oneWayDiffs`가 `"delete"` 타입을 지원하지 않기 때문에 하위 컬렉션에서는 항상 이 방식을 사용한다. 반환 `type`은 `"create" | "update" | "same"` 3종뿐이다(`packages/core-common/src/extensions/arr-ext.types.ts:206`). 서버는 `isDeleted: true` row를 soft-delete 또는 물리 삭제로 처리한다.
197
+ - **시트 셀 내부 컨트롤은 `[inset]="true" [size]="'sm'"` 명시 필수** — [공통 규칙: 시트 셀 `[inset]/[size]`](../_common-rules.md#시트-셀-내부-컨트롤에-insettrue-sizesm을-명시한다).
198
+ - **`data().boxes.push(newBox)` 같은 배열 mutation 후에는 `mark(this.data)`로 signal 참조를 갱신한다** — OnPush 템플릿 재렌더링·연계 computed 갱신 용도의 **통지**이며, 값 비교(저장 감지)와는 별개다: [공통 규칙: `mark(sig)`…](../_common-rules.md#marksig를-저장-감지-수단으로-사용하지-않는다).
199
+ - **`id`는 클라이언트에서 UUID로 생성** — `Uuid.generate().toString()`으로 문자열 key를 만들어 `trackByFn` + `oneWayDiffs`의 key로 사용한다. 서버가 발급한 PK가 별도로 있다면 별도 컬럼으로 관리하고 클라이언트 UUID는 row 식별자로만 쓴다.
200
+ - **삭제 플래그 혼재 시 `confirm`** — `this.data().boxes.some((b) => b.isDeleted)`이면 저장 직전 사용자 확인을 요청한다.
201
+
202
+ > 공통 규칙(시트 셀 `[inset]/[size]`, `mark` 오용, 상위 테이블 soft-delete 선택 기준)은 [레시피 공통 규칙](../_common-rules.md)을 참조한다.
@@ -0,0 +1,280 @@
1
+ # Recipe: CRUD 상세폼 화면 직접 조립
2
+
3
+ 단일 레코드 CRUD 상세폼을, `<sd-busy-container>` · `<sd-topbar-container>` · `<sd-topbar>` · `<sd-form>` 표준 컴포넌트를 소비 화면이 **직접 조립**하여 구성한다. 과거 `SdDataDetail` / `SdDataDetailBase`가 감추고 있던 load·save·delete 라이프사이클, snapshot 기반 변경 감지, 이탈 방지, busy 카운트, Ctrl+S 단축키를 화면 내부에 인라인으로 풀어쓴다.
4
+
5
+ ## When to use / When NOT to use
6
+
7
+ - ✅ 단일 레코드(고객, 주문 헤더 등)의 CRUD 상세폼을 만들 때
8
+ - ✅ page / modal / control 뷰 중 **필요한 뷰만 선택적으로** 지원해야 할 때
9
+ - ✅ 편집·저장·삭제·복구·보조 기능·복합 상세(내부 시트)를 상황에 따라 누적해야 할 때
10
+ - ❌ CRUD 리스트(시트) 화면 → [`crud-list.md`](./crud-list.md)
11
+ - ❌ 페이지/모달 뷰 분기만 필요한 단순 컨테이너(라이프사이클 없음) → [`page-modal-container.md`](./page-modal-container.md)
12
+ - ❌ 다른 화면에서 데이터를 고르는 선택 버튼 → [`data-select-button.md`](./data-select-button.md)
13
+
14
+ ## 전제조건
15
+
16
+ - `provideSdAngular({ clientName })` 부트스트랩 완료
17
+ - 앱별 ORM provider (예: `AppOrmProvider`) — `@simplysm/angular`가 아니라 각 앱이 소유
18
+ - 권한 제어가 있는 경우 `SdAppStructureProvider` 등록 (`injectPermsSignal` 전제)
19
+ - 횡단 규칙: [`_common-rules.md`](./_common-rules.md)에 정의된 공통 규칙을 모두 준수한다
20
+ - [화면 레이아웃 구간과 버튼 스타일 구분](./_common-rules.md#화면-레이아웃-구간과-버튼-스타일을-구분한다)
21
+ - [page 컴포넌트가 `<sd-topbar>`를 소유](./_common-rules.md#page-컴포넌트가-sd-topbar-container와-sd-topbar를-소유한다)
22
+
23
+ ## 기본 레시피 (page 뷰, 읽기 전용)
24
+
25
+ 라우트 진입 시 `itemId`를 받아 단일 레코드를 로드하고 읽기 전용 필드로 표시하는 최소 완성 컴포넌트다. 편집·삭제·modal·control·보조·복합이 필요하면 [변형](#변형-확장-a-f-인덱스)의 확장을 선택적으로 얹는다.
26
+
27
+ ```typescript
28
+ import {
29
+ ChangeDetectionStrategy,
30
+ Component,
31
+ effect,
32
+ inject,
33
+ input,
34
+ signal,
35
+ untracked,
36
+ ViewEncapsulation,
37
+ } from "@angular/core";
38
+ import type { DateTime } from "@simplysm/core-common";
39
+ import {
40
+ FormatPipe,
41
+ injectPermsSignal,
42
+ injectViewTitleSignal,
43
+ SdBusyContainer,
44
+ SdButton,
45
+ SdForm,
46
+ SdTextfield,
47
+ SdToastProvider,
48
+ SdTopbar,
49
+ SdTopbarContainer,
50
+ } from "@simplysm/angular";
51
+ // 앱별 대체: ORM provider + DbContext. @simplysm/angular가 아니라 각 앱이 소유한다.
52
+ import { AppOrmProvider } from "@adtek/client-common";
53
+
54
+ interface ICustomer {
55
+ id: number | undefined; // undefined면 신규 — 확장 A 편집/저장 시 활용
56
+ name: string;
57
+ phone: string;
58
+ lastModifiedAt: DateTime | undefined;
59
+ lastModifiedBy: string | undefined;
60
+ }
61
+
62
+ @Component({
63
+ selector: "app-customer-detail",
64
+ changeDetection: ChangeDetectionStrategy.OnPush,
65
+ encapsulation: ViewEncapsulation.None,
66
+ standalone: true,
67
+ imports: [
68
+ SdBusyContainer, SdTopbarContainer, SdTopbar,
69
+ SdForm, SdButton, SdTextfield,
70
+ FormatPipe,
71
+ ],
72
+ template: `
73
+ <sd-busy-container [busy]="busyCount() > 0">
74
+ @if (initialized()) {
75
+ <sd-topbar-container>
76
+ <sd-topbar>
77
+ <h4>{{ viewTitle() }}</h4>
78
+ </sd-topbar>
79
+
80
+ <div class="flex-column fill">
81
+ <sd-form class="flex-fill">
82
+ <div class="p-default">
83
+ <table class="form-table">
84
+ <tbody>
85
+ <tr>
86
+ <th>명칭</th>
87
+ <td>
88
+ <sd-textfield
89
+ [type]="'text'"
90
+ [readonly]="true"
91
+ [(value)]="data().name"
92
+ />
93
+ </td>
94
+ </tr>
95
+ <tr>
96
+ <th>전화번호</th>
97
+ <td>
98
+ <sd-textfield
99
+ [type]="'text'"
100
+ [readonly]="true"
101
+ [(value)]="data().phone"
102
+ />
103
+ </td>
104
+ </tr>
105
+ </tbody>
106
+ </table>
107
+ </div>
108
+ </sd-form>
109
+
110
+ @if (data().lastModifiedAt || data().lastModifiedBy) {
111
+ <div class="p-sm-default">
112
+ 최종수정:
113
+ @if (data().lastModifiedAt) {
114
+ {{ data().lastModifiedAt | format: "yyyy-MM-dd HH:mm" }}
115
+ }
116
+ @if (data().lastModifiedBy) {
117
+ ({{ data().lastModifiedBy }})
118
+ }
119
+ </div>
120
+ }
121
+ </div>
122
+ </sd-topbar-container>
123
+ }
124
+ </sd-busy-container>
125
+ `,
126
+ })
127
+ export class CustomerDetail {
128
+ //== DI ==
129
+ private readonly _appOrm = inject(AppOrmProvider);
130
+ private readonly _sdToast = inject(SdToastProvider);
131
+
132
+ //== input ==
133
+ itemId = input<number>();
134
+
135
+ //== 타이틀 / 권한 ==
136
+ protected readonly viewTitle = injectViewTitleSignal();
137
+ perms = injectPermsSignal(["sales.customer"], ["use"]);
138
+
139
+ //== 상태 ==
140
+ protected readonly busyCount = signal(0);
141
+ protected readonly initialized = signal(false);
142
+ protected readonly data = signal<ICustomer>({
143
+ id: undefined,
144
+ name: "",
145
+ phone: "",
146
+ lastModifiedAt: undefined,
147
+ lastModifiedBy: undefined,
148
+ });
149
+
150
+ //== 라이프사이클 ==
151
+ constructor() {
152
+ // 최초 진입 + itemId 변경 시 재조회.
153
+ effect(() => {
154
+ this.itemId(); // 의존성 등록
155
+ if (!this.perms().includes("use")) {
156
+ this.initialized.set(true);
157
+ return;
158
+ }
159
+
160
+ void untracked(async () => {
161
+ this.busyCount.update((v) => v + 1);
162
+ await this._sdToast.try(async () => {
163
+ await this._refresh();
164
+ });
165
+ this.busyCount.update((v) => v - 1);
166
+ this.initialized.set(true);
167
+ });
168
+ });
169
+ }
170
+
171
+ //== 내부 메서드 ==
172
+ private async _refresh(): Promise<void> {
173
+ let data: ICustomer;
174
+ if (this.itemId() == null) {
175
+ data = {
176
+ id: undefined, name: "", phone: "",
177
+ lastModifiedAt: undefined, lastModifiedBy: undefined,
178
+ };
179
+ } else {
180
+ // 앱별 ORM 조회 — 예:
181
+ // data = await this._appOrm.connectAsync(async (db) =>
182
+ // (await db.customer.where((it) => [expr.eq(it.id, this.itemId())]).single())!
183
+ // );
184
+ throw new Error("구현 필요");
185
+ }
186
+
187
+ this.data.set(data);
188
+ }
189
+
190
+ }
191
+ ```
192
+
193
+ ### 조건부 요소 포함 기준
194
+
195
+ 인프라·라이프사이클 요소는 화면 요건에 따라 포함·생략한다. 필요 없는 요소를 기계적으로 포함하지 않는다.
196
+
197
+ | 요소 | 포함 조건 | 생략 예시 |
198
+ |------|----------|----------|
199
+ | `<sd-topbar-container>` + `<sd-topbar>` | routes로 연결된 page에서 헤더가 필요할 때. 기본 레시피는 page 전용이라 조건 없이 렌더 | route 미연결(control·래퍼) |
200
+ | `injectViewTitleSignal()` | topbar에 타이틀을 표시할 때 | topbar 없음·타이틀 불필요 |
201
+ | `injectViewTypeSignal()` + 분기 | page 외에 modal/control로도 겸용될 때. 기본 레시피는 page 전용이므로 **미포함** — [확장 C](./crud-detail/extension-c-modal-view.md) / [확장 D](./crud-detail/extension-d-control-view.md)에서 도입 | page 전용 |
202
+ | `injectPermsSignal()` + effect 내 권한 체크 | 권한 제어가 있는 화면. effect에서 `perms().includes("use")` 검사 후 미보유 시 `return` | 권한 제어 없음 |
203
+ | `<sd-busy-container>` + `busyCount` | 비동기 작업(DB 조회 등)이 있어 busy 표시가 필요할 때 | 동기 래퍼·레이아웃 |
204
+ | `initialized` + `@if (initialized())` | 초기 로딩 완료 전 깜박임 방지가 필요할 때 | 빈 상태 렌더가 무방 |
205
+
206
+ ## 변형 (확장 A~F 인덱스)
207
+
208
+ | 상황 | 시작 지점 + 필요한 확장 |
209
+ |---|---|
210
+ | 단일 레코드 **읽기 전용 상세 폼** (page 뷰, 감사 필드 표시) | 기본 레시피만 |
211
+ | 편집·저장 가능한 단일 레코드 상세 폼 | 기본 + [확장 A](./crud-detail/extension-a-edit-save.md) |
212
+ | 삭제·복구 토글 포함 | 기본 + A + [확장 B](./crud-detail/extension-b-delete-restore.md) |
213
+ | page + **modal 뷰** 재사용 (확인·취소·삭제·복구 하단 바) | 기본 + A + B + [확장 C](./crud-detail/extension-c-modal-view.md) |
214
+ | 마스터-디테일의 "디테일" 영역 (**control 뷰**) | 기본 + A + B + [확장 D](./crud-detail/extension-d-control-view.md) |
215
+ | page + modal + control **3뷰** 모두 지원 | 기본 + A + B + C + D |
216
+ | 메인 폼과 별개의 **보조 기능** (가져오기/출력 등) | 기본 + A + [확장 E](./crud-detail/extension-e-auxiliary.md) |
217
+ | 상세 폼 내부에 **하위 컬렉션** 편집 (박스 목록 등) | 기본 + A + [확장 F](./crud-detail/extension-f-complex-detail.md) |
218
+
219
+ ### 각 확장 요약
220
+
221
+ - **A. 편집/저장** (선행: 없음) — 읽기 전용을 편집 가능으로 전환. snapshot 기반 변경 감지, `setupCanDeactivate` 이탈 방지, Ctrl+S 일괄 저장. → [상세](./crud-detail/extension-a-edit-save.md)
222
+ - **B. 삭제/복구 토글** (선행: A) — soft-delete 전제. `isDeleted` 필드 + 삭제·복구 버튼. → [상세](./crud-detail/extension-b-delete-restore.md)
223
+ - **C. modal 뷰** (선행: A + B) — `SdModalContentDef` 계약, 하단 액션 바, 모달 우측 상단 액션 슬롯. → [상세](./crud-detail/extension-c-modal-view.md)
224
+ - **D. control 뷰** (선행: A + B) — 마스터-디테일 디테일 영역. 상단 `<sd-dock>` 도구 바. 확장 C와 병행 가능. → [상세](./crud-detail/extension-d-control-view.md)
225
+ - **E. 보조 기능 영역** (선행: A) — 메인 submit과 분리된 보조 `<sd-form>`. 권한 복사·출력 등. → [상세](./crud-detail/extension-e-auxiliary.md)
226
+ - **F. 복합 상세** (선행: A) — 내부 `<sd-sheet>` 중첩, `oneWayDiffs` 기반 일괄 저장. → [상세](./crud-detail/extension-f-complex-detail.md)
227
+
228
+ ## 🚫 흔한 실수 (Anti-patterns)
229
+
230
+ > 공통 규칙(`mark` 오용, `injectViewTypeSignal()` 호출 위치, `_sdSharedData.wait()` 조건, 시트 셀 `[inset]`/`[size]`, soft-delete 선택 기준 등)은 [레시피 공통 규칙](./_common-rules.md)을 참조한다. 이 섹션은 **CRUD 상세폼 진입점 고유 실수**만 다룬다.
231
+
232
+ ### 지원할 뷰를 확인하지 않고 3뷰 분기를 미리 박는다
233
+
234
+ ```typescript
235
+ // ✅ 기본 레시피는 page 전용으로 시작. 필요한 뷰가 생기면 확장을 얹는다
236
+ // modal 뷰가 필요해지는 시점에 확장 C를, control 뷰는 확장 D를 추가.
237
+ @Component({ /* ... */ })
238
+ export class CustomerDetail {
239
+ itemId = input<number>();
240
+ // page 전용 — viewType 분기·close output 없음
241
+ }
242
+ ```
243
+
244
+ **근거**: 실제 호출되지 않는 뷰의 계약·분기·슬롯은 죽은 코드로 남아 LLM이 모달 사용처 탐색 시 오판 원인이 된다. 지원할 뷰를 먼저 확정하고 필요한 확장만 얹는다.
245
+
246
+ ### `effect` 내부 비동기 호출을 `untracked`로 감싸지 않는다
247
+
248
+ ```typescript
249
+ // ✅ 비동기 작업은 untracked로 감싸 의존성 등록을 차단한다
250
+ constructor() {
251
+ effect(() => {
252
+ this.itemId(); // 여기서만 의존성 등록
253
+ void untracked(async () => {
254
+ await this._sdToast.try(() => this._refresh());
255
+ });
256
+ });
257
+ }
258
+ ```
259
+
260
+ **근거**: Angular `effect`는 콜백 실행 중 읽힌 모든 signal을 의존성으로 등록한다. 비동기 함수 내부에서 signal을 읽으면 effect가 재실행되어 무한 루프가 발생한다.
261
+
262
+ ### `setupCanDeactivate`를 `computed`·`effect`·일반 메서드에서 호출한다
263
+
264
+ ```typescript
265
+ // ✅ 생성자(또는 필드 이니셜라이저)에서만 호출
266
+ constructor() {
267
+ setupCanDeactivate(() => !this._dirty());
268
+ }
269
+ ```
270
+
271
+ **근거**: `setupCanDeactivate`는 내부에서 `inject(Router)` 등을 사용하므로 injection context가 필수다. computed/effect 콜백이나 일반 메서드 호출 시점엔 context가 없다.
272
+
273
+ ## 관련 Entry
274
+
275
+ - [`crud-list.md`](./crud-list.md) — 시트 기반 CRUD 리스트. 차이: 단일 레코드 vs 컬렉션
276
+ - [`page-modal-container.md`](./page-modal-container.md) — page/modal 뷰 분기만 필요한 단순 컨테이너. 차이: CRUD 라이프사이클 없음
277
+ - [`data-select-button.md`](./data-select-button.md) — 데이터 선택 버튼. 차이: 모달 내부 선택 UI
278
+ - [`_common-rules.md`](./_common-rules.md) — 레시피 공통 규칙 (✅ Always / ⚠️ Ask first / 🚫 Never)
279
+ - [`SdModalContentDef`](../provider-types/sd-modal-content-def.md) — 확장 C(modal 뷰)에서 구현하는 계약
280
+ - [`SdModalProvider.showAsync`](../providers/sd-modal-provider.md) — 프로그래밍 방식 모달 호출