create-react-admin-template 0.0.0-stage → 0.1.0

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 (736) hide show
  1. package/README.md +46 -2
  2. package/bin/create.mjs +5 -0
  3. package/package.json +22 -4
  4. package/template/.dockerignore +12 -0
  5. package/template/.editorconfig +12 -0
  6. package/template/.env +14 -0
  7. package/template/.env.development +5 -0
  8. package/template/.env.production +2 -0
  9. package/template/.env.test +5 -0
  10. package/template/.github/workflows/ci.yml +40 -0
  11. package/template/.gitlab-ci.yml +208 -0
  12. package/template/.husky/commit-msg +1 -0
  13. package/template/.husky/pre-commit +1 -0
  14. package/template/.nvmrc +1 -0
  15. package/template/.prettierignore +11 -0
  16. package/template/.prettierrc +47 -0
  17. package/template/Dockerfile +16 -0
  18. package/template/README.md +372 -0
  19. package/template/build/advancedTable.ts +103 -0
  20. package/template/build/environment.ts +150 -0
  21. package/template/commitlint.config.js +32 -0
  22. package/template/components.json +21 -0
  23. package/template/deploy/README.md +132 -0
  24. package/template/deploy/host-nginx/react-admin-api.conf +14 -0
  25. package/template/deploy/host-nginx/react-admin-web.conf +8 -0
  26. package/template/deploy/nginx.conf +38 -0
  27. package/template/docs/activity-status.md +217 -0
  28. package/template/docs/audit-logs.md +158 -0
  29. package/template/docs/authentication-adapters.md +219 -0
  30. package/template/docs/browser-security.md +58 -0
  31. package/template/docs/bundle-budgets.md +65 -0
  32. package/template/docs/component-source-governance.md +99 -0
  33. package/template/docs/data-masking.md +169 -0
  34. package/template/docs/enterprise-scaffold.md +208 -0
  35. package/template/docs/feature-data-template.md +227 -0
  36. package/template/docs/feature-flags.md +169 -0
  37. package/template/docs/file-capabilities.md +196 -0
  38. package/template/docs/locale-and-i18n.md +132 -0
  39. package/template/docs/mutation-idempotency.md +24 -0
  40. package/template/docs/optional-editors.md +203 -0
  41. package/template/docs/page-feedback.md +83 -0
  42. package/template/docs/query-data-conventions.md +178 -0
  43. package/template/docs/realtime-collaboration.md +140 -0
  44. package/template/docs/reporting-printing-templates.md +156 -0
  45. package/template/docs/scaffold-capability-roadmap.md +226 -0
  46. package/template/docs/scaffold-guide.md +443 -0
  47. package/template/docs/template-changelog.md +30 -0
  48. package/template/docs/template-versioning.md +26 -0
  49. package/template/docs/tenant-workspace-context.md +147 -0
  50. package/template/docs/unsaved-changes.md +58 -0
  51. package/template/docs/white-label.md +102 -0
  52. package/template/eslint.config.js +697 -0
  53. package/template/gitignore +39 -0
  54. package/template/index.html +26 -0
  55. package/template/knip.config.ts +42 -0
  56. package/template/lint-staged.config.js +8 -0
  57. package/template/package.json +133 -0
  58. package/template/pnpm-lock.yaml +8694 -0
  59. package/template/public/favicon.ico +0 -0
  60. package/template/public/logo.svg +1 -0
  61. package/template/public/runtime-config.json +49 -0
  62. package/template/scaffold.template.json +5 -0
  63. package/template/src/Application.tsx +114 -0
  64. package/template/src/api/ApiError.ts +33 -0
  65. package/template/src/api/activity/ActivityProvider.tsx +167 -0
  66. package/template/src/api/activity/access.ts +13 -0
  67. package/template/src/api/activity/errors.ts +17 -0
  68. package/template/src/api/activity/index.ts +67 -0
  69. package/template/src/api/activity/model.ts +227 -0
  70. package/template/src/api/activity/query.ts +163 -0
  71. package/template/src/api/activity/source.ts +16 -0
  72. package/template/src/api/activity/subscription.ts +292 -0
  73. package/template/src/api/activity/transports.ts +271 -0
  74. package/template/src/api/activity/types.ts +402 -0
  75. package/template/src/api/authClient.ts +134 -0
  76. package/template/src/api/authSession.ts +307 -0
  77. package/template/src/api/clients/configureApiClient.ts +62 -0
  78. package/template/src/api/clients/httpStatus.ts +4 -0
  79. package/template/src/api/config/services.json +7 -0
  80. package/template/src/api/demoAuthClient.ts +46 -0
  81. package/template/src/api/enums/EnumCatalogProvider.tsx +169 -0
  82. package/template/src/api/enums/EnumDictionary.ts +55 -0
  83. package/template/src/api/enums/access.ts +130 -0
  84. package/template/src/api/enums/catalog.ts +216 -0
  85. package/template/src/api/enums/errors.ts +21 -0
  86. package/template/src/api/enums/index.ts +48 -0
  87. package/template/src/api/enums/query.ts +82 -0
  88. package/template/src/api/enums/scope.ts +58 -0
  89. package/template/src/api/enums/types.ts +251 -0
  90. package/template/src/api/hooks/error.ts +198 -0
  91. package/template/src/api/hooks/index.ts +4 -0
  92. package/template/src/api/hooks/request.ts +99 -0
  93. package/template/src/api/hooks/requestId.ts +65 -0
  94. package/template/src/api/hooks/response.ts +22 -0
  95. package/template/src/api/hooks/types.ts +20 -0
  96. package/template/src/api/idempotency/index.ts +1 -0
  97. package/template/src/api/idempotency/key.ts +23 -0
  98. package/template/src/api/index.ts +14 -0
  99. package/template/src/api/metadata/MetadataProvider.tsx +37 -0
  100. package/template/src/api/metadata/index.ts +2 -0
  101. package/template/src/api/metadata/types.ts +30 -0
  102. package/template/src/api/parameters/GlobalParameterProvider.tsx +210 -0
  103. package/template/src/api/parameters/access.ts +117 -0
  104. package/template/src/api/parameters/catalog.ts +170 -0
  105. package/template/src/api/parameters/errors.ts +21 -0
  106. package/template/src/api/parameters/index.ts +53 -0
  107. package/template/src/api/parameters/query.ts +84 -0
  108. package/template/src/api/parameters/scope.ts +58 -0
  109. package/template/src/api/parameters/types.ts +214 -0
  110. package/template/src/api/query/index.ts +13 -0
  111. package/template/src/api/query/keys.ts +155 -0
  112. package/template/src/api/query/mutation.ts +48 -0
  113. package/template/src/api/query/react.ts +36 -0
  114. package/template/src/api/query/scope.ts +38 -0
  115. package/template/src/api/query/types.ts +147 -0
  116. package/template/src/api/types.ts +144 -0
  117. package/template/src/application/types.ts +52 -0
  118. package/template/src/auditLogs/errors.ts +17 -0
  119. package/template/src/auditLogs/export.ts +85 -0
  120. package/template/src/auditLogs/index.ts +54 -0
  121. package/template/src/auditLogs/model.ts +526 -0
  122. package/template/src/auditLogs/query.ts +113 -0
  123. package/template/src/auditLogs/react.ts +36 -0
  124. package/template/src/auditLogs/source.ts +51 -0
  125. package/template/src/auditLogs/types.ts +357 -0
  126. package/template/src/authentication/controller.ts +351 -0
  127. package/template/src/authentication/index.ts +8 -0
  128. package/template/src/authentication/redirect.ts +72 -0
  129. package/template/src/authentication/types.ts +300 -0
  130. package/template/src/bootstrap.tsx +96 -0
  131. package/template/src/components/AppDataTable/AppDataTable.tsx +74 -0
  132. package/template/src/components/AppDataTable/index.ts +2 -0
  133. package/template/src/components/AppDataTable/types.ts +27 -0
  134. package/template/src/components/AppDialog/AppConfirmDialog.tsx +44 -0
  135. package/template/src/components/AppDialog/AppDialog.tsx +113 -0
  136. package/template/src/components/AppDialog/index.ts +3 -0
  137. package/template/src/components/AppDialog/messages.tsx +22 -0
  138. package/template/src/components/AppDialog/types.ts +53 -0
  139. package/template/src/components/AppPageForm/AppPageForm.tsx +21 -0
  140. package/template/src/components/AppPageForm/PageForm.tsx +765 -0
  141. package/template/src/components/AppPageForm/SOURCE.md +26 -0
  142. package/template/src/components/AppPageForm/config.ts +253 -0
  143. package/template/src/components/AppPageForm/controller.ts +580 -0
  144. package/template/src/components/AppPageForm/index.ts +2 -0
  145. package/template/src/components/AppPageForm/messages.ts +90 -0
  146. package/template/src/components/AppPageForm/optionUtils.ts +91 -0
  147. package/template/src/components/AppPageForm/options.ts +397 -0
  148. package/template/src/components/AppPageForm/query.ts +44 -0
  149. package/template/src/components/AppPageForm/style.css +119 -0
  150. package/template/src/components/AppPageForm/types.ts +632 -0
  151. package/template/src/components/AppPageForm/validation.ts +233 -0
  152. package/template/src/components/AppTable/AppTable.tsx +26 -0
  153. package/template/src/components/AppTable/SOURCE.md +72 -0
  154. package/template/src/components/AppTable/cell/customCell/TableCellLayer.tsx +73 -0
  155. package/template/src/components/AppTable/cell/customCell/actions/ActionDropdownCell.tsx +104 -0
  156. package/template/src/components/AppTable/cell/customCell/cellLayer.ts +358 -0
  157. package/template/src/components/AppTable/cell/customCell/componentProps.ts +30 -0
  158. package/template/src/components/AppTable/cell/customCell/date/TemporalPickerEditor.tsx +54 -0
  159. package/template/src/components/AppTable/cell/customCell/index.ts +2 -0
  160. package/template/src/components/AppTable/cell/customCell/select/SelectCellEditor.tsx +225 -0
  161. package/template/src/components/AppTable/cell/customCell/tableCellLayer.css +20 -0
  162. package/template/src/components/AppTable/cell/customCell/tooltip/TooltipCell.tsx +45 -0
  163. package/template/src/components/AppTable/cell/customCell/types.ts +63 -0
  164. package/template/src/components/AppTable/cell/customCell/useCellLayerLifecycle.ts +111 -0
  165. package/template/src/components/AppTable/cell/frameworkCell/TableCellComponentLayer.tsx +40 -0
  166. package/template/src/components/AppTable/cell/frameworkCell/cellComponentSession.ts +203 -0
  167. package/template/src/components/AppTable/cell/frameworkCell/index.ts +3 -0
  168. package/template/src/components/AppTable/cell/index.ts +2 -0
  169. package/template/src/components/AppTable/columns/TableColumnEditor.tsx +257 -0
  170. package/template/src/components/AppTable/columns/index.ts +1 -0
  171. package/template/src/components/AppTable/columns/useTableColumnPreferenceActions.ts +85 -0
  172. package/template/src/components/AppTable/config/defaults.ts +46 -0
  173. package/template/src/components/AppTable/config/index.ts +2 -0
  174. package/template/src/components/AppTable/config/license.ts +39 -0
  175. package/template/src/components/AppTable/config/resolver.ts +25 -0
  176. package/template/src/components/AppTable/config/types.ts +377 -0
  177. package/template/src/components/AppTable/engine/bottom/index.ts +1 -0
  178. package/template/src/components/AppTable/engine/bottom/types.ts +14 -0
  179. package/template/src/components/AppTable/engine/cell/constants.ts +32 -0
  180. package/template/src/components/AppTable/engine/cell/customCell/actions/index.ts +1 -0
  181. package/template/src/components/AppTable/engine/cell/customCell/actions/renderer.ts +162 -0
  182. package/template/src/components/AppTable/engine/cell/customCell/date/index.ts +1 -0
  183. package/template/src/components/AppTable/engine/cell/customCell/date/renderer.ts +116 -0
  184. package/template/src/components/AppTable/engine/cell/customCell/editors/editorBounds.ts +57 -0
  185. package/template/src/components/AppTable/engine/cell/customCell/editors/editorTrigger.ts +46 -0
  186. package/template/src/components/AppTable/engine/cell/customCell/editors/index.ts +3 -0
  187. package/template/src/components/AppTable/engine/cell/customCell/editors/layerEditor.ts +244 -0
  188. package/template/src/components/AppTable/engine/cell/customCell/index.ts +7 -0
  189. package/template/src/components/AppTable/engine/cell/customCell/renderers/columnRenderer.ts +245 -0
  190. package/template/src/components/AppTable/engine/cell/customCell/renderers/confirmInput.ts +57 -0
  191. package/template/src/components/AppTable/engine/cell/customCell/renderers/display.ts +78 -0
  192. package/template/src/components/AppTable/engine/cell/customCell/renderers/index.ts +3 -0
  193. package/template/src/components/AppTable/engine/cell/customCell/renderers/itemList.ts +60 -0
  194. package/template/src/components/AppTable/engine/cell/customCell/renderers/links.ts +131 -0
  195. package/template/src/components/AppTable/engine/cell/customCell/renderers/selection.ts +41 -0
  196. package/template/src/components/AppTable/engine/cell/customCell/renderers/shared.ts +71 -0
  197. package/template/src/components/AppTable/engine/cell/customCell/renderers/step.ts +37 -0
  198. package/template/src/components/AppTable/engine/cell/customCell/renderers/switch.ts +45 -0
  199. package/template/src/components/AppTable/engine/cell/customCell/select/index.ts +1 -0
  200. package/template/src/components/AppTable/engine/cell/customCell/select/renderer.ts +33 -0
  201. package/template/src/components/AppTable/engine/cell/customCell/tooltip/index.ts +1 -0
  202. package/template/src/components/AppTable/engine/cell/customCell/tooltip/tooltip.ts +94 -0
  203. package/template/src/components/AppTable/engine/cell/customCell/types.ts +82 -0
  204. package/template/src/components/AppTable/engine/cell/formatting.ts +355 -0
  205. package/template/src/components/AppTable/engine/cell/formula.ts +145 -0
  206. package/template/src/components/AppTable/engine/cell/index.ts +7 -0
  207. package/template/src/components/AppTable/engine/cell/multiSelect.ts +96 -0
  208. package/template/src/components/AppTable/engine/cell/options.ts +339 -0
  209. package/template/src/components/AppTable/engine/cell/types.ts +53 -0
  210. package/template/src/components/AppTable/engine/columns/column.ts +430 -0
  211. package/template/src/components/AppTable/engine/columns/config/columns.ts +33 -0
  212. package/template/src/components/AppTable/engine/columns/config/index.ts +4 -0
  213. package/template/src/components/AppTable/engine/columns/config/mutation.ts +138 -0
  214. package/template/src/components/AppTable/engine/columns/config/temporal.ts +11 -0
  215. package/template/src/components/AppTable/engine/columns/config/validation.ts +106 -0
  216. package/template/src/components/AppTable/engine/columns/constants.ts +6 -0
  217. package/template/src/components/AppTable/engine/columns/gridColumns.ts +332 -0
  218. package/template/src/components/AppTable/engine/columns/index.ts +4 -0
  219. package/template/src/components/AppTable/engine/columns/rendererPolicies.ts +129 -0
  220. package/template/src/components/AppTable/engine/component/resolver.ts +272 -0
  221. package/template/src/components/AppTable/engine/component/types.ts +384 -0
  222. package/template/src/components/AppTable/engine/config/constants.ts +33 -0
  223. package/template/src/components/AppTable/engine/config/grid/compiler.ts +65 -0
  224. package/template/src/components/AppTable/engine/config/grid/defaults.ts +82 -0
  225. package/template/src/components/AppTable/engine/config/grid/ownership.ts +35 -0
  226. package/template/src/components/AppTable/engine/config/grid/runtimeDelta.ts +34 -0
  227. package/template/src/components/AppTable/engine/config/grid/types.ts +30 -0
  228. package/template/src/components/AppTable/engine/pagination/config.ts +75 -0
  229. package/template/src/components/AppTable/engine/pagination/constants.ts +5 -0
  230. package/template/src/components/AppTable/engine/pagination/index.ts +3 -0
  231. package/template/src/components/AppTable/engine/pagination/types.ts +70 -0
  232. package/template/src/components/AppTable/engine/preference/index.ts +2 -0
  233. package/template/src/components/AppTable/engine/preference/preference.ts +535 -0
  234. package/template/src/components/AppTable/engine/preference/types.ts +28 -0
  235. package/template/src/components/AppTable/engine/right/index.ts +1 -0
  236. package/template/src/components/AppTable/engine/right/types.ts +18 -0
  237. package/template/src/components/AppTable/engine/search/config.ts +64 -0
  238. package/template/src/components/AppTable/engine/search/constants.ts +8 -0
  239. package/template/src/components/AppTable/engine/search/index.ts +7 -0
  240. package/template/src/components/AppTable/engine/search/localQuery.ts +145 -0
  241. package/template/src/components/AppTable/engine/search/query.ts +203 -0
  242. package/template/src/components/AppTable/engine/search/remoteQuery.ts +99 -0
  243. package/template/src/components/AppTable/engine/search/searchInteraction.ts +46 -0
  244. package/template/src/components/AppTable/engine/search/types.ts +155 -0
  245. package/template/src/components/AppTable/engine/selection/config.ts +13 -0
  246. package/template/src/components/AppTable/engine/selection/index.ts +4 -0
  247. package/template/src/components/AppTable/engine/selection/selection.ts +357 -0
  248. package/template/src/components/AppTable/engine/selection/selectionHeader.ts +88 -0
  249. package/template/src/components/AppTable/engine/selection/types.ts +66 -0
  250. package/template/src/components/AppTable/engine/shared/action.ts +11 -0
  251. package/template/src/components/AppTable/engine/shared/constants.ts +2 -0
  252. package/template/src/components/AppTable/engine/shared/decimal.ts +114 -0
  253. package/template/src/components/AppTable/engine/shared/feedback.ts +62 -0
  254. package/template/src/components/AppTable/engine/shared/index.ts +13 -0
  255. package/template/src/components/AppTable/engine/shared/interaction.ts +55 -0
  256. package/template/src/components/AppTable/engine/shared/messages.ts +161 -0
  257. package/template/src/components/AppTable/engine/shared/row.ts +32 -0
  258. package/template/src/components/AppTable/engine/shared/scheduler.ts +17 -0
  259. package/template/src/components/AppTable/engine/shared/tableKey.ts +31 -0
  260. package/template/src/components/AppTable/engine/shared/theme.ts +196 -0
  261. package/template/src/components/AppTable/engine/shared/treeRows.ts +155 -0
  262. package/template/src/components/AppTable/engine/shared/types.ts +58 -0
  263. package/template/src/components/AppTable/engine/shared/valueSnapshot.ts +46 -0
  264. package/template/src/components/AppTable/engine/summary/config/export.ts +117 -0
  265. package/template/src/components/AppTable/engine/summary/config/index.ts +3 -0
  266. package/template/src/components/AppTable/engine/summary/config/summary.ts +62 -0
  267. package/template/src/components/AppTable/engine/summary/config/types.ts +93 -0
  268. package/template/src/components/AppTable/engine/summary/constants.ts +13 -0
  269. package/template/src/components/AppTable/engine/summary/excelJs.ts +133 -0
  270. package/template/src/components/AppTable/engine/summary/export.ts +311 -0
  271. package/template/src/components/AppTable/engine/summary/index.ts +6 -0
  272. package/template/src/components/AppTable/engine/summary/selectionSum.ts +92 -0
  273. package/template/src/components/AppTable/engine/summary/summary.ts +457 -0
  274. package/template/src/components/AppTable/engine/table/clipboard/index.ts +1 -0
  275. package/template/src/components/AppTable/engine/table/clipboard/transfer.ts +9 -0
  276. package/template/src/components/AppTable/engine/table/controller/TableController.ts +802 -0
  277. package/template/src/components/AppTable/engine/table/controller/errors.ts +106 -0
  278. package/template/src/components/AppTable/engine/table/controller/index.ts +4 -0
  279. package/template/src/components/AppTable/engine/table/controller/latestAbortableTask.ts +33 -0
  280. package/template/src/components/AppTable/engine/table/controller/tableDataReplacement.ts +60 -0
  281. package/template/src/components/AppTable/engine/table/controller/tableDomainConfiguration.ts +94 -0
  282. package/template/src/components/AppTable/engine/table/controller/tableEditingCommands.ts +163 -0
  283. package/template/src/components/AppTable/engine/table/controller/tableGridHost.ts +324 -0
  284. package/template/src/components/AppTable/engine/table/controller/tableIdentity.ts +68 -0
  285. package/template/src/components/AppTable/engine/table/controller/tableMutationPipeline.ts +79 -0
  286. package/template/src/components/AppTable/engine/table/controller/tableQueryCoordinator.ts +187 -0
  287. package/template/src/components/AppTable/engine/table/controller/tableReportingCoordinator.ts +143 -0
  288. package/template/src/components/AppTable/engine/table/controller/tableSaveCoordinator.ts +227 -0
  289. package/template/src/components/AppTable/engine/table/controller/tableSaveValidation.ts +29 -0
  290. package/template/src/components/AppTable/engine/table/controller/tableSnapshot.ts +58 -0
  291. package/template/src/components/AppTable/engine/table/controller/types.ts +202 -0
  292. package/template/src/components/AppTable/engine/table/editing/baselineStore.ts +134 -0
  293. package/template/src/components/AppTable/engine/table/editing/changeSet.ts +492 -0
  294. package/template/src/components/AppTable/engine/table/editing/changeSetSettlement.ts +633 -0
  295. package/template/src/components/AppTable/engine/table/editing/commitResultIndex.ts +75 -0
  296. package/template/src/components/AppTable/engine/table/editing/constants.ts +15 -0
  297. package/template/src/components/AppTable/engine/table/editing/dirtyCellIndex.ts +96 -0
  298. package/template/src/components/AppTable/engine/table/editing/index.ts +6 -0
  299. package/template/src/components/AppTable/engine/table/editing/mutation.ts +173 -0
  300. package/template/src/components/AppTable/engine/table/editing/rowKey.ts +10 -0
  301. package/template/src/components/AppTable/engine/table/editing/types.ts +404 -0
  302. package/template/src/components/AppTable/engine/table/editing/validation.ts +452 -0
  303. package/template/src/components/AppTable/engine/table/grid/cellMeta.ts +90 -0
  304. package/template/src/components/AppTable/engine/table/grid/handsontable.ts +25 -0
  305. package/template/src/components/AppTable/engine/table/grid/handsontableExtensions.d.ts +26 -0
  306. package/template/src/components/AppTable/engine/table/grid/index.ts +5 -0
  307. package/template/src/components/AppTable/engine/table/grid/moduleRegistry.ts +39 -0
  308. package/template/src/components/AppTable/engine/table/grid/runtime.ts +31 -0
  309. package/template/src/components/AppTable/engine/table/grid/types.ts +25 -0
  310. package/template/src/components/AppTable/engine/table/hooks/fixedEndHooks.ts +44 -0
  311. package/template/src/components/AppTable/engine/table/hooks/gridHooks.ts +108 -0
  312. package/template/src/components/AppTable/engine/table/hooks/headerHooks.ts +103 -0
  313. package/template/src/components/AppTable/engine/table/hooks/index.ts +3 -0
  314. package/template/src/components/AppTable/engine/table/index.ts +6 -0
  315. package/template/src/components/AppTable/engine/table/layout/constants.ts +2 -0
  316. package/template/src/components/AppTable/engine/table/layout/dropdownMenu.ts +89 -0
  317. package/template/src/components/AppTable/engine/table/layout/fixedColumns.ts +44 -0
  318. package/template/src/components/AppTable/engine/table/layout/fixedEndOverlay.ts +90 -0
  319. package/template/src/components/AppTable/engine/table/layout/fixedEndOverlayAccessibility.ts +104 -0
  320. package/template/src/components/AppTable/engine/table/layout/fixedEndOverlayRenderer.ts +690 -0
  321. package/template/src/components/AppTable/engine/table/layout/fixedEndOverlaySignature.ts +58 -0
  322. package/template/src/components/AppTable/engine/table/layout/fixedEndRuntime.ts +137 -0
  323. package/template/src/components/AppTable/engine/table/layout/handsontableDomAdapter.ts +40 -0
  324. package/template/src/components/AppTable/engine/table/layout/height.ts +72 -0
  325. package/template/src/components/AppTable/engine/table/layout/index.ts +14 -0
  326. package/template/src/components/AppTable/engine/table/layout/layoutScheduler.ts +60 -0
  327. package/template/src/components/AppTable/engine/table/layout/mergeCells.ts +146 -0
  328. package/template/src/components/AppTable/engine/table/layout/nestedHeaders.ts +271 -0
  329. package/template/src/components/AppTable/engine/table/layout/types.ts +10 -0
  330. package/template/src/components/AppTable/engine/toolbar/index.ts +1 -0
  331. package/template/src/components/AppTable/engine/toolbar/types.ts +56 -0
  332. package/template/src/components/AppTable/index.ts +11 -0
  333. package/template/src/components/AppTable/messages.ts +256 -0
  334. package/template/src/components/AppTable/pagination/TablePaginationBar.tsx +193 -0
  335. package/template/src/components/AppTable/pagination/index.ts +1 -0
  336. package/template/src/components/AppTable/pagination/paginationItems.ts +56 -0
  337. package/template/src/components/AppTable/preference/index.ts +1 -0
  338. package/template/src/components/AppTable/preference/useTablePreference.ts +208 -0
  339. package/template/src/components/AppTable/reporting/index.ts +1 -0
  340. package/template/src/components/AppTable/reporting/useTableReporting.ts +342 -0
  341. package/template/src/components/AppTable/search/TableSearchBar.tsx +301 -0
  342. package/template/src/components/AppTable/search/TableSearchConditionEditor.tsx +254 -0
  343. package/template/src/components/AppTable/search/TableSearchField.tsx +338 -0
  344. package/template/src/components/AppTable/search/TableSearchFields.tsx +65 -0
  345. package/template/src/components/AppTable/search/constants.ts +9 -0
  346. package/template/src/components/AppTable/search/index.ts +3 -0
  347. package/template/src/components/AppTable/search/tableSearchBar.css +164 -0
  348. package/template/src/components/AppTable/search/types.ts +7 -0
  349. package/template/src/components/AppTable/search/useTableQuery.ts +373 -0
  350. package/template/src/components/AppTable/selection/index.ts +1 -0
  351. package/template/src/components/AppTable/selection/useTableSelection.ts +188 -0
  352. package/template/src/components/AppTable/sensitiveData.tsx +41 -0
  353. package/template/src/components/AppTable/shared/styles.ts +2 -0
  354. package/template/src/components/AppTable/styles/index.css +6 -0
  355. package/template/src/components/AppTable/styles/tableComponent.css +297 -0
  356. package/template/src/components/AppTable/styles/theme.css +133 -0
  357. package/template/src/components/AppTable/table/components/TableComponent.tsx +567 -0
  358. package/template/src/components/AppTable/table/components/TableErrorFeedback.tsx +36 -0
  359. package/template/src/components/AppTable/table/components/TableGridViewport.tsx +85 -0
  360. package/template/src/components/AppTable/table/components/index.ts +2 -0
  361. package/template/src/components/AppTable/table/components/types.ts +90 -0
  362. package/template/src/components/AppTable/table/controller/configuration.ts +89 -0
  363. package/template/src/components/AppTable/table/controller/index.ts +2 -0
  364. package/template/src/components/AppTable/table/controller/useTableController.ts +155 -0
  365. package/template/src/components/AppTable/table/controller/useTableLifecycle.ts +97 -0
  366. package/template/src/components/AppTable/table/grid/index.ts +1 -0
  367. package/template/src/components/AppTable/table/grid/useTableGrid.ts +857 -0
  368. package/template/src/components/AppTable/table/grid/useTableGridRuntimeSettings.ts +49 -0
  369. package/template/src/components/AppTable/table/index.ts +4 -0
  370. package/template/src/components/AppTable/table/layout/TablePanels.tsx +389 -0
  371. package/template/src/components/AppTable/table/layout/index.ts +7 -0
  372. package/template/src/components/AppTable/table/layout/types.ts +3 -0
  373. package/template/src/components/AppTable/table/layout/useResizablePanel.ts +213 -0
  374. package/template/src/components/AppTable/table/layout/useTableAdaptiveHeight.ts +238 -0
  375. package/template/src/components/AppTable/table/layout/useTablePanels.ts +329 -0
  376. package/template/src/components/AppTable/table/layout/useTableTheme.ts +123 -0
  377. package/template/src/components/AppTable/toolbar/TableToolbar.tsx +336 -0
  378. package/template/src/components/AppTable/toolbar/index.ts +1 -0
  379. package/template/src/components/BrandLogo/BrandLogo.tsx +41 -0
  380. package/template/src/components/BrandLogo/index.ts +1 -0
  381. package/template/src/components/Can/Can.tsx +19 -0
  382. package/template/src/components/Can/index.ts +7 -0
  383. package/template/src/components/Can/types.ts +41 -0
  384. package/template/src/components/EnumBadge/EnumBadge.tsx +44 -0
  385. package/template/src/components/EnumBadge/index.ts +2 -0
  386. package/template/src/components/EnumBadge/types.ts +16 -0
  387. package/template/src/components/EnumText/EnumText.tsx +33 -0
  388. package/template/src/components/EnumText/index.ts +2 -0
  389. package/template/src/components/EnumText/types.ts +13 -0
  390. package/template/src/components/FilePreview/FilePreview.tsx +120 -0
  391. package/template/src/components/FilePreview/index.ts +11 -0
  392. package/template/src/components/FilePreview/preview.ts +88 -0
  393. package/template/src/components/FilePreview/types.ts +91 -0
  394. package/template/src/components/FileUpload/FileUpload.tsx +172 -0
  395. package/template/src/components/FileUpload/index.ts +2 -0
  396. package/template/src/components/FileUpload/types.ts +32 -0
  397. package/template/src/components/JsonEditor/JsonEditor.tsx +103 -0
  398. package/template/src/components/JsonEditor/index.ts +1 -0
  399. package/template/src/components/JsonEditor/types.ts +14 -0
  400. package/template/src/components/PageFeedback/PageFeedback.tsx +194 -0
  401. package/template/src/components/PageFeedback/index.ts +10 -0
  402. package/template/src/components/PageFeedback/types.ts +31 -0
  403. package/template/src/components/PasswordInput/PasswordInput.tsx +50 -0
  404. package/template/src/components/PasswordInput/index.ts +1 -0
  405. package/template/src/components/RouteDialog/RouteDialog.tsx +20 -0
  406. package/template/src/components/RouteDialog/index.ts +2 -0
  407. package/template/src/components/RouteDialog/types.ts +8 -0
  408. package/template/src/components/RouteDialog/useRouteDialogNavigation.ts +30 -0
  409. package/template/src/components/SensitiveData/SensitiveData.tsx +337 -0
  410. package/template/src/components/SensitiveData/index.ts +2 -0
  411. package/template/src/components/SensitiveData/types.ts +31 -0
  412. package/template/src/components/StatusBadge/StatusBadge.tsx +28 -0
  413. package/template/src/components/StatusBadge/index.ts +2 -0
  414. package/template/src/components/StatusBadge/statusBadgeStyles.ts +30 -0
  415. package/template/src/components/StatusBadge/types.ts +7 -0
  416. package/template/src/components/layout/AppHeader/AppHeader.tsx +57 -0
  417. package/template/src/components/layout/AppHeader/HeaderSearch.tsx +160 -0
  418. package/template/src/components/layout/AppHeader/HeaderUserMenu.tsx +59 -0
  419. package/template/src/components/layout/AppHeader/ThemeControls.tsx +44 -0
  420. package/template/src/components/layout/AppHeader/index.ts +1 -0
  421. package/template/src/components/layout/AppHeader/themeOptions.ts +13 -0
  422. package/template/src/components/layout/AppSidebar.tsx +268 -0
  423. package/template/src/components/layout/PageContainer.tsx +16 -0
  424. package/template/src/components/ui/avatar.tsx +108 -0
  425. package/template/src/components/ui/badge.tsx +47 -0
  426. package/template/src/components/ui/button.tsx +63 -0
  427. package/template/src/components/ui/card.tsx +60 -0
  428. package/template/src/components/ui/checkbox.tsx +31 -0
  429. package/template/src/components/ui/collapsible.tsx +33 -0
  430. package/template/src/components/ui/command.tsx +181 -0
  431. package/template/src/components/ui/dialog.tsx +157 -0
  432. package/template/src/components/ui/dropdown-menu.tsx +254 -0
  433. package/template/src/components/ui/form.tsx +141 -0
  434. package/template/src/components/ui/input.tsx +20 -0
  435. package/template/src/components/ui/label.tsx +23 -0
  436. package/template/src/components/ui/pagination.tsx +127 -0
  437. package/template/src/components/ui/popover.tsx +41 -0
  438. package/template/src/components/ui/select.tsx +187 -0
  439. package/template/src/components/ui/separator.tsx +25 -0
  440. package/template/src/components/ui/sheet.tsx +142 -0
  441. package/template/src/components/ui/sidebar.tsx +878 -0
  442. package/template/src/components/ui/skeleton.tsx +13 -0
  443. package/template/src/components/ui/sonner.tsx +33 -0
  444. package/template/src/components/ui/tooltip.tsx +54 -0
  445. package/template/src/config/RuntimeConfigErrorPage.tsx +48 -0
  446. package/template/src/config/appConfig.ts +126 -0
  447. package/template/src/config/buildInfo.ts +8 -0
  448. package/template/src/config/observabilityAdapter.ts +8 -0
  449. package/template/src/config/runtimeConfig.ts +360 -0
  450. package/template/src/config/types.ts +195 -0
  451. package/template/src/context/ThemeProvider.tsx +84 -0
  452. package/template/src/context/UnsavedChangesProvider.tsx +123 -0
  453. package/template/src/context/applicationScope.ts +39 -0
  454. package/template/src/context/types.ts +41 -0
  455. package/template/src/dataMasking/index.ts +14 -0
  456. package/template/src/dataMasking/masking.ts +139 -0
  457. package/template/src/dataMasking/types.ts +144 -0
  458. package/template/src/featureFlags/FeatureFlagProvider.tsx +143 -0
  459. package/template/src/featureFlags/FeatureGate.tsx +12 -0
  460. package/template/src/featureFlags/catalog.ts +140 -0
  461. package/template/src/featureFlags/errors.ts +17 -0
  462. package/template/src/featureFlags/index.ts +43 -0
  463. package/template/src/featureFlags/query.ts +103 -0
  464. package/template/src/featureFlags/registry.ts +149 -0
  465. package/template/src/featureFlags/scope.ts +27 -0
  466. package/template/src/featureFlags/types.ts +241 -0
  467. package/template/src/features/auth/AuthLayout.tsx +17 -0
  468. package/template/src/features/auth/index.ts +2 -0
  469. package/template/src/features/auth/signIn/components/UserAuthForm.tsx +121 -0
  470. package/template/src/features/auth/signIn/index.tsx +71 -0
  471. package/template/src/features/auth/signIn/messages.ts +37 -0
  472. package/template/src/features/auth/signIn/types.ts +4 -0
  473. package/template/src/features/errors/ForbiddenError.tsx +34 -0
  474. package/template/src/features/errors/GeneralError.tsx +46 -0
  475. package/template/src/features/errors/MaintenanceError.tsx +31 -0
  476. package/template/src/features/errors/NotFoundError.tsx +34 -0
  477. package/template/src/features/errors/RouteError.tsx +72 -0
  478. package/template/src/features/errors/UnauthorizedError.tsx +34 -0
  479. package/template/src/features/errors/index.ts +6 -0
  480. package/template/src/features/errors/messages.ts +56 -0
  481. package/template/src/features/home/index.tsx +107 -0
  482. package/template/src/features/home/messages.ts +59 -0
  483. package/template/src/features/showcase/AccessShowcasePage.tsx +284 -0
  484. package/template/src/features/showcase/AdvancedTableDemo.tsx +120 -0
  485. package/template/src/features/showcase/FeedbackShowcasePage.tsx +142 -0
  486. package/template/src/features/showcase/FileShowcasePage.tsx +110 -0
  487. package/template/src/features/showcase/FormShowcasePage.tsx +156 -0
  488. package/template/src/features/showcase/MetadataShowcasePage.tsx +241 -0
  489. package/template/src/features/showcase/ShowcasePageHeader.tsx +24 -0
  490. package/template/src/features/showcase/TableShowcasePage.tsx +436 -0
  491. package/template/src/features/showcase/accessMessages.ts +67 -0
  492. package/template/src/features/showcase/index.ts +6 -0
  493. package/template/src/features/showcase/messages.ts +192 -0
  494. package/template/src/files/download.ts +82 -0
  495. package/template/src/files/errors.ts +15 -0
  496. package/template/src/files/filename.ts +61 -0
  497. package/template/src/files/index.ts +38 -0
  498. package/template/src/files/types.ts +299 -0
  499. package/template/src/files/useFileTask.ts +153 -0
  500. package/template/src/files/useFileUpload.ts +117 -0
  501. package/template/src/files/validation.ts +109 -0
  502. package/template/src/layouts/AppLayout.tsx +37 -0
  503. package/template/src/lib/accessControl.ts +42 -0
  504. package/template/src/lib/navigationRedirect.ts +26 -0
  505. package/template/src/lib/utils.ts +6 -0
  506. package/template/src/locale/LocaleProvider.tsx +37 -0
  507. package/template/src/locale/context.ts +15 -0
  508. package/template/src/locale/formatters.ts +123 -0
  509. package/template/src/locale/hooks.ts +35 -0
  510. package/template/src/locale/index.ts +17 -0
  511. package/template/src/locale/messages.ts +151 -0
  512. package/template/src/locale/types.ts +167 -0
  513. package/template/src/main.tsx +5 -0
  514. package/template/src/observability/browser.ts +37 -0
  515. package/template/src/observability/consoleAdapter.ts +18 -0
  516. package/template/src/observability/index.ts +26 -0
  517. package/template/src/observability/observer.ts +118 -0
  518. package/template/src/observability/redaction.ts +85 -0
  519. package/template/src/observability/types.ts +119 -0
  520. package/template/src/optionalEditors/controller.ts +327 -0
  521. package/template/src/optionalEditors/errors.ts +21 -0
  522. package/template/src/optionalEditors/index.ts +35 -0
  523. package/template/src/optionalEditors/model.ts +253 -0
  524. package/template/src/optionalEditors/react.ts +89 -0
  525. package/template/src/optionalEditors/types.ts +254 -0
  526. package/template/src/permissions/index.ts +3 -0
  527. package/template/src/permissions/types.ts +5 -0
  528. package/template/src/permissions/usePermission.ts +16 -0
  529. package/template/src/realtimeCollaboration/controller.ts +355 -0
  530. package/template/src/realtimeCollaboration/errors.ts +20 -0
  531. package/template/src/realtimeCollaboration/index.ts +39 -0
  532. package/template/src/realtimeCollaboration/model.ts +212 -0
  533. package/template/src/realtimeCollaboration/react.ts +72 -0
  534. package/template/src/realtimeCollaboration/types.ts +251 -0
  535. package/template/src/reporting/errors.ts +21 -0
  536. package/template/src/reporting/generation.ts +87 -0
  537. package/template/src/reporting/index.ts +42 -0
  538. package/template/src/reporting/model.ts +373 -0
  539. package/template/src/reporting/print.ts +16 -0
  540. package/template/src/reporting/query.ts +50 -0
  541. package/template/src/reporting/react.ts +17 -0
  542. package/template/src/reporting/source.ts +13 -0
  543. package/template/src/reporting/types.ts +219 -0
  544. package/template/src/router/RootRouteLayout.tsx +11 -0
  545. package/template/src/router/authLifecycle.ts +39 -0
  546. package/template/src/router/config.ts +293 -0
  547. package/template/src/router/interceptors.ts +48 -0
  548. package/template/src/router/lazyRouteComponents.ts +78 -0
  549. package/template/src/router/messages.ts +48 -0
  550. package/template/src/router/navigation.ts +167 -0
  551. package/template/src/router/router.ts +66 -0
  552. package/template/src/router/searchSchemas.ts +9 -0
  553. package/template/src/router/types.ts +76 -0
  554. package/template/src/stores/authSessionStorage.ts +27 -0
  555. package/template/src/stores/authStore.ts +165 -0
  556. package/template/src/stores/types.ts +36 -0
  557. package/template/src/stores/uiPreferenceStore.ts +34 -0
  558. package/template/src/styles/index.css +141 -0
  559. package/template/src/styles/theme.css +213 -0
  560. package/template/src/tenantWorkspace/TenantWorkspaceProvider.tsx +102 -0
  561. package/template/src/tenantWorkspace/index.ts +33 -0
  562. package/template/src/tenantWorkspace/store.ts +184 -0
  563. package/template/src/tenantWorkspace/switch.ts +206 -0
  564. package/template/src/tenantWorkspace/types.ts +155 -0
  565. package/template/src/vite-env.d.ts +20 -0
  566. package/template/stylelint.config.js +28 -0
  567. package/template/tests/integration/Application.test.tsx +269 -0
  568. package/template/tests/integration/layout/AppHeader.test.tsx +182 -0
  569. package/template/tests/integration/layout/AppSidebar.test.tsx +121 -0
  570. package/template/tests/integration/layout/__screenshots__/AppHeader.test.tsx/AppHeader-command-search-hides-the-duplicate-header-trigger-when-the-desktop-sidebar-collapses-1.png +0 -0
  571. package/template/tests/integration/router/__screenshots__/config.test.ts/route-tree-authentication-boundaries-exposes-only-scaffold-navigation-metadata-1.png +0 -0
  572. package/template/tests/integration/router/config.test.ts +123 -0
  573. package/template/tests/integration/router/interceptors.test.ts +100 -0
  574. package/template/tests/setup/accessibility.ts +25 -0
  575. package/template/tests/setup/runtimeConfig.ts +3 -0
  576. package/template/tests/unit/api/ApiError.test.ts +25 -0
  577. package/template/tests/unit/api/__screenshots__/authSession.test.ts/administrator-authentication-clears-the-session-if-a-refresh-identity-loses-administrator-access-1.png +0 -0
  578. package/template/tests/unit/api/__screenshots__/authSession.test.ts/administrator-authentication-creates-a-session-from-the-generated-login-response-for-an-admin-1.png +0 -0
  579. package/template/tests/unit/api/__screenshots__/authSession.test.ts/administrator-authentication-rejects-and-revokes-the-generated-login-result-for-an-ordinary-user-1.png +0 -0
  580. package/template/tests/unit/api/activity/ActivityProvider.test.tsx +131 -0
  581. package/template/tests/unit/api/activity/__screenshots__/transports.test.ts/activity-transport-adapters-polls-sequentially-and-advances-the-last-event-ID-1.png +0 -0
  582. package/template/tests/unit/api/activity/modelAndQuery.test.ts +144 -0
  583. package/template/tests/unit/api/activity/subscription.test.ts +103 -0
  584. package/template/tests/unit/api/activity/transports.test.ts +145 -0
  585. package/template/tests/unit/api/authClient.test.ts +110 -0
  586. package/template/tests/unit/api/authSession.test.ts +289 -0
  587. package/template/tests/unit/api/clients/configureApiClient.test.ts +198 -0
  588. package/template/tests/unit/api/demoAuthClient.test.ts +47 -0
  589. package/template/tests/unit/api/enums/access.test.ts +107 -0
  590. package/template/tests/unit/api/enums/catalog.test.ts +200 -0
  591. package/template/tests/unit/api/enums/query.test.ts +110 -0
  592. package/template/tests/unit/api/enums/useEnum.test.tsx +98 -0
  593. package/template/tests/unit/api/enums/useEnumCatalog.test.tsx +68 -0
  594. package/template/tests/unit/api/hooks/error.test.ts +168 -0
  595. package/template/tests/unit/api/hooks/request.test.ts +170 -0
  596. package/template/tests/unit/api/hooks/response.test.ts +46 -0
  597. package/template/tests/unit/api/metadata/MetadataProvider.test.tsx +102 -0
  598. package/template/tests/unit/api/parameters/catalog.test.ts +147 -0
  599. package/template/tests/unit/api/parameters/query.test.ts +78 -0
  600. package/template/tests/unit/api/parameters/useGlobalParameter.test.tsx +89 -0
  601. package/template/tests/unit/api/query/queryPolicy.test.ts +245 -0
  602. package/template/tests/unit/api/query/useAppQueryScope.test.tsx +74 -0
  603. package/template/tests/unit/auditLogs/auditLogHooks.test.tsx +194 -0
  604. package/template/tests/unit/auditLogs/auditLogs.test.ts +199 -0
  605. package/template/tests/unit/authentication/__screenshots__/authentication.test.ts/authentication-controller-completes-Step-up-callbacks-without-creating-a-second-login-result-1.png +0 -0
  606. package/template/tests/unit/authentication/__screenshots__/authentication.test.ts/authentication-controller-moves-from-challenge-to-completion-without-retaining-tokens-in-snapshot-1.png +0 -0
  607. package/template/tests/unit/authentication/authentication.test.ts +376 -0
  608. package/template/tests/unit/components/AppDialog.test.tsx +225 -0
  609. package/template/tests/unit/components/AppTable.test.tsx +129 -0
  610. package/template/tests/unit/components/AppTableLayoutTransition.test.ts +118 -0
  611. package/template/tests/unit/components/AppTableLocalization.test.ts +58 -0
  612. package/template/tests/unit/components/AppTableSensitiveData.test.ts +35 -0
  613. package/template/tests/unit/components/AppTableUpgrade.test.tsx +179 -0
  614. package/template/tests/unit/components/AppTableUpgradeCore.test.ts +258 -0
  615. package/template/tests/unit/components/BrandLogo.test.tsx +24 -0
  616. package/template/tests/unit/components/Can.test.tsx +80 -0
  617. package/template/tests/unit/components/Dialog.test.tsx +56 -0
  618. package/template/tests/unit/components/EnumPresentation.test.tsx +64 -0
  619. package/template/tests/unit/components/FilePreviewEngine.test.ts +51 -0
  620. package/template/tests/unit/components/JsonEditor.test.tsx +47 -0
  621. package/template/tests/unit/components/LocalizedSharedComponents.test.tsx +36 -0
  622. package/template/tests/unit/components/OverlayLayer.test.tsx +151 -0
  623. package/template/tests/unit/components/PageFeedback.test.tsx +143 -0
  624. package/template/tests/unit/components/PageForm.test.tsx +272 -0
  625. package/template/tests/unit/components/PageFormCore.test.ts +74 -0
  626. package/template/tests/unit/components/PasswordInput.test.tsx +105 -0
  627. package/template/tests/unit/components/ScaffoldComponents.test.tsx +64 -0
  628. package/template/tests/unit/components/SensitiveData.test.tsx +151 -0
  629. package/template/tests/unit/components/StatusBadge.test.tsx +36 -0
  630. package/template/tests/unit/components/TableComponent.test.tsx +644 -0
  631. package/template/tests/unit/components/TableCore.test.ts +145 -0
  632. package/template/tests/unit/components/ThemeAccessibility.test.tsx +27 -0
  633. package/template/tests/unit/components/__screenshots__/BatchOperationDialog.test.tsx/confirms-a-batch-action-and-presents-partial-failure-details-1.png +0 -0
  634. package/template/tests/unit/components/__screenshots__/PageForm.test.tsx/PageForm-writes-uploaded-values-through-the-public-file-field-and-resets-dirty-state-1.png +0 -0
  635. package/template/tests/unit/components/__screenshots__/PasswordInput.test.tsx/PasswordInput-toggles-the-password-visibility-when-the-show-password-button-is-clicked-1.png +0 -0
  636. package/template/tests/unit/components/__screenshots__/TableComponent.test.tsx/TableComponent-pins-trailing-action-columns-and-removes-their-header-menu-by-default-1.png +0 -0
  637. package/template/tests/unit/components/__screenshots__/TableComponent.test.tsx/TableComponent-renders-shadcn-components-through-cellComponent-1.png +0 -0
  638. package/template/tests/unit/components/__screenshots__/TableComponent.test.tsx/TableComponent-renders-the-toolbar-without-a-bottom-divider-1.png +0 -0
  639. package/template/tests/unit/components/__screenshots__/TableComponent.test.tsx/TableComponent-resyncs-adaptive-height-after-a-column-resize-changes-wrapped-row-height-1.png +0 -0
  640. package/template/tests/unit/config/RuntimeConfigErrorPage.test.tsx +23 -0
  641. package/template/tests/unit/config/appConfig.test.ts +98 -0
  642. package/template/tests/unit/config/appTableContracts.test.mjs +120 -0
  643. package/template/tests/unit/config/bundleBudget.test.mjs +190 -0
  644. package/template/tests/unit/config/componentGovernance.test.mjs +156 -0
  645. package/template/tests/unit/config/deployConfig.test.mjs +211 -0
  646. package/template/tests/unit/config/eslintConfig.test.mjs +101 -0
  647. package/template/tests/unit/config/featureBoundaries.test.mjs +126 -0
  648. package/template/tests/unit/config/npmPackage.test.mjs +37 -0
  649. package/template/tests/unit/config/releaseArtifact.test.mjs +105 -0
  650. package/template/tests/unit/config/runtimeConfig.test.ts +225 -0
  651. package/template/tests/unit/config/scaffoldCheck.test.mjs +53 -0
  652. package/template/tests/unit/config/scaffoldFeature.test.mjs +177 -0
  653. package/template/tests/unit/config/scaffoldInit.test.mjs +218 -0
  654. package/template/tests/unit/config/scaffoldProject.test.mjs +378 -0
  655. package/template/tests/unit/config/scaffoldTransaction.test.mjs +77 -0
  656. package/template/tests/unit/config/viteConfig.test.mjs +371 -0
  657. package/template/tests/unit/context/ThemeProvider.test.tsx +108 -0
  658. package/template/tests/unit/context/UnsavedChangesProvider.test.tsx +94 -0
  659. package/template/tests/unit/context/__screenshots__/ThemeProvider.test.tsx/ThemeProvider-uses-the-neutral-black-palette-for-the-app-and-scoped-table-theme-1.png +0 -0
  660. package/template/tests/unit/context/applicationScope.test.ts +62 -0
  661. package/template/tests/unit/dataMasking/dataMasking.test.ts +95 -0
  662. package/template/tests/unit/featureFlags/featureFlags.test.ts +169 -0
  663. package/template/tests/unit/featureFlags/useFeatureFlag.test.tsx +108 -0
  664. package/template/tests/unit/features/FeatureLocalization.test.tsx +54 -0
  665. package/template/tests/unit/features/RouteError.test.tsx +40 -0
  666. package/template/tests/unit/features/auth/signIn/UserAuthForm.test.tsx +79 -0
  667. package/template/tests/unit/features/auth/signIn/__screenshots__/UserAuthForm.test.tsx/UserAuthForm-passes-validated-values-to-onSubmit-1.png +0 -0
  668. package/template/tests/unit/features/auth/signIn/__screenshots__/UserAuthForm.test.tsx/UserAuthForm-shows-validation-messages-when-submitting-an-empty-form-1.png +0 -0
  669. package/template/tests/unit/files/fileHooks.test.tsx +130 -0
  670. package/template/tests/unit/files/files.test.ts +112 -0
  671. package/template/tests/unit/lib/accessControl.test.ts +69 -0
  672. package/template/tests/unit/locale/locale.test.tsx +90 -0
  673. package/template/tests/unit/observability/browser.test.ts +48 -0
  674. package/template/tests/unit/observability/observer.test.ts +115 -0
  675. package/template/tests/unit/optionalEditors/__screenshots__/useOptionalEditor.test.tsx/useOptionalEditor-fails-permission-precheck-before-loading-the-project-SDK-1.png +0 -0
  676. package/template/tests/unit/optionalEditors/__screenshots__/useOptionalEditor.test.tsx/useOptionalEditor-mounts-a-route-scoped-SDK-into-the-dedicated-host-with-permission-1.png +0 -0
  677. package/template/tests/unit/optionalEditors/optionalEditors.test.ts +313 -0
  678. package/template/tests/unit/optionalEditors/useOptionalEditor.test.tsx +141 -0
  679. package/template/tests/unit/realtimeCollaboration/collaboration.test.ts +240 -0
  680. package/template/tests/unit/realtimeCollaboration/useRealtimeCollaboration.test.tsx +115 -0
  681. package/template/tests/unit/reporting/reporting.test.ts +195 -0
  682. package/template/tests/unit/reporting/reportingHooks.test.tsx +203 -0
  683. package/template/tests/unit/router/authLifecycle.test.ts +55 -0
  684. package/template/tests/unit/router/navigation.test.ts +55 -0
  685. package/template/tests/unit/router/redirects.test.ts +22 -0
  686. package/template/tests/unit/scaffoldFeatureTemplate/featureTemplate.test.ts +42 -0
  687. package/template/tests/unit/scaffoldFeatureTemplate/publicContract.test.ts +28 -0
  688. package/template/tests/unit/scaffoldFeatureTemplate/queries.test.tsx +289 -0
  689. package/template/tests/unit/stores/authStore.test.ts +128 -0
  690. package/template/tests/unit/stores/uiPreferenceStore.test.ts +56 -0
  691. package/template/tests/unit/tenantWorkspace/tenantWorkspace.test.tsx +261 -0
  692. package/template/tools/bundle/budgets.json +48 -0
  693. package/template/tools/bundle/check.mjs +307 -0
  694. package/template/tools/component-governance/check.mjs +703 -0
  695. package/template/tools/component-governance/manifest.json +112 -0
  696. package/template/tools/deployment/browser-smoke.mjs +76 -0
  697. package/template/tools/deployment/browser-smoke.sh +141 -0
  698. package/template/tools/openapi/generate.mjs +268 -0
  699. package/template/tools/openapi/templates/README.md +14 -0
  700. package/template/tools/openapi/templates/base/README.md +7 -0
  701. package/template/tools/openapi/templates/base/data-contracts.eta +44 -0
  702. package/template/tools/openapi/templates/base/http-client.eta +3 -0
  703. package/template/tools/openapi/templates/base/http-clients/axios-http-client.eta +132 -0
  704. package/template/tools/openapi/templates/base/http-clients/fetch-http-client.eta +220 -0
  705. package/template/tools/openapi/templates/base/route-docs.eta +31 -0
  706. package/template/tools/openapi/templates/base/route-name.eta +43 -0
  707. package/template/tools/openapi/templates/base/route-type.eta +22 -0
  708. package/template/tools/openapi/templates/default/README.md +7 -0
  709. package/template/tools/openapi/templates/default/api.eta +67 -0
  710. package/template/tools/openapi/templates/default/http-client.eta +137 -0
  711. package/template/tools/openapi/templates/default/procedure-call.eta +99 -0
  712. package/template/tools/openapi/templates/default/route-docs.eta +40 -0
  713. package/template/tools/openapi/templates/default/route-types.eta +28 -0
  714. package/template/tools/openapi/templates/modular/README.md +7 -0
  715. package/template/tools/openapi/templates/modular/api.eta +28 -0
  716. package/template/tools/openapi/templates/modular/procedure-call.eta +99 -0
  717. package/template/tools/openapi/templates/modular/route-types.eta +18 -0
  718. package/template/tools/release/artifact.mjs +258 -0
  719. package/template/tools/scaffold/add-capability.mjs +409 -0
  720. package/template/tools/scaffold/capability-catalog.json +163 -0
  721. package/template/tools/scaffold/check.mjs +326 -0
  722. package/template/tools/scaffold/create-feature.mjs +444 -0
  723. package/template/tools/scaffold/create-project.mjs +482 -0
  724. package/template/tools/scaffold/init.example.json +64 -0
  725. package/template/tools/scaffold/init.mjs +419 -0
  726. package/template/tools/scaffold/lockfile.mjs +193 -0
  727. package/template/tools/scaffold/templates/feature/index.ts +19 -0
  728. package/template/tools/scaffold/templates/feature/model.ts +142 -0
  729. package/template/tools/scaffold/templates/feature/queries.ts +154 -0
  730. package/template/tools/scaffold/templates/feature/repository.ts +206 -0
  731. package/template/tools/scaffold/templates/feature/types.ts +168 -0
  732. package/template/tools/scaffold/workspace-transaction.mjs +111 -0
  733. package/template/tsconfig.app.json +31 -0
  734. package/template/tsconfig.json +12 -0
  735. package/template/tsconfig.node.json +24 -0
  736. package/template/vite.config.ts +121 -0
@@ -0,0 +1,208 @@
1
+ # 企业 React 管理脚手架方案
2
+
3
+ ## 目标
4
+
5
+ 这个仓库是企业内部管理系统的启动底座,不是某个产品的克隆,也不是页面示例集合。
6
+ 初始化后应同时满足三个条件:没有产品业务语义、无后端也能完整演示、接入后端时不重写
7
+ 页面和路由。
8
+
9
+ 默认面向桌面端内部管理后台,以登录用户中的租户 ID 隔离缓存;工作空间切换上下文按需
10
+ 加入,不默认提供计费、套餐、开放注册等 SaaS 能力,也不承诺移动端查看、审批或操作体验。
11
+ 现有窄窗口布局用于桌面窗口缩放,不代表建立移动端产品能力。
12
+
13
+ ## 能力分层
14
+
15
+ ### P0:开箱即可开发
16
+
17
+ | 领域 | 内置能力 | 交付形态 |
18
+ | -------- | ------------------------------------------------ | ----------------------- |
19
+ | 应用壳层 | 品牌、主题、侧边栏、面包屑、命令搜索、错误边界 | 可直接使用 |
20
+ | 身份会话 | 登录、退出、刷新、回跳、会话过期 | demo/connected 双适配器 |
21
+ | 访问控制 | 路由、菜单、按钮和数据请求的统一权限判断 | 权限码契约 |
22
+ | 业务扩展 | Feature、Repository 与 API Adapter 接入约定 | 文档与目录约束 |
23
+ | 数据交互 | PageForm、Table、Dialog、反馈、空态和加载态 | 项目自有组件边界 |
24
+ | API | OpenAPI 生成、统一错误、请求标识、取消和缓存 | 基础设施 |
25
+ | 初始化 | 项目标识、Runtime Config、OpenAPI 清单与占位诊断 | 预览式写入与只读检查 |
26
+ | 发布 | 单次构建、文件摘要、镜像 Digest 与环境配置注入 | 不可变产物晋级 |
27
+ | 诊断安全 | 错误追踪、Web Vitals、脱敏、CSP 与依赖审计 | 可关闭 Adapter 与门禁 |
28
+ | 工程质量 | 类型、Lint、死代码、浏览器测试、构建和 CI | `pnpm verify` |
29
+
30
+ 默认应用只提供“演示登录 → 权限路由 → 中性首页”的壳层闭环。用户、角色、组织等
31
+ 系统管理同样属于具体项目业务,初始化后按 Feature 接入,不在脚手架中预置页面或数据。
32
+
33
+ ### P1:企业项目常见增强
34
+
35
+ - 租户/工作空间上下文:按需加入稳定 ID、后端确认切换、缓存隔离和失败恢复,不内置管理页面。
36
+ - 通知与任务状态:按需加入活动摘要、轮询/SSE/WebSocket Adapter 和断线恢复,不内置待办页。
37
+ - 幂等写事务:统一幂等键、按钮状态、超时恢复和后端结果确认,不用前端防抖冒充幂等。
38
+ - 批量操作:Table 负责选择和入口,Feature 负责权限、确认、提交及业务结果反馈。
39
+ - 页面筛选:Table 负责查询、排序、分页与偏好;可分享 URL 由具体路由按需定义。
40
+ - 任务中心:待办、已办、抄送、批量处理和未读提醒。
41
+ - 审批接入:审批详情、意见、附件和流转记录;不内置可视化流程设计器。
42
+ - 字典与参数:通用枚举、远程选项缓存和环境级参数。
43
+ - 文件能力:上传、下载、预览、失败重试和权限校验。
44
+ - 国际化:语言包、日期、时区和数字格式策略。
45
+ - 业务审计:高风险操作留痕、后端审计 ID 和用户可见操作记录。
46
+
47
+ ### P2:按项目选择
48
+
49
+ - 租户级品牌、计费套餐和跨租户运营能力。
50
+ - SSO/OIDC、MFA、设备管理和高风险操作二次确认。
51
+ - Feature Flag、灰度发布、离线能力和微前端承载。
52
+ - 复杂报表、打印模板、地图、富文本和实时协作。
53
+
54
+ 这些能力不应默认进入主包;通过明确的 Feature 或 Adapter 接入。
55
+
56
+ ## 运行模式契约
57
+
58
+ `runtime-config.json` 中 `app.strMode=demo` 时,仅认证使用内存数据。默认演示账号为
59
+ `13800000000`,密码为 `admin123`。刷新页面可恢复初始演示数据,不产生网络写入。
60
+
61
+ `app.strMode=connected` 时,认证 Adapter 连接真实服务。生产部署通过环境专属的运行时
62
+ 配置文件使用该模式。项目新增的业务 Feature 应自行定义 Repository 契约,并用生成的 OpenAPI
63
+ 客户端实现;真实数据不得在页面组件中分支,也不得在连接失败时回退到 demo 数据。
64
+
65
+ 可复制的中性 DTO、Repository、Demo/Connected Adapter、Query 和 Mutation 实现见
66
+ [`feature-data-template.md`](feature-data-template.md)。模板不注册路由,真实 Feature
67
+ 复制后拥有自己的契约,不能把模板变成跨业务共用的万能 CRUD 层。
68
+
69
+ ```text
70
+ Route / Feature
71
+ │
72
+ ▼
73
+ Domain repository contract
74
+ │
75
+ ├── demo adapter(内存数据)
76
+ └── connected adapter(OpenAPI client)
77
+ ```
78
+
79
+ ## 权限契约
80
+
81
+ 权限使用稳定的 `domain:resource:action` 字符串,例如 `inventory:item:read` 和
82
+ `inventory:item:write`;具体权限码由接入项目定义,脚手架不预置业务权限。
83
+
84
+ 路由元数据声明进入页面所需的权限;侧边栏和命令搜索从同一份路由元数据生成并自动
85
+ 过滤。页面中的写操作还必须单独检查写权限,不能因为页面可见就默认允许修改。
86
+ 后端仍是最终授权边界,前端权限只负责体验与提前阻断。
87
+
88
+ 操作权限通过 `usePermission` 和 `Can` 直接读取认证身份;表格使用同一判断结果设置
89
+ 工具栏与单元格动作的 `hidden/disabled`。Query/Mutation 使用请求权限包装器在调用生成
90
+ 客户端前阻断无权操作。刷新接口返回新身份时,权限、角色或租户变化会统一清理服务端
91
+ 缓存并重新校验当前路由,不建立独立权限 Store。
92
+
93
+ 全局枚举和全局参数都由 TanStack Query 持有服务端真相,并由 `MetadataProvider` 在认证
94
+ 完成后按租户、会话代次和语言并行加载。参数值在进入缓存前根据后端声明的
95
+ `boolean/number/string/json` 类型校验,提供 React 与非 React 读取入口。任一目录失败只
96
+ 影响使用该资源的 Feature,可单独重试,不得用全屏初始化状态阻塞无关页面。
97
+
98
+ ## 模块边界
99
+
100
+ ```text
101
+ app shell → router → feature → repository contract → api adapter
102
+ │
103
+ └── owned UI components
104
+ ```
105
+
106
+ - `features/` 只包含按领域组织的页面、领域模型和用例。
107
+ - `components/` 是脚手架自有 UI;常规 CRUD 使用源码内置的 `AppDataTable`,PageForm
108
+ 与高级 Table 通过项目入口导出并按需加载。
109
+ - `api/` 只处理协议、序列化和请求生命周期,不承载页面状态。
110
+ - `api/activity/` 用 Query 持有活动摘要并隔离传输生命周期,不保存完整通知/任务列表。
111
+ - `api/idempotency/` 只创建和校验幂等键;事务状态、结果确认与恢复能力由后端拥有。
112
+ - `files/` 只处理文件交互生命周期与 Adapter 契约,不包含接口地址、供应商或模板。
113
+ - `locale/` 统一语言、时区、Intl 和共享文案;业务语言包仍归所属 Feature。
114
+ - 可选 `tenantWorkspace/` 只编排当前稳定 ID 和切换事务;列表与成员关系仍归后端和 Feature。
115
+ - `stores/` 只保存会话、主题等跨 Feature 状态,服务端数据交给 TanStack Query。
116
+ - Feature 之间不得直接导入内部文件;共享行为提升到公共组件或基础设施。
117
+
118
+ 上述边界由 ESLint 和配置测试执行:每个一级 Feature 必须提供 `index.ts(x)`;路由、应用层
119
+ 和其他 Feature 只能从 `@/features/<featureName>` 公共入口导入,不能访问内部文件;Feature
120
+ 不能反向依赖 `router/`、`layouts/`、`Application` 或 `main`。Feature 可直接使用框架路由
121
+ Hook,但共享跳转策略应位于 `lib/` 或由上层组合注入。白盒测试允许直接导入内部单元,
122
+ 不为测试扩大生产公共 API。
123
+
124
+ 上传、下载、图片/PDF 预览以及同步/异步导入导出任务已形成独立文件能力层。Feature
125
+ 通过生成客户端注入请求;大文件、Office 预览和对象存储通过可替换 Adapter 接入,具体
126
+ 接法见 [`file-capabilities.md`](file-capabilities.md)。
127
+
128
+ 应用语言同时驱动共享文案、格式化和后端元数据语言,部署环境使用 IANA 时区固定业务
129
+ 日期边界;Feature 语言包不注册进全局目录。详细契约和迁移状态见
130
+ [`locale-and-i18n.md`](locale-and-i18n.md)。
131
+
132
+ 默认 core 的当前租户以认证会话为唯一来源,不建立工作空间全局状态。需要切换时加入
133
+ `tenantWorkspace` 能力:工作空间选择绑定用户与租户、切换先由后端确认,跨租户时还必须
134
+ 返回新会话。缓存隔离、失败重试和 generated API Adapter 见
135
+ [`tenant-workspace-context.md`](tenant-workspace-context.md)。
136
+
137
+ 有重复副作用风险的 Mutation 使用统一幂等键和结果确认控制器;生成客户端接线、按钮
138
+ 状态、超时恢复及后端强制契约见
139
+ [`mutation-idempotency.md`](mutation-idempotency.md)。
140
+
141
+ `AppTable` 统一提供显式/跨页选择和工具栏回调。批量业务请求不得在共享组件中推断,
142
+ Feature 应使用后端批量接口,并组合权限、幂等 Mutation 与 `AppDialog` 完成具体流程。
143
+
144
+ ## PageForm 与 Table 内建策略
145
+
146
+ PageForm 与高级 Table 都由模板维护仓库持有源码,不再依赖内部 Git Node 包。生成的 `core`
147
+ 项目默认只包含 PageForm、AppDataTable;高级 Table 通过 `advancedTable` 能力复制到目标项目。
148
+ 组件边界如下:
149
+
150
+ 1. 所有页面只依赖 `AppPageForm`、`AppDataTable` 或 `AppTable`,形成稳定的项目边界。
151
+ 2. `AppPageForm` 以单个应用组件目录组织,不保留 `core/`、`react/` 或发布包目录。
152
+ 3. `AppTable` 保留 `engine/`、`config/`、`styles/` 三个基础边界,React 能力直接按
153
+ `table/`、`search/`、`selection/`、`toolbar/` 等表格领域组织,不再套 package 或
154
+ adapter 目录;Feature 只能通过组件根入口使用,不能直接导入实现目录。
155
+
156
+ 不直接把完整多框架仓库复制进 `src/`:Vue Adapter、发布脚本、包管理配置和无关示例
157
+ 不属于 React 脚手架。当前 Table 源码基线为提交
158
+ `d11c1a1a9837108da59eec41b482f83f5a8fac73`(package `0.4.0`);迁移前后必须运行
159
+ 原组件测试与应用集成测试,避免悄悄丢失编辑、查询、导出、偏好和授权能力。
160
+
161
+ 标准系统页面不得因为基础列表加载 Handsontable、Excel 导出或公式计算依赖。高级
162
+ `AppTable` 只由确实需要编辑、导出、偏好等能力的 Feature 引入;生产环境还必须配置
163
+ 商业许可证,评估许可证会被显式拒绝。
164
+
165
+ ## 页面准入标准
166
+
167
+ 新增到脚手架的页面必须满足:
168
+
169
+ - 默认路由只承载项目真实需要的页面;演示页面放在项目自有示例或文档中,不进入壳层。
170
+ - demo 与 connected 共用页面和领域契约。
171
+ - 声明读取与写入权限,使用统一页面反馈契约覆盖加载、空、错误、无权限、重试中和成功状态。
172
+ - 页面内错误与全局 Toast 不重复;错误恢复保留请求 ID,已有内容不因后台刷新被整页替换。
173
+ - 键盘可操作,表单错误可定位,并在桌面端常用窗口尺寸和缩放比例下保持可用。
174
+ - 有覆盖用户可见行为的浏览器测试,并通过 `pnpm verify`。
175
+
176
+ 状态判定、`ApiError` 重试边界和生成客户端 `bShowError` 接线见
177
+ [`page-feedback.md`](page-feedback.md)。
178
+
179
+ 应用壳层在真实 Chromium 中执行浅色、深色 axe 冒烟,并以键盘完成登录、进入受保护
180
+ 首页和退出旅程。全局 `primary`、`secondary`、`destructive` 与
181
+ `muted-foreground` 语义色必须满足其文本用途的 WCAG AA 对比度;高级表格作用域主题与
182
+ 应用主题使用相同的可访问色值。axe 不替代复合控件的键盘和焦点行为测试。
183
+
184
+ ## 建设顺序
185
+
186
+ 具体状态、验收标准和逐项实施顺序统一维护在
187
+ [`scaffold-capability-roadmap.md`](scaffold-capability-roadmap.md),本文件不再维护第二份
188
+ 进度清单。
189
+
190
+ 模板和派生项目独立版本化:应用版本进入发布产物,已应用模板版本进入项目状态文件;升级
191
+ 前通过只读目录检查证明连续路径,升级和回滚都以完整 Git 提交为单位。维护契约见
192
+ [`template-versioning.md`](template-versioning.md)。
193
+
194
+ 多品牌采用部署级 Runtime Config:同一不可变构建按站点注入名称、明暗 Logo、Favicon 和
195
+ 受限语义色,设计系统继续拥有背景、文字、状态与焦点体系。禁止复制应用源码或通过配置注入
196
+ 任意 CSS,契约见 [`white-label.md`](white-label.md)。
197
+
198
+ 每一步都保持主分支可运行,不用未完成的空菜单冒充能力。
199
+
200
+ 新项目安装依赖后先运行 `pnpm scaffold:check`;首次交付前使用 `--strict` 阻断默认包名、
201
+ 品牌、存储命名空间、认证参数、demo 模式和占位 OpenAPI 服务名。命令复用 Vite 配置加载和浏览器
202
+ Runtime Config Schema,不维护第二份配置真相。
203
+
204
+ CI 中只有 `verify` 阶段构建前端,`package` 和 `deploy` 必须校验静态文件摘要、Commit 以及
205
+ Registry 镜像 Digest。环境专属 `runtime-config.json` 不进入镜像摘要,在容器启动前单独
206
+ 注入。生产构建还会按入口和关键路由静态依赖图执行 gzip 体积预算,内部 Vite Manifest
207
+ 不会进入发布站点。完整预算策略见 [`bundle-budgets.md`](bundle-budgets.md),晋级、回滚和
208
+ 本地验证流程见 [`../deploy/README.md`](../deploy/README.md)。
@@ -0,0 +1,227 @@
1
+ # 中性 Feature 数据模板
2
+
3
+ `tools/scaffold/templates/feature` 是 Feature 生成器拥有的源码模板,不属于应用运行时
4
+ `src/features`。它用中性的“记录”演示一个企业 Feature 如何连接 Swagger 生成客户端,
5
+ 同时保持领域模型、缓存和页面状态不依赖传输 DTO。模板本身不是万能 CRUD 框架,也不是
6
+ 所有 Feature 运行时共同依赖的共享业务模块。
7
+
8
+ ## 目录和所有权
9
+
10
+ ```text
11
+ tools/scaffold/templates/feature/
12
+ types.ts DTO、领域模型、Feature 实例和 Hook 契约
13
+ model.ts 不可信 DTO 的运行时校验、映射与输入规范化
14
+ repository.ts Demo/Connected Adapter 选择和数据访问实现
15
+ queries.ts Feature 自有的列表、详情 Query 与更新 Mutation
16
+ index.ts 唯一跨 Feature 公共入口
17
+ ```
18
+
19
+ `index.ts` 是唯一面向 Feature 外部的入口。Feature 内部文件使用相对路径;路由、其他
20
+ Feature 和应用组合层不得直接导入 `model.ts`、`repository.ts`、`queries.ts` 或 `types.ts`。
21
+ 该约束由 ESLint 和 `test:config` 自动检查。
22
+
23
+ 依赖方向固定为:
24
+
25
+ ```text
26
+ Feature UI / Route
27
+ │
28
+ ▼
29
+ Feature Query hooks ──► 不透明 Feature 运行实例
30
+ │
31
+ ▼
32
+ 内部 Repository contract ──► Query、权限与错误基础设施
33
+ │
34
+ ├── Demo Adapter(Feature 自有内存数据)
35
+ └── Connected Adapter(swagger-typescript-api 生成客户端)
36
+ │
37
+ ▼
38
+ DTO → domain mapping
39
+ ```
40
+
41
+ 页面只接收由组合点创建的 `ITemplateRecordFeature`,不读取 Repository 和权限码,不判断
42
+ `demo/connected`,不解析 DTO,也不直接调用生成客户端。服务端数据只存在于 TanStack
43
+ Query;Repository 和 Hook 都不会把它复制到 Zustand。
44
+
45
+ ## 初始化真实 Feature
46
+
47
+ 先用生成器完成确定性改名。下面示例生成 `customerManagement` Feature,领域模型为
48
+ `CustomerRecord`,Query Resource Key 和权限前缀为 `customer:record`:
49
+
50
+ ```bash
51
+ pnpm scaffold:feature --name customerManagement --model CustomerRecord --resource customer:record
52
+ pnpm scaffold:feature --name customerManagement --model CustomerRecord --resource customer:record --write
53
+ ```
54
+
55
+ 第一次命令只预览将创建的文件;追加 `--write` 后才会同时生成:
56
+
57
+ ```text
58
+ src/features/customerManagement/
59
+ index.ts
60
+ model.ts
61
+ queries.ts
62
+ repository.ts
63
+ types.ts
64
+ tests/unit/features/customerManagement/
65
+ feature.test.ts
66
+ publicContract.test.ts
67
+ queries.test.tsx
68
+ ```
69
+
70
+ 参数契约保持刻意收敛:
71
+
72
+ | 参数 | 约束 | 所有权 |
73
+ | ------------ | ---------------------------------- | ---------------------------------------------- |
74
+ | `--name` | 1 到 60 位 `lowerCamelCase` | Feature 目录、公共导入路径与 Query Feature Key |
75
+ | `--model` | 1 到 60 位 `PascalCase` | 领域模型、Repository、Hook 和错误码标识 |
76
+ | `--resource` | 小写资源名,可使用 `-` 或 `:` 分段 | Query Resource Key 与读写权限前缀 |
77
+
78
+ 源码目录或测试目录只要存在同名或大小写等价目录,生成器都会以
79
+ `FEATURE_CREATE_CONFLICT` 停止,绝不合并或覆盖文件。写入发生异常时只清理由本次命令创建的
80
+ 未完成目录。
81
+
82
+ 生成后继续完成真实接入:
83
+
84
+ 1. 用 `pnpm api` 生成的 DTO 类型替换模板 DTO;不要修改 `src/api/generated`。
85
+ 2. 在 `model.ts` 保留运行时校验和 DTO 到领域对象的显式映射。
86
+ 3. 在 `repository.ts` 用生成客户端实现 Connected Source,并准备同契约 Demo 数据。
87
+ 4. 在 Feature 组合点根据后端授权模型声明真实读写权限码。
88
+ 5. 从 Feature 根 `index.ts` 只导出页面或其他 Feature 真正需要的契约。
89
+ 6. 根据真实行为更新随模块生成的测试,再显式注册路由。
90
+
91
+ 生成器不会创建产品页面,不会修改 Router、菜单或 `knip.config.ts`,不会调用后端或执行
92
+ `pnpm api`。路由是否存在、页面挂在哪个 Layout、菜单和权限元数据是什么,必须由项目
93
+ 根据真实业务显式决定。
94
+
95
+ 生成完成后,真实 Feature 拥有自己的模型、Repository 和查询策略,不依赖工具目录中的
96
+ 模板源码。模板作为 `scaffold:feature` 的确定性输入长期保留在工具层,不进入应用生产包;
97
+ 删除它会使后续 Feature 生成失败,因此不再把它当作可随意删除的运行时示例。
98
+
99
+ ## 接入 Swagger 生成客户端
100
+
101
+ 脚手架通过 `swagger-typescript-api` 按 `src/api/config/services.json` 生成客户端。生成
102
+ 方法已经自动返回响应数据,并通过 `fnConfigureApiClient()` 获得认证刷新、请求 ID、取消和
103
+ 标准 `ApiError`。真实方法名和 DTO 名以当前 OpenAPI 契约为准,下面的 `recordsList` 等名称
104
+ 只是接线位置示意:
105
+
106
+ ```ts
107
+ import { fnConfigureApiClient } from '@/api'
108
+ import { objAppConfig } from '@/config/appConfig'
109
+ import { Api } from '@/api/generated/backend/Api'
110
+ import type { IConnectedCustomerRecordSource } from '@/features/customerManagement'
111
+
112
+ const objGeneratedApi = fnConfigureApiClient(
113
+ new Api<void>({ baseURL: objAppConfig.api.strBaseUrl })
114
+ )
115
+
116
+ const objConnectedSource: IConnectedCustomerRecordSource = {
117
+ fnGet: (strRecordId, objSignal) =>
118
+ objGeneratedApi.records.recordsDetail(strRecordId, {
119
+ bShowError: false,
120
+ signal: objSignal,
121
+ }),
122
+ fnList: (objInput, objSignal) =>
123
+ objGeneratedApi.records.recordsList(
124
+ {
125
+ keyword: objInput.strKeyword,
126
+ page: objInput.nPage,
127
+ pageSize: objInput.nPageSize,
128
+ },
129
+ { bShowError: false, signal: objSignal }
130
+ ),
131
+ fnUpdate: (objInput) =>
132
+ objGeneratedApi.records.recordsUpdate(objInput.strRecordId, {
133
+ enabled: objInput.objChanges.bIsEnabled,
134
+ expectedRevision: objInput.nExpectedRevision,
135
+ name: objInput.objChanges.strName,
136
+ }),
137
+ }
138
+ ```
139
+
140
+ 如果生成 DTO 字段可选、接口使用响应信封或命名不同,只在 Connected Source 和 `model.ts`
141
+ 处理。不要为了匹配页面而修改 Eta 模板或生成文件,也不要把 Axios Response 传到 Feature
142
+ UI。模板保留 `id/name/enabled/revision/items/total` 外部字段名,是为了明确展示 DTO 与
143
+ `strId/strName/bIsEnabled/nRevision/arrRecords/nTotal` 领域模型之间的边界。
144
+
145
+ ## Demo/Connected 组合
146
+
147
+ 应用组合点从同一个运行时配置创建 Feature 运行实例。它一次性隐藏 Repository、权限和
148
+ 模式选择;Connected 缺少数据源时会立即报错,不会在网络故障或配置错误时静默回退到
149
+ Demo 数据:
150
+
151
+ ```ts
152
+ const objRecordFeature = fnCreateCustomerRecordFeature({
153
+ strMode: objAppConfig.runtime.strMode,
154
+ strReadPermission: 'domain:record:read',
155
+ strWritePermission: 'domain:record:write',
156
+ objConnectedSource,
157
+ arrDemoRecords: [
158
+ {
159
+ bIsEnabled: true,
160
+ nRevision: 0,
161
+ strId: 'record-1',
162
+ strName: '示例记录',
163
+ },
164
+ ],
165
+ })
166
+ ```
167
+
168
+ Demo Adapter 支持分页、关键字、取消、404 和基于 `nExpectedRevision` 的 409 冲突;更新只
169
+ 修改自身闭包数据,刷新后恢复初始值。Connected Adapter 依赖后端完成最终授权、事务和
170
+ 版本检查。
171
+
172
+ ## Query 与 Mutation
173
+
174
+ 列表和详情 Hook 只接收组合好的 Feature 运行实例,并自动复用应用级用户、租户、语言、
175
+ 会话版本和工作空间 Query 作用域:
176
+
177
+ ```tsx
178
+ const objListQuery = useTemplateRecordList({
179
+ objFeature: objRecordFeature,
180
+ objInput: { nPage: 1, nPageSize: 20, strKeyword },
181
+ strWorkspaceId,
182
+ })
183
+
184
+ const objDetailQuery = useTemplateRecordDetail({
185
+ objFeature: objRecordFeature,
186
+ strRecordId,
187
+ strWorkspaceId,
188
+ })
189
+ ```
190
+
191
+ 更新 Hook 绑定单个实体,因此同一实体 Mutation 串行、不同实体并行。详情存在缓存时执行
192
+ 可逆乐观更新;失败恢复快照;完成后用统一 Key 失效详情和列表。按钮仍应使用
193
+ `objMutation.isPending` 防止用户无意重复激活:
194
+
195
+ ```tsx
196
+ const objMutation = useUpdateTemplateRecord({
197
+ objFeature: objRecordFeature,
198
+ strRecordId,
199
+ strWorkspaceId,
200
+ })
201
+
202
+ objMutation.mutate({
203
+ nExpectedRevision: objDetailQuery.data.nRevision,
204
+ objChanges: { strName: '新名称' },
205
+ })
206
+ ```
207
+
208
+ Query 取消信号会一直传到生成客户端。Mutation 一旦到达服务端默认不假设可取消;具有
209
+ 重复副作用风险的命令使用
210
+ [`mutation-idempotency.md`](mutation-idempotency.md) 的原键重试与结果确认协议,不能由
211
+ 本地缓存替代。
212
+
213
+ 页面首次加载、成功空态、错误恢复、后台刷新及 Toast 归属规则见
214
+ [`page-feedback.md`](page-feedback.md)。列表和详情请求由页面内错误态负责时,Connected
215
+ Source 必须传入 `bShowError: false`,避免统一响应 Hook 和页面重复提示同一次失败。
216
+
217
+ ## 模板明确不做的事
218
+
219
+ - 不注册示例路由、菜单、页面或产品数据。
220
+ - 不提供全局 Repository 容器、Service Locator 或万能 CRUD 配置。
221
+ - 不要求所有 Feature 都拥有列表、详情和乐观更新;按真实工作流删减。
222
+ - 不将客户端权限检查当作后端授权。
223
+ - 不在 Connected 失败时显示 Demo 数据。
224
+ - 不让其他 Feature 导入 `model.ts`、`repository.ts` 或 `queries.ts` 内部路径。
225
+
226
+ 模板契约测试位于 `tests/unit/scaffoldFeatureTemplate`,覆盖 DTO 拒绝、双 Adapter、取消、
227
+ 版本冲突、权限阻断、作用域 Key 以及 Mutation 后列表/详情缓存收敛。
@@ -0,0 +1,169 @@
1
+ # Feature Flag、灰度与 Kill Switch 接入
2
+
3
+ `src/featureFlags` 提供厂商中立的 Feature Flag 运行时边界。它解决的是应用如何
4
+ 声明开关、隔离缓存、消费后端已评估结果,以及远端不可用时如何安全降级;不在
5
+ 浏览器中实现百分比、人群、权限或租户灰度规则。
6
+
7
+ ## 职责边界
8
+
9
+ | 层级 | 负责内容 | 不负责内容 |
10
+ | ---------------------- | --------------------------------------------------------- | ------------------------------ |
11
+ | 后端 Feature Flag 服务 | 规则、人群、百分比、租户和权限判断,返回已评估结果 | 前端展示 |
12
+ | 项目 Adapter | 用 Swagger 生成客户端请求接口,并映射成脚手架目录契约 | 重新实现请求客户端 |
13
+ | `src/featureFlags` | 本地定义、安全默认、作用域缓存、有效期、刷新和 React 接入 | 权威鉴权、业务规则 |
14
+ | Feature | 根据评估结果控制入口、流程与回退体验 | 拼接远端规则或直接调用厂商 SDK |
15
+
16
+ Feature Flag 只影响前端呈现和行为。敏感数据、接口权限和操作合法性仍必须由后端
17
+ 授权。浏览器不得接收完整灰度规则、用户画像、Token 或供应商管理密钥。
18
+
19
+ ## 声明本地安全策略
20
+
21
+ 应用只请求显式声明的 Key。未知 Key 会立即抛出 `FeatureFlagError`,避免拼写错误
22
+ 静默变成关闭状态。
23
+
24
+ ```ts
25
+ import type { IFeatureFlagDefinition } from '@/featureFlags'
26
+
27
+ export const arrFeatureFlagDefinitions: readonly IFeatureFlagDefinition[] = [
28
+ {
29
+ bSafeDefault: false,
30
+ strKey: 'orders.bulkExport',
31
+ strKind: 'killSwitch',
32
+ },
33
+ {
34
+ bAllowStale: true,
35
+ bSafeDefault: false,
36
+ nMaxStaleMs: 5 * 60_000,
37
+ strKey: 'navigation.newShell',
38
+ strKind: 'release',
39
+ },
40
+ ]
41
+ ```
42
+
43
+ 三种用途的约束如下:
44
+
45
+ - `killSwitch`:用于高风险能力,强制 `bSafeDefault: false`,禁止使用过期结果。
46
+ - `release`:用于渐进发布;只有显式配置 `bAllowStale` 和有限
47
+ `nMaxStaleMs` 才能短暂使用最近结果。
48
+ - `experiment`:用于服务端已完成分组的实验,可读取 `strVariant` 和
49
+ `objPayload`,前端不自行分桶。
50
+
51
+ ## 对接 Swagger 生成客户端
52
+
53
+ `fnCreateFeatureFlagSource` 接收项目 Adapter 请求函数。下面仅展示映射位置,实际
54
+ 方法名和响应字段以生成代码为准:
55
+
56
+ ```ts
57
+ import { fnCreateFeatureFlagSource } from '@/featureFlags'
58
+ import { objGeneratedApi } from '@/api/generated/project'
59
+
60
+ export const objFeatureFlagSource = fnCreateFeatureFlagSource(
61
+ async ({ arrFlagKeys, objScope, objSignal }) => {
62
+ const objResponse = await objGeneratedApi.featureFlags.evaluate(
63
+ {
64
+ environment: objScope.strEnvironment,
65
+ keys: arrFlagKeys,
66
+ sessionGeneration: objScope.nSessionGeneration,
67
+ tenantId: objScope.strTenantId,
68
+ userId: objScope.strUserId,
69
+ workspaceId: objScope.strWorkspaceId,
70
+ },
71
+ { signal: objSignal }
72
+ )
73
+
74
+ return {
75
+ nEvaluatedAt: objResponse.data.evaluatedAt,
76
+ nExpiresAt: objResponse.data.expiresAt,
77
+ objFlags: Object.fromEntries(
78
+ objResponse.data.flags.map((objFlag) => [
79
+ objFlag.key,
80
+ {
81
+ bEnabled: objFlag.enabled,
82
+ objPayload: objFlag.payload,
83
+ strReason: objFlag.reason,
84
+ strVariant: objFlag.variant,
85
+ },
86
+ ])
87
+ ),
88
+ version: objResponse.data.version,
89
+ }
90
+ }
91
+ )
92
+ ```
93
+
94
+ Adapter 返回值会做运行时校验并深度冻结。时间戳必须是有限的毫秒值,且
95
+ `nExpiresAt` 必须晚于 `nEvaluatedAt`。请求取消通过 `objSignal` 传给生成客户端。
96
+
97
+ ## 应用装配
98
+
99
+ 这是按需能力,默认 `Application` 不装配 Provider。项目应在需要开关的认证布局或 Feature
100
+ 边界挂载,并从现有查询作用域补充用户、租户、工作空间和会话隔离信息:
101
+
102
+ ```tsx
103
+ const objQueryScope = useAppQueryScope()
104
+
105
+ <FeatureFlagProvider
106
+ arrDefinitions={arrFeatureFlagDefinitions}
107
+ bIsEnabled={bIsAuthenticated}
108
+ objScope={{
109
+ strEnvironment: 'production',
110
+ nSessionGeneration: objQueryScope.nSessionGeneration,
111
+ strTenantId: objQueryScope.strTenantId,
112
+ strUserId: objQueryScope.strUserId,
113
+ strWorkspaceId: objQueryScope.strWorkspaceId,
114
+ }}
115
+ objSource={objFeatureFlagSource}
116
+ >
117
+ {objChildren}
118
+ </FeatureFlagProvider>
119
+ ```
120
+
121
+ 未配置数据源、关闭远端能力、首次加载和请求失败都不会阻塞子树渲染,而是立即返回本地
122
+ 安全默认值。匿名页面确实需要开关时,可以在公开页面边界单独挂载并提供匿名作用域;不要
123
+ 为了少写一层 Provider 把它重新塞回全局 `Application`。
124
+
125
+ ## Feature 消费
126
+
127
+ ```tsx
128
+ import { FeatureGate, useFeatureFlag } from '@/featureFlags'
129
+
130
+ function ExportEntry() {
131
+ const objFlag = useFeatureFlag('orders.bulkExport')
132
+
133
+ return (
134
+ <FeatureGate
135
+ objFallback={<p>批量导出暂不可用</p>}
136
+ strFlagKey="orders.bulkExport"
137
+ >
138
+ <ExportButton strVariant={objFlag.strVariant} />
139
+ </FeatureGate>
140
+ )
141
+ }
142
+ ```
143
+
144
+ `bEnabled` 是最终状态;`bIsFallback`、`strEvaluationSource`、
145
+ `strEvaluationReason` 和 `strVersion` 用于非敏感诊断。长任务不能只隐藏入口:
146
+ Feature 还应在开关关闭时取消尚未提交的前端工作,后端必须独立拒绝已关闭的危险
147
+ 操作。
148
+
149
+ ## 缓存、刷新与降级
150
+
151
+ - 缓存仅保存在现有 React Query 内存缓存中,不写 `localStorage`,避免跨用户泄漏。
152
+ - Query Key 包含环境、用户、租户、工作空间、会话代次和排序后的声明 Key。
153
+ - 目录按后端 `nExpiresAt` 自动刷新;失败后以一分钟间隔恢复请求。
154
+ - 新作用域会取消或隔离旧请求;登出、租户切换和会话代次变化不会复用旧身份结果。
155
+ - Kill Switch 过期立即关闭。其他类型只有声明了有限 stale 窗口才可继续使用旧值。
156
+ - `fnInvalidateFeatureFlags` 用于管理操作、会话变化或项目事件触发主动失效;
157
+ `fnEnsureFeatureFlags` 和 `fnGetCachedFeatureFlags` 支持 Loader 场景。
158
+
159
+ 不要把“最后一次成功结果”永久持久化。离线持久化涉及用户身份、敏感配置和撤销
160
+ 时效,属于 P2-08 的独立策略,不由本模块隐式开启。
161
+
162
+ ## 验收重点
163
+
164
+ - 无数据源和请求失败时,所有已声明开关都有确定的本地结果。
165
+ - Kill Switch 无法配置为默认开启,也无法允许过期结果。
166
+ - 远端目录、单项值、有效期和 JSON Payload 都经过运行时校验。
167
+ - 不同用户、租户、工作空间、会话代次和环境不会共享缓存。
168
+ - React 消费者共享同一请求,远端失败不阻塞应用子树。
169
+ - 前端没有人群规则、权限替代逻辑、厂商密钥和业务页面。