create-wakii-stack 0.0.0-stage → 0.1.1

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 (998) hide show
  1. package/README.md +66 -2
  2. package/dist/chunk-7XGW4UJ5.js +75 -0
  3. package/dist/chunk-AKPWS7FJ.js +76 -0
  4. package/dist/chunk-ELM6GGC5.js +50 -0
  5. package/dist/chunk-ON2WTGZH.js +77 -0
  6. package/dist/index.js +391 -0
  7. package/dist/manifest-2JVLRMDB.js +10 -0
  8. package/dist/manifest-O35TPW73.js +10 -0
  9. package/dist/manifest-TXTY67BF.js +10 -0
  10. package/dist/manifest-XWHR7Y3F.js +10 -0
  11. package/package.json +23 -4
  12. package/stack-template/.changeset/config.json +15 -0
  13. package/stack-template/.changeset/vu53-ui-redesign.md +11 -0
  14. package/stack-template/.claude/agents/be-dev.md +56 -0
  15. package/stack-template/.claude/agents/contracts-keeper.md +51 -0
  16. package/stack-template/.claude/agents/e2e-runner.md +61 -0
  17. package/stack-template/.claude/agents/fe-dev.md +53 -0
  18. package/stack-template/.claude/settings.json +77 -0
  19. package/stack-template/.claude/settings.local.json +9 -0
  20. package/stack-template/.claude/skills/add-service/SKILL.md +81 -0
  21. package/stack-template/.claude/skills/sync-contracts/SKILL.md +74 -0
  22. package/stack-template/.editorconfig +21 -0
  23. package/stack-template/.gitattributes +10 -0
  24. package/stack-template/.github/pull_request_template.md +26 -0
  25. package/stack-template/.github/workflow-templates/services-ci.yml.example +69 -0
  26. package/stack-template/.github/workflows/contracts.yml +133 -0
  27. package/stack-template/.github/workflows/convergence.yml +209 -0
  28. package/stack-template/.github/workflows/git-guard.yml +44 -0
  29. package/stack-template/.github/workflows/publish-uikit.yml +96 -0
  30. package/stack-template/.github/workflows/remotes-activity.yml +82 -0
  31. package/stack-template/.github/workflows/remotes-tasks.yml +82 -0
  32. package/stack-template/.github/workflows/services-auth-svc.yml +153 -0
  33. package/stack-template/.github/workflows/services-go-svc.yml +281 -0
  34. package/stack-template/.github/workflows/services-node-svc.yml +173 -0
  35. package/stack-template/.github/workflows/services-spring-svc.yml +132 -0
  36. package/stack-template/.github/workflows/shell.yml +78 -0
  37. package/stack-template/.github/workflows/ui-kit.yml +51 -0
  38. package/stack-template/.husky/commit-msg +14 -0
  39. package/stack-template/.husky/pre-push +51 -0
  40. package/stack-template/.spectral.yaml +17 -0
  41. package/stack-template/AGENTS.md +197 -0
  42. package/stack-template/CLAUDE.md +114 -0
  43. package/stack-template/README.md +172 -0
  44. package/stack-template/app/admin/index.html +12 -0
  45. package/stack-template/app/admin/package.json +40 -0
  46. package/stack-template/app/admin/scripts/verify-chart.mjs +49 -0
  47. package/stack-template/app/admin/src/App.test.tsx +70 -0
  48. package/stack-template/app/admin/src/App.tsx +33 -0
  49. package/stack-template/app/admin/src/data/users.ts +47 -0
  50. package/stack-template/app/admin/src/layout/AdminLayout.tsx +212 -0
  51. package/stack-template/app/admin/src/main.tsx +17 -0
  52. package/stack-template/app/admin/src/pages/ComponentsDemo.tsx +138 -0
  53. package/stack-template/app/admin/src/pages/Dashboard.tsx +182 -0
  54. package/stack-template/app/admin/src/pages/HooksDemo.tsx +153 -0
  55. package/stack-template/app/admin/src/pages/Settings.tsx +156 -0
  56. package/stack-template/app/admin/src/pages/UploadPage.tsx +34 -0
  57. package/stack-template/app/admin/src/pages/Users.test.tsx +66 -0
  58. package/stack-template/app/admin/src/pages/Users.tsx +245 -0
  59. package/stack-template/app/admin/src/styles.css +9 -0
  60. package/stack-template/app/admin/src/tests/setup.ts +15 -0
  61. package/stack-template/app/admin/tsconfig.json +18 -0
  62. package/stack-template/app/admin/vite.config.ts +11 -0
  63. package/stack-template/app/admin/vitest.config.ts +14 -0
  64. package/stack-template/app/create-wakii-app/README.md +71 -0
  65. package/stack-template/app/create-wakii-app/package.json +27 -0
  66. package/stack-template/app/create-wakii-app/scripts/publish-npm.sh +38 -0
  67. package/stack-template/app/create-wakii-app/src/index.ts +127 -0
  68. package/stack-template/app/create-wakii-app/src/options.test.ts +80 -0
  69. package/stack-template/app/create-wakii-app/src/options.ts +117 -0
  70. package/stack-template/app/create-wakii-app/src/scaffold.test.ts +143 -0
  71. package/stack-template/app/create-wakii-app/src/scaffold.ts +194 -0
  72. package/stack-template/app/create-wakii-app/tsconfig.json +17 -0
  73. package/stack-template/app/create-wakii-app/vitest.config.ts +9 -0
  74. package/stack-template/app/create-wakii-stack/package.json +27 -0
  75. package/stack-template/app/create-wakii-stack/src/manifest.ts +101 -0
  76. package/stack-template/app/create-wakii-stack/src/options.ts +106 -0
  77. package/stack-template/app/create-wakii-stack/src/scaffold.ts +315 -0
  78. package/stack-template/app/create-wakii-stack/tsconfig.json +17 -0
  79. package/stack-template/app/create-wakii-stack/vitest.config.ts +9 -0
  80. package/stack-template/app/remotes/activity/Dockerfile +36 -0
  81. package/stack-template/app/remotes/activity/README.md +59 -0
  82. package/stack-template/app/remotes/activity/index.html +11 -0
  83. package/stack-template/app/remotes/activity/nginx.conf +35 -0
  84. package/stack-template/app/remotes/activity/package.json +40 -0
  85. package/stack-template/app/remotes/activity/rspack.config.mjs +152 -0
  86. package/stack-template/app/remotes/activity/src/ActivityPage.tsx +139 -0
  87. package/stack-template/app/remotes/activity/src/api.ts +63 -0
  88. package/stack-template/app/remotes/activity/src/app.css +7 -0
  89. package/stack-template/app/remotes/activity/src/components/FeedItem.tsx +39 -0
  90. package/stack-template/app/remotes/activity/src/components/StatTile.tsx +24 -0
  91. package/stack-template/app/remotes/activity/src/components/Timeline.tsx +53 -0
  92. package/stack-template/app/remotes/activity/src/components/time.ts +30 -0
  93. package/stack-template/app/remotes/activity/src/env.d.ts +5 -0
  94. package/stack-template/app/remotes/activity/src/index.tsx +12 -0
  95. package/stack-template/app/remotes/activity/src/standalone.tsx +36 -0
  96. package/stack-template/app/remotes/activity/tests/ActivityPage.test.tsx +260 -0
  97. package/stack-template/app/remotes/activity/tests/api.test.ts +61 -0
  98. package/stack-template/app/remotes/activity/tests/setup.ts +1 -0
  99. package/stack-template/app/remotes/activity/tests/test-utils.tsx +16 -0
  100. package/stack-template/app/remotes/activity/tsconfig.json +26 -0
  101. package/stack-template/app/remotes/activity/vitest.config.ts +38 -0
  102. package/stack-template/app/remotes/tasks/Dockerfile +36 -0
  103. package/stack-template/app/remotes/tasks/README.md +59 -0
  104. package/stack-template/app/remotes/tasks/index.html +11 -0
  105. package/stack-template/app/remotes/tasks/nginx.conf +35 -0
  106. package/stack-template/app/remotes/tasks/package.json +41 -0
  107. package/stack-template/app/remotes/tasks/rspack.config.mjs +153 -0
  108. package/stack-template/app/remotes/tasks/src/TasksPage.tsx +284 -0
  109. package/stack-template/app/remotes/tasks/src/api.ts +109 -0
  110. package/stack-template/app/remotes/tasks/src/app.css +7 -0
  111. package/stack-template/app/remotes/tasks/src/components/StatusBadge.tsx +20 -0
  112. package/stack-template/app/remotes/tasks/src/components/StatusSelect.tsx +27 -0
  113. package/stack-template/app/remotes/tasks/src/components/TaskForm.tsx +74 -0
  114. package/stack-template/app/remotes/tasks/src/components/TaskItem.tsx +199 -0
  115. package/stack-template/app/remotes/tasks/src/components/TaskList.tsx +60 -0
  116. package/stack-template/app/remotes/tasks/src/components/status.ts +23 -0
  117. package/stack-template/app/remotes/tasks/src/env.d.ts +5 -0
  118. package/stack-template/app/remotes/tasks/src/index.tsx +12 -0
  119. package/stack-template/app/remotes/tasks/src/standalone.tsx +38 -0
  120. package/stack-template/app/remotes/tasks/tests/TasksPage.test.tsx +445 -0
  121. package/stack-template/app/remotes/tasks/tests/api.test.ts +159 -0
  122. package/stack-template/app/remotes/tasks/tests/setup.ts +1 -0
  123. package/stack-template/app/remotes/tasks/tests/test-utils.tsx +16 -0
  124. package/stack-template/app/remotes/tasks/tsconfig.json +26 -0
  125. package/stack-template/app/remotes/tasks/vitest.config.ts +34 -0
  126. package/stack-template/app/shared/README.md +21 -0
  127. package/stack-template/app/shared/package.json +37 -0
  128. package/stack-template/app/shared/src/api-client.ts +66 -0
  129. package/stack-template/app/shared/src/error-envelope.ts +38 -0
  130. package/stack-template/app/shared/src/index.ts +21 -0
  131. package/stack-template/app/shared/src/mf-bootstrap.ts +89 -0
  132. package/stack-template/app/shared/src/refresh-client.ts +170 -0
  133. package/stack-template/app/shared/src/token-storage.ts +57 -0
  134. package/stack-template/app/shell/Dockerfile +37 -0
  135. package/stack-template/app/shell/README.md +79 -0
  136. package/stack-template/app/shell/index.html +11 -0
  137. package/stack-template/app/shell/nginx.conf +23 -0
  138. package/stack-template/app/shell/package.json +43 -0
  139. package/stack-template/app/shell/rspack.config.mjs +147 -0
  140. package/stack-template/app/shell/src/App.tsx +57 -0
  141. package/stack-template/app/shell/src/api.ts +36 -0
  142. package/stack-template/app/shell/src/app.css +11 -0
  143. package/stack-template/app/shell/src/bootstrap.tsx +24 -0
  144. package/stack-template/app/shell/src/components/Layout.tsx +35 -0
  145. package/stack-template/app/shell/src/components/NavBar.tsx +118 -0
  146. package/stack-template/app/shell/src/components/RemoteSlot.tsx +82 -0
  147. package/stack-template/app/shell/src/components/RequireAuth.tsx +14 -0
  148. package/stack-template/app/shell/src/env.d.ts +7 -0
  149. package/stack-template/app/shell/src/index.tsx +3 -0
  150. package/stack-template/app/shell/src/pages/HomePage.tsx +70 -0
  151. package/stack-template/app/shell/src/pages/LoginPage.tsx +217 -0
  152. package/stack-template/app/shell/src/remote-urls.ts +18 -0
  153. package/stack-template/app/shell/tests/a11y.test.tsx +53 -0
  154. package/stack-template/app/shell/tests/api-timeout.test.ts +43 -0
  155. package/stack-template/app/shell/tests/integration.test.tsx +93 -0
  156. package/stack-template/app/shell/tests/login.test.tsx +227 -0
  157. package/stack-template/app/shell/tests/mf-retry.test.ts +76 -0
  158. package/stack-template/app/shell/tests/refresh-client.test.ts +301 -0
  159. package/stack-template/app/shell/tests/remote-slot.test.tsx +109 -0
  160. package/stack-template/app/shell/tests/remote-urls.test.ts +26 -0
  161. package/stack-template/app/shell/tests/setup.ts +15 -0
  162. package/stack-template/app/shell/tests/shell-chrome.test.tsx +126 -0
  163. package/stack-template/app/shell/tsconfig.json +26 -0
  164. package/stack-template/app/shell/vitest.config.ts +42 -0
  165. package/stack-template/app/spike/README.md +35 -0
  166. package/stack-template/app/spike/host/index.html +11 -0
  167. package/stack-template/app/spike/host/package.json +17 -0
  168. package/stack-template/app/spike/host/rspack.config.mjs +34 -0
  169. package/stack-template/app/spike/host/src/bootstrap.jsx +26 -0
  170. package/stack-template/app/spike/host/src/index.jsx +3 -0
  171. package/stack-template/app/spike/remote/package.json +17 -0
  172. package/stack-template/app/spike/remote/rspack.config.mjs +36 -0
  173. package/stack-template/app/spike/remote/src/Hello.jsx +7 -0
  174. package/stack-template/app/spike/remote/src/index.js +2 -0
  175. package/stack-template/app/spike/serve.mjs +31 -0
  176. package/stack-template/app/starter-templates/template-feats/extras/carousel/src/DemoCarousel.tsx +99 -0
  177. package/stack-template/app/starter-templates/template-feats/extras/chart/src/DemoChart.tsx +84 -0
  178. package/stack-template/app/starter-templates/template-feats/extras/editor/src/DemoEditor.tsx +110 -0
  179. package/stack-template/app/starter-templates/template-feats/extras/schedule/src/DemoSchedule.tsx +81 -0
  180. package/stack-template/app/starter-templates/template-feats/router/src/App.tsx +332 -0
  181. package/stack-template/app/starter-templates/template-feats/router/src/main.tsx +14 -0
  182. package/stack-template/app/starter-templates/vite-js/README.md +72 -0
  183. package/stack-template/app/starter-templates/vite-js/index.html +12 -0
  184. package/stack-template/app/starter-templates/vite-js/jsconfig.json +10 -0
  185. package/stack-template/app/starter-templates/vite-js/package.json +22 -0
  186. package/stack-template/app/starter-templates/vite-js/src/App.jsx +158 -0
  187. package/stack-template/app/starter-templates/vite-js/src/main.jsx +10 -0
  188. package/stack-template/app/starter-templates/vite-js/src/styles.css +15 -0
  189. package/stack-template/app/starter-templates/vite-js/src/theme.js +21 -0
  190. package/stack-template/app/starter-templates/vite-js/vite.config.mjs +8 -0
  191. package/stack-template/app/starter-templates/vite-ts/README.md +53 -0
  192. package/stack-template/app/starter-templates/vite-ts/index.html +12 -0
  193. package/stack-template/app/starter-templates/vite-ts/package.json +29 -0
  194. package/stack-template/app/starter-templates/vite-ts/src/App.tsx +181 -0
  195. package/stack-template/app/starter-templates/vite-ts/src/main.tsx +12 -0
  196. package/stack-template/app/starter-templates/vite-ts/src/styles.css +21 -0
  197. package/stack-template/app/starter-templates/vite-ts/src/theme.ts +16 -0
  198. package/stack-template/app/starter-templates/vite-ts/tsconfig.json +25 -0
  199. package/stack-template/app/starter-templates/vite-ts/tsconfig.node.json +11 -0
  200. package/stack-template/app/starter-templates/vite-ts/vite.config.ts +10 -0
  201. package/stack-template/app/ui-kit/.storybook/main.ts +29 -0
  202. package/stack-template/app/ui-kit/.storybook/manager-head.html +97 -0
  203. package/stack-template/app/ui-kit/.storybook/manager.ts +138 -0
  204. package/stack-template/app/ui-kit/.storybook/preview-head.html +57 -0
  205. package/stack-template/app/ui-kit/.storybook/preview.ts +62 -0
  206. package/stack-template/app/ui-kit/.storybook/tailwind-preview.css +3 -0
  207. package/stack-template/app/ui-kit/.storybook/test-runner.config.ts +20 -0
  208. package/stack-template/app/ui-kit/CHANGELOG.md +137 -0
  209. package/stack-template/app/ui-kit/LICENSE +21 -0
  210. package/stack-template/app/ui-kit/MIGRATION.md +84 -0
  211. package/stack-template/app/ui-kit/README.md +173 -0
  212. package/stack-template/app/ui-kit/RELEASE.md +77 -0
  213. package/stack-template/app/ui-kit/USAGE.md +380 -0
  214. package/stack-template/app/ui-kit/eslint.config.js +47 -0
  215. package/stack-template/app/ui-kit/package.json +166 -0
  216. package/stack-template/app/ui-kit/scripts/publish-github.sh +39 -0
  217. package/stack-template/app/ui-kit/scripts/publish-npm.sh +76 -0
  218. package/stack-template/app/ui-kit/scripts/stamp-build.cjs +13 -0
  219. package/stack-template/app/ui-kit/src/KitchenSink.stories.tsx +576 -0
  220. package/stack-template/app/ui-kit/src/Tokens.stories.tsx +193 -0
  221. package/stack-template/app/ui-kit/src/entries/carousel.ts +7 -0
  222. package/stack-template/app/ui-kit/src/entries/chart.ts +4 -0
  223. package/stack-template/app/ui-kit/src/entries/editor.ts +4 -0
  224. package/stack-template/app/ui-kit/src/entries/experience3d.ts +5 -0
  225. package/stack-template/app/ui-kit/src/entries/schedule.ts +5 -0
  226. package/stack-template/app/ui-kit/src/env.d.ts +3 -0
  227. package/stack-template/app/ui-kit/src/hooks/form.stories.tsx +80 -0
  228. package/stack-template/app/ui-kit/src/hooks/hooks-new.stories.tsx +392 -0
  229. package/stack-template/app/ui-kit/src/hooks/hooks.stories.tsx +167 -0
  230. package/stack-template/app/ui-kit/src/hooks/useClickAway.test.tsx +63 -0
  231. package/stack-template/app/ui-kit/src/hooks/useClickAway.ts +30 -0
  232. package/stack-template/app/ui-kit/src/hooks/useControllableState.test.ts +36 -0
  233. package/stack-template/app/ui-kit/src/hooks/useControllableState.ts +41 -0
  234. package/stack-template/app/ui-kit/src/hooks/useCopyToClipboard.test.ts +89 -0
  235. package/stack-template/app/ui-kit/src/hooks/useCopyToClipboard.ts +20 -0
  236. package/stack-template/app/ui-kit/src/hooks/useCountdown.test.ts +88 -0
  237. package/stack-template/app/ui-kit/src/hooks/useCountdown.ts +38 -0
  238. package/stack-template/app/ui-kit/src/hooks/useDebounce.test.ts +71 -0
  239. package/stack-template/app/ui-kit/src/hooks/useDebounce.ts +14 -0
  240. package/stack-template/app/ui-kit/src/hooks/useDefault.test.ts +37 -0
  241. package/stack-template/app/ui-kit/src/hooks/useDefault.ts +15 -0
  242. package/stack-template/app/ui-kit/src/hooks/useEventListener.test.ts +47 -0
  243. package/stack-template/app/ui-kit/src/hooks/useEventListener.ts +28 -0
  244. package/stack-template/app/ui-kit/src/hooks/useFieldArray.test.tsx +160 -0
  245. package/stack-template/app/ui-kit/src/hooks/useFieldArray.ts +85 -0
  246. package/stack-template/app/ui-kit/src/hooks/useFocusTrap.ts +67 -0
  247. package/stack-template/app/ui-kit/src/hooks/useForm.test.tsx +192 -0
  248. package/stack-template/app/ui-kit/src/hooks/useForm.ts +119 -0
  249. package/stack-template/app/ui-kit/src/hooks/useFullscreen.test.tsx +71 -0
  250. package/stack-template/app/ui-kit/src/hooks/useFullscreen.ts +68 -0
  251. package/stack-template/app/ui-kit/src/hooks/useHover.test.tsx +30 -0
  252. package/stack-template/app/ui-kit/src/hooks/useHover.ts +23 -0
  253. package/stack-template/app/ui-kit/src/hooks/useInView.test.tsx +70 -0
  254. package/stack-template/app/ui-kit/src/hooks/useInView.ts +55 -0
  255. package/stack-template/app/ui-kit/src/hooks/useInfiniteScroll.test.tsx +72 -0
  256. package/stack-template/app/ui-kit/src/hooks/useInfiniteScroll.ts +45 -0
  257. package/stack-template/app/ui-kit/src/hooks/useIsFirstRender.test.ts +30 -0
  258. package/stack-template/app/ui-kit/src/hooks/useIsFirstRender.ts +14 -0
  259. package/stack-template/app/ui-kit/src/hooks/useKeyPress.test.ts +45 -0
  260. package/stack-template/app/ui-kit/src/hooks/useKeyPress.ts +31 -0
  261. package/stack-template/app/ui-kit/src/hooks/useLocalStorage.test.ts +102 -0
  262. package/stack-template/app/ui-kit/src/hooks/useLocalStorage.ts +34 -0
  263. package/stack-template/app/ui-kit/src/hooks/useLockBodyScroll.test.ts +42 -0
  264. package/stack-template/app/ui-kit/src/hooks/useLockBodyScroll.ts +13 -0
  265. package/stack-template/app/ui-kit/src/hooks/useMeasure.test.tsx +57 -0
  266. package/stack-template/app/ui-kit/src/hooks/useMeasure.ts +32 -0
  267. package/stack-template/app/ui-kit/src/hooks/useMediaQuery.test.ts +73 -0
  268. package/stack-template/app/ui-kit/src/hooks/useMediaQuery.ts +20 -0
  269. package/stack-template/app/ui-kit/src/hooks/useMountEffect.test.ts +22 -0
  270. package/stack-template/app/ui-kit/src/hooks/useMountEffect.ts +10 -0
  271. package/stack-template/app/ui-kit/src/hooks/useOnlineStatus.test.ts +36 -0
  272. package/stack-template/app/ui-kit/src/hooks/useOnlineStatus.ts +21 -0
  273. package/stack-template/app/ui-kit/src/hooks/usePrevious.test.ts +35 -0
  274. package/stack-template/app/ui-kit/src/hooks/usePrevious.ts +13 -0
  275. package/stack-template/app/ui-kit/src/hooks/useScrollProgress.test.ts +59 -0
  276. package/stack-template/app/ui-kit/src/hooks/useScrollProgress.ts +31 -0
  277. package/stack-template/app/ui-kit/src/hooks/useSessionStorage.test.ts +80 -0
  278. package/stack-template/app/ui-kit/src/hooks/useSessionStorage.ts +34 -0
  279. package/stack-template/app/ui-kit/src/hooks/useThrottle.test.ts +61 -0
  280. package/stack-template/app/ui-kit/src/hooks/useThrottle.ts +30 -0
  281. package/stack-template/app/ui-kit/src/hooks/useTimeout.test.ts +95 -0
  282. package/stack-template/app/ui-kit/src/hooks/useTimeout.ts +38 -0
  283. package/stack-template/app/ui-kit/src/hooks/useTitle.test.ts +34 -0
  284. package/stack-template/app/ui-kit/src/hooks/useTitle.ts +24 -0
  285. package/stack-template/app/ui-kit/src/hooks/useToggle.test.ts +46 -0
  286. package/stack-template/app/ui-kit/src/hooks/useToggle.ts +16 -0
  287. package/stack-template/app/ui-kit/src/hooks/useUpdateEffect.test.ts +25 -0
  288. package/stack-template/app/ui-kit/src/hooks/useUpdateEffect.ts +18 -0
  289. package/stack-template/app/ui-kit/src/hooks/useWindowSize.test.ts +33 -0
  290. package/stack-template/app/ui-kit/src/hooks/useWindowSize.ts +23 -0
  291. package/stack-template/app/ui-kit/src/index.ts +218 -0
  292. package/stack-template/app/ui-kit/src/intro-showcase.stories.tsx +272 -0
  293. package/stack-template/app/ui-kit/src/intro.docs.mdx +247 -0
  294. package/stack-template/app/ui-kit/src/motion/motion-showcase.stories.tsx +234 -0
  295. package/stack-template/app/ui-kit/src/motion/motion.md +38 -0
  296. package/stack-template/app/ui-kit/src/provider/index.tsx +77 -0
  297. package/stack-template/app/ui-kit/src/provider/provider.stories.tsx +87 -0
  298. package/stack-template/app/ui-kit/src/provider/provider.test.tsx +121 -0
  299. package/stack-template/app/ui-kit/src/styles/base.css +171 -0
  300. package/stack-template/app/ui-kit/src/styles/dark-theme.test.ts +21 -0
  301. package/stack-template/app/ui-kit/src/styles/tailwind.css +220 -0
  302. package/stack-template/app/ui-kit/src/styles/themes/dark.css +71 -0
  303. package/stack-template/app/ui-kit/src/styles/tokens.css +133 -0
  304. package/stack-template/app/ui-kit/src/styles/ui-kit.css +10 -0
  305. package/stack-template/app/ui-kit/src/templates/auth.stories.tsx +425 -0
  306. package/stack-template/app/ui-kit/src/templates/crud.stories.tsx +416 -0
  307. package/stack-template/app/ui-kit/src/templates/dashboard.stories.tsx +504 -0
  308. package/stack-template/app/ui-kit/src/templates/experience/chapters/ch1-deep-focus.tsx +96 -0
  309. package/stack-template/app/ui-kit/src/templates/experience/chapters/ch2-living-docs.tsx +134 -0
  310. package/stack-template/app/ui-kit/src/templates/experience/chapters/ch3-team-velocity.tsx +148 -0
  311. package/stack-template/app/ui-kit/src/templates/experience/chapters/ch4-ship-your-app.tsx +100 -0
  312. package/stack-template/app/ui-kit/src/templates/experience/chapters/ch5-future.tsx +67 -0
  313. package/stack-template/app/ui-kit/src/templates/experience/chapters/hero.tsx +434 -0
  314. package/stack-template/app/ui-kit/src/templates/experience/chapters/nav-footer.tsx +85 -0
  315. package/stack-template/app/ui-kit/src/templates/experience/hero.stories.tsx +27 -0
  316. package/stack-template/app/ui-kit/src/templates/experience/hero.test.tsx +108 -0
  317. package/stack-template/app/ui-kit/src/templates/experience/index.stories.tsx +51 -0
  318. package/stack-template/app/ui-kit/src/templates/experience/lib/ChapterShell.tsx +84 -0
  319. package/stack-template/app/ui-kit/src/templates/experience/lib/SideNav.tsx +173 -0
  320. package/stack-template/app/ui-kit/src/templates/experience/lib/chapter-shell.test.tsx +266 -0
  321. package/stack-template/app/ui-kit/src/templates/experience/lib/scroll-mood.tsx +143 -0
  322. package/stack-template/app/ui-kit/src/templates/experience/lib/starfield.test.tsx +31 -0
  323. package/stack-template/app/ui-kit/src/templates/experience/lib/starfield.tsx +190 -0
  324. package/stack-template/app/ui-kit/src/templates/experience/mood-engine.stories.tsx +114 -0
  325. package/stack-template/app/ui-kit/src/templates/experience/shell-nav.stories.tsx +113 -0
  326. package/stack-template/app/ui-kit/src/templates/kanban-project.stories.tsx +352 -0
  327. package/stack-template/app/ui-kit/src/templates/landing.stories.tsx +380 -0
  328. package/stack-template/app/ui-kit/src/templates/parallax-landing.stories.tsx +633 -0
  329. package/stack-template/app/ui-kit/src/templates/settings.stories.tsx +474 -0
  330. package/stack-template/app/ui-kit/src/ui/accordion/accordion.stories.tsx +91 -0
  331. package/stack-template/app/ui-kit/src/ui/accordion/accordion.test.tsx +99 -0
  332. package/stack-template/app/ui-kit/src/ui/accordion/index.tsx +107 -0
  333. package/stack-template/app/ui-kit/src/ui/affix/affix.stories.tsx +104 -0
  334. package/stack-template/app/ui-kit/src/ui/affix/affix.test.tsx +138 -0
  335. package/stack-template/app/ui-kit/src/ui/affix/index.tsx +89 -0
  336. package/stack-template/app/ui-kit/src/ui/alert/alert.stories.tsx +149 -0
  337. package/stack-template/app/ui-kit/src/ui/alert/alert.test.tsx +85 -0
  338. package/stack-template/app/ui-kit/src/ui/alert/index.tsx +118 -0
  339. package/stack-template/app/ui-kit/src/ui/anchor/anchor.stories.tsx +96 -0
  340. package/stack-template/app/ui-kit/src/ui/anchor/anchor.test.tsx +191 -0
  341. package/stack-template/app/ui-kit/src/ui/anchor/index.tsx +144 -0
  342. package/stack-template/app/ui-kit/src/ui/auto-complete/auto-complete.stories.tsx +67 -0
  343. package/stack-template/app/ui-kit/src/ui/auto-complete/auto-complete.test.tsx +94 -0
  344. package/stack-template/app/ui-kit/src/ui/auto-complete/index.tsx +54 -0
  345. package/stack-template/app/ui-kit/src/ui/avatar/avatar.stories.tsx +132 -0
  346. package/stack-template/app/ui-kit/src/ui/avatar/avatar.test.tsx +65 -0
  347. package/stack-template/app/ui-kit/src/ui/avatar/index.tsx +48 -0
  348. package/stack-template/app/ui-kit/src/ui/avatar-group/avatar-group.stories.tsx +113 -0
  349. package/stack-template/app/ui-kit/src/ui/avatar-group/avatar-group.test.tsx +71 -0
  350. package/stack-template/app/ui-kit/src/ui/avatar-group/index.tsx +66 -0
  351. package/stack-template/app/ui-kit/src/ui/backdrop/backdrop.stories.tsx +66 -0
  352. package/stack-template/app/ui-kit/src/ui/backdrop/backdrop.test.tsx +37 -0
  353. package/stack-template/app/ui-kit/src/ui/backdrop/index.tsx +29 -0
  354. package/stack-template/app/ui-kit/src/ui/badge/badge.stories.tsx +105 -0
  355. package/stack-template/app/ui-kit/src/ui/badge/badge.test.tsx +115 -0
  356. package/stack-template/app/ui-kit/src/ui/badge/index.tsx +154 -0
  357. package/stack-template/app/ui-kit/src/ui/blockui/blockui.stories.tsx +34 -0
  358. package/stack-template/app/ui-kit/src/ui/blockui/blockui.test.tsx +29 -0
  359. package/stack-template/app/ui-kit/src/ui/blockui/index.tsx +25 -0
  360. package/stack-template/app/ui-kit/src/ui/bottom-navigation/bottom-navigation.stories.tsx +70 -0
  361. package/stack-template/app/ui-kit/src/ui/bottom-navigation/bottom-navigation.test.tsx +68 -0
  362. package/stack-template/app/ui-kit/src/ui/bottom-navigation/index.tsx +82 -0
  363. package/stack-template/app/ui-kit/src/ui/branch-fill.test.tsx +245 -0
  364. package/stack-template/app/ui-kit/src/ui/breadcrumb/breadcrumb.stories.tsx +103 -0
  365. package/stack-template/app/ui-kit/src/ui/breadcrumb/breadcrumb.test.tsx +49 -0
  366. package/stack-template/app/ui-kit/src/ui/breadcrumb/index.tsx +37 -0
  367. package/stack-template/app/ui-kit/src/ui/busy-box/busy-box.stories.tsx +30 -0
  368. package/stack-template/app/ui-kit/src/ui/busy-box/busy-box.test.tsx +29 -0
  369. package/stack-template/app/ui-kit/src/ui/busy-box/index.tsx +25 -0
  370. package/stack-template/app/ui-kit/src/ui/button/button.stories.tsx +121 -0
  371. package/stack-template/app/ui-kit/src/ui/button/button.test.tsx +207 -0
  372. package/stack-template/app/ui-kit/src/ui/button/index.tsx +128 -0
  373. package/stack-template/app/ui-kit/src/ui/calendar/calendar.stories.tsx +100 -0
  374. package/stack-template/app/ui-kit/src/ui/calendar/calendar.test.tsx +92 -0
  375. package/stack-template/app/ui-kit/src/ui/calendar/index.tsx +163 -0
  376. package/stack-template/app/ui-kit/src/ui/card/card.stories.tsx +203 -0
  377. package/stack-template/app/ui-kit/src/ui/card/card.test.tsx +135 -0
  378. package/stack-template/app/ui-kit/src/ui/card/index.tsx +84 -0
  379. package/stack-template/app/ui-kit/src/ui/carousel/carousel.stories.tsx +533 -0
  380. package/stack-template/app/ui-kit/src/ui/carousel/carousel.test.tsx +148 -0
  381. package/stack-template/app/ui-kit/src/ui/carousel/index.tsx +195 -0
  382. package/stack-template/app/ui-kit/src/ui/cascade-select/cascade-select.stories.tsx +126 -0
  383. package/stack-template/app/ui-kit/src/ui/cascade-select/cascade-select.test.tsx +132 -0
  384. package/stack-template/app/ui-kit/src/ui/cascade-select/index.tsx +87 -0
  385. package/stack-template/app/ui-kit/src/ui/chart/chart-theme.test.tsx +79 -0
  386. package/stack-template/app/ui-kit/src/ui/chart/chart.stories.tsx +278 -0
  387. package/stack-template/app/ui-kit/src/ui/chart/chart.test.tsx +103 -0
  388. package/stack-template/app/ui-kit/src/ui/chart/index.tsx +172 -0
  389. package/stack-template/app/ui-kit/src/ui/checkbox/checkbox.stories.tsx +67 -0
  390. package/stack-template/app/ui-kit/src/ui/checkbox/checkbox.test.tsx +99 -0
  391. package/stack-template/app/ui-kit/src/ui/checkbox/index.tsx +52 -0
  392. package/stack-template/app/ui-kit/src/ui/chips/chips.stories.tsx +53 -0
  393. package/stack-template/app/ui-kit/src/ui/chips/chips.test.tsx +86 -0
  394. package/stack-template/app/ui-kit/src/ui/chips/index.tsx +44 -0
  395. package/stack-template/app/ui-kit/src/ui/collapse/collapse.stories.tsx +93 -0
  396. package/stack-template/app/ui-kit/src/ui/collapse/collapse.test.tsx +128 -0
  397. package/stack-template/app/ui-kit/src/ui/collapse/index.tsx +75 -0
  398. package/stack-template/app/ui-kit/src/ui/color-picker/color-picker.stories.tsx +48 -0
  399. package/stack-template/app/ui-kit/src/ui/color-picker/color-picker.test.tsx +68 -0
  400. package/stack-template/app/ui-kit/src/ui/color-picker/index.tsx +38 -0
  401. package/stack-template/app/ui-kit/src/ui/context-menu/context-menu.stories.tsx +73 -0
  402. package/stack-template/app/ui-kit/src/ui/context-menu/context-menu.test.tsx +93 -0
  403. package/stack-template/app/ui-kit/src/ui/context-menu/index.tsx +79 -0
  404. package/stack-template/app/ui-kit/src/ui/count-up/count-up.stories.tsx +80 -0
  405. package/stack-template/app/ui-kit/src/ui/count-up/count-up.test.tsx +121 -0
  406. package/stack-template/app/ui-kit/src/ui/count-up/index.tsx +70 -0
  407. package/stack-template/app/ui-kit/src/ui/date-picker/date-picker.stories.tsx +154 -0
  408. package/stack-template/app/ui-kit/src/ui/date-picker/date-picker.test.tsx +221 -0
  409. package/stack-template/app/ui-kit/src/ui/date-picker/index.tsx +287 -0
  410. package/stack-template/app/ui-kit/src/ui/date-picker/locale-constants.ts +90 -0
  411. package/stack-template/app/ui-kit/src/ui/date-picker/locale.tsx +15 -0
  412. package/stack-template/app/ui-kit/src/ui/deferred-content/deferred-content.stories.tsx +62 -0
  413. package/stack-template/app/ui-kit/src/ui/deferred-content/deferred-content.test.tsx +94 -0
  414. package/stack-template/app/ui-kit/src/ui/deferred-content/index.tsx +61 -0
  415. package/stack-template/app/ui-kit/src/ui/descriptions/descriptions.stories.tsx +114 -0
  416. package/stack-template/app/ui-kit/src/ui/descriptions/descriptions.test.tsx +75 -0
  417. package/stack-template/app/ui-kit/src/ui/descriptions/index.tsx +48 -0
  418. package/stack-template/app/ui-kit/src/ui/divider/divider.stories.tsx +66 -0
  419. package/stack-template/app/ui-kit/src/ui/divider/divider.test.tsx +83 -0
  420. package/stack-template/app/ui-kit/src/ui/divider/index.tsx +65 -0
  421. package/stack-template/app/ui-kit/src/ui/drag-drop/drag-drop.stories.tsx +145 -0
  422. package/stack-template/app/ui-kit/src/ui/drag-drop/drag-drop.test.tsx +352 -0
  423. package/stack-template/app/ui-kit/src/ui/drag-drop/index.tsx +456 -0
  424. package/stack-template/app/ui-kit/src/ui/drawer/drawer.stories.tsx +108 -0
  425. package/stack-template/app/ui-kit/src/ui/drawer/drawer.test.tsx +132 -0
  426. package/stack-template/app/ui-kit/src/ui/drawer/index.tsx +113 -0
  427. package/stack-template/app/ui-kit/src/ui/dropdown/dropdown.stories.tsx +61 -0
  428. package/stack-template/app/ui-kit/src/ui/dropdown/dropdown.test.tsx +101 -0
  429. package/stack-template/app/ui-kit/src/ui/dropdown/index.tsx +162 -0
  430. package/stack-template/app/ui-kit/src/ui/editor/EditorInner.tsx +93 -0
  431. package/stack-template/app/ui-kit/src/ui/editor/editor.stories.tsx +37 -0
  432. package/stack-template/app/ui-kit/src/ui/editor/editor.test.tsx +84 -0
  433. package/stack-template/app/ui-kit/src/ui/editor/index.tsx +58 -0
  434. package/stack-template/app/ui-kit/src/ui/empty-state/empty-state.stories.tsx +24 -0
  435. package/stack-template/app/ui-kit/src/ui/empty-state/empty-state.test.tsx +48 -0
  436. package/stack-template/app/ui-kit/src/ui/empty-state/index.tsx +22 -0
  437. package/stack-template/app/ui-kit/src/ui/experience3d/experience3d.stories.tsx +66 -0
  438. package/stack-template/app/ui-kit/src/ui/experience3d/experience3d.test.tsx +50 -0
  439. package/stack-template/app/ui-kit/src/ui/experience3d/index.tsx +457 -0
  440. package/stack-template/app/ui-kit/src/ui/field/field-array.stories.tsx +214 -0
  441. package/stack-template/app/ui-kit/src/ui/field/field.stories.tsx +158 -0
  442. package/stack-template/app/ui-kit/src/ui/field/field.test.tsx +68 -0
  443. package/stack-template/app/ui-kit/src/ui/field/index.tsx +48 -0
  444. package/stack-template/app/ui-kit/src/ui/fieldset/fieldset.stories.tsx +49 -0
  445. package/stack-template/app/ui-kit/src/ui/fieldset/fieldset.test.tsx +88 -0
  446. package/stack-template/app/ui-kit/src/ui/fieldset/index.tsx +62 -0
  447. package/stack-template/app/ui-kit/src/ui/flex/flex.stories.tsx +96 -0
  448. package/stack-template/app/ui-kit/src/ui/flex/flex.test.tsx +79 -0
  449. package/stack-template/app/ui-kit/src/ui/flex/index.tsx +45 -0
  450. package/stack-template/app/ui-kit/src/ui/float-button/float-button.stories.tsx +82 -0
  451. package/stack-template/app/ui-kit/src/ui/float-button/float-button.test.tsx +107 -0
  452. package/stack-template/app/ui-kit/src/ui/float-button/index.tsx +124 -0
  453. package/stack-template/app/ui-kit/src/ui/galleria/galleria.stories.tsx +78 -0
  454. package/stack-template/app/ui-kit/src/ui/galleria/galleria.test.tsx +67 -0
  455. package/stack-template/app/ui-kit/src/ui/galleria/index.tsx +47 -0
  456. package/stack-template/app/ui-kit/src/ui/grid/grid.stories.tsx +179 -0
  457. package/stack-template/app/ui-kit/src/ui/grid/grid.test.tsx +286 -0
  458. package/stack-template/app/ui-kit/src/ui/grid/index.tsx +104 -0
  459. package/stack-template/app/ui-kit/src/ui/icons/icons.stories.tsx +52 -0
  460. package/stack-template/app/ui-kit/src/ui/icons/icons.test.tsx +60 -0
  461. package/stack-template/app/ui-kit/src/ui/icons/index.tsx +294 -0
  462. package/stack-template/app/ui-kit/src/ui/image/image.stories.tsx +231 -0
  463. package/stack-template/app/ui-kit/src/ui/image/image.test.tsx +79 -0
  464. package/stack-template/app/ui-kit/src/ui/image/index.tsx +76 -0
  465. package/stack-template/app/ui-kit/src/ui/inplace/index.tsx +33 -0
  466. package/stack-template/app/ui-kit/src/ui/inplace/inplace.stories.tsx +75 -0
  467. package/stack-template/app/ui-kit/src/ui/inplace/inplace.test.tsx +58 -0
  468. package/stack-template/app/ui-kit/src/ui/input/index.tsx +133 -0
  469. package/stack-template/app/ui-kit/src/ui/input/input-search.stories.tsx +112 -0
  470. package/stack-template/app/ui-kit/src/ui/input/input-search.test.tsx +116 -0
  471. package/stack-template/app/ui-kit/src/ui/input/input-search.tsx +116 -0
  472. package/stack-template/app/ui-kit/src/ui/input/input.stories.tsx +176 -0
  473. package/stack-template/app/ui-kit/src/ui/input/input.test.tsx +106 -0
  474. package/stack-template/app/ui-kit/src/ui/input-mask/index.tsx +39 -0
  475. package/stack-template/app/ui-kit/src/ui/input-mask/input-mask.stories.tsx +46 -0
  476. package/stack-template/app/ui-kit/src/ui/input-mask/input-mask.test.tsx +57 -0
  477. package/stack-template/app/ui-kit/src/ui/input-number/index.tsx +125 -0
  478. package/stack-template/app/ui-kit/src/ui/input-number/input-number.stories.tsx +190 -0
  479. package/stack-template/app/ui-kit/src/ui/input-number/input-number.test.tsx +157 -0
  480. package/stack-template/app/ui-kit/src/ui/input-otp/index.tsx +57 -0
  481. package/stack-template/app/ui-kit/src/ui/input-otp/input-otp.stories.tsx +90 -0
  482. package/stack-template/app/ui-kit/src/ui/input-otp/input-otp.test.tsx +66 -0
  483. package/stack-template/app/ui-kit/src/ui/kanban/index.tsx +277 -0
  484. package/stack-template/app/ui-kit/src/ui/kanban/kanban.stories.tsx +219 -0
  485. package/stack-template/app/ui-kit/src/ui/kanban/kanban.test.tsx +234 -0
  486. package/stack-template/app/ui-kit/src/ui/knob/index.tsx +58 -0
  487. package/stack-template/app/ui-kit/src/ui/knob/knob.stories.tsx +49 -0
  488. package/stack-template/app/ui-kit/src/ui/knob/knob.test.tsx +42 -0
  489. package/stack-template/app/ui-kit/src/ui/layout/index.tsx +145 -0
  490. package/stack-template/app/ui-kit/src/ui/layout/layout.stories.tsx +158 -0
  491. package/stack-template/app/ui-kit/src/ui/layout/layout.test.tsx +154 -0
  492. package/stack-template/app/ui-kit/src/ui/link/index.tsx +61 -0
  493. package/stack-template/app/ui-kit/src/ui/link/link.stories.tsx +68 -0
  494. package/stack-template/app/ui-kit/src/ui/link/link.test.tsx +69 -0
  495. package/stack-template/app/ui-kit/src/ui/list/index.tsx +135 -0
  496. package/stack-template/app/ui-kit/src/ui/list/list.stories.tsx +194 -0
  497. package/stack-template/app/ui-kit/src/ui/list/list.test.tsx +164 -0
  498. package/stack-template/app/ui-kit/src/ui/listbox/index.tsx +27 -0
  499. package/stack-template/app/ui-kit/src/ui/listbox/listbox.stories.tsx +57 -0
  500. package/stack-template/app/ui-kit/src/ui/listbox/listbox.test.tsx +49 -0
  501. package/stack-template/app/ui-kit/src/ui/mega-menu/index.tsx +142 -0
  502. package/stack-template/app/ui-kit/src/ui/mega-menu/mega-menu.stories.tsx +137 -0
  503. package/stack-template/app/ui-kit/src/ui/mega-menu/mega-menu.test.tsx +130 -0
  504. package/stack-template/app/ui-kit/src/ui/mention/index.tsx +76 -0
  505. package/stack-template/app/ui-kit/src/ui/mention/mention.stories.tsx +44 -0
  506. package/stack-template/app/ui-kit/src/ui/mention/mention.test.tsx +87 -0
  507. package/stack-template/app/ui-kit/src/ui/menu/index.tsx +256 -0
  508. package/stack-template/app/ui-kit/src/ui/menu/menu.stories.tsx +124 -0
  509. package/stack-template/app/ui-kit/src/ui/menu/menu.test.tsx +251 -0
  510. package/stack-template/app/ui-kit/src/ui/menubar/index.tsx +42 -0
  511. package/stack-template/app/ui-kit/src/ui/menubar/menubar.stories.tsx +66 -0
  512. package/stack-template/app/ui-kit/src/ui/menubar/menubar.test.tsx +65 -0
  513. package/stack-template/app/ui-kit/src/ui/message/index.tsx +123 -0
  514. package/stack-template/app/ui-kit/src/ui/message/message.stories.tsx +104 -0
  515. package/stack-template/app/ui-kit/src/ui/message/message.test.tsx +109 -0
  516. package/stack-template/app/ui-kit/src/ui/modal/index.tsx +142 -0
  517. package/stack-template/app/ui-kit/src/ui/modal/modal.stories.tsx +128 -0
  518. package/stack-template/app/ui-kit/src/ui/modal/modal.test.tsx +166 -0
  519. package/stack-template/app/ui-kit/src/ui/notification/index.tsx +142 -0
  520. package/stack-template/app/ui-kit/src/ui/notification/notification.stories.tsx +155 -0
  521. package/stack-template/app/ui-kit/src/ui/notification/notification.test.tsx +83 -0
  522. package/stack-template/app/ui-kit/src/ui/order-list/index.tsx +38 -0
  523. package/stack-template/app/ui-kit/src/ui/order-list/order-list.stories.tsx +38 -0
  524. package/stack-template/app/ui-kit/src/ui/order-list/order-list.test.tsx +54 -0
  525. package/stack-template/app/ui-kit/src/ui/org-chart/index.tsx +138 -0
  526. package/stack-template/app/ui-kit/src/ui/org-chart/org-chart.stories.tsx +76 -0
  527. package/stack-template/app/ui-kit/src/ui/org-chart/org-chart.test.tsx +98 -0
  528. package/stack-template/app/ui-kit/src/ui/pagination/index.tsx +102 -0
  529. package/stack-template/app/ui-kit/src/ui/pagination/pagination.stories.tsx +103 -0
  530. package/stack-template/app/ui-kit/src/ui/pagination/pagination.test.tsx +112 -0
  531. package/stack-template/app/ui-kit/src/ui/panel-menu/index.tsx +59 -0
  532. package/stack-template/app/ui-kit/src/ui/panel-menu/panel-menu.stories.tsx +96 -0
  533. package/stack-template/app/ui-kit/src/ui/panel-menu/panel-menu.test.tsx +64 -0
  534. package/stack-template/app/ui-kit/src/ui/parallax/index.tsx +62 -0
  535. package/stack-template/app/ui-kit/src/ui/parallax/parallax.stories.tsx +115 -0
  536. package/stack-template/app/ui-kit/src/ui/parallax/parallax.test.tsx +148 -0
  537. package/stack-template/app/ui-kit/src/ui/password/index.tsx +67 -0
  538. package/stack-template/app/ui-kit/src/ui/password/password.stories.tsx +43 -0
  539. package/stack-template/app/ui-kit/src/ui/password/password.test.tsx +45 -0
  540. package/stack-template/app/ui-kit/src/ui/pick-list/index.tsx +103 -0
  541. package/stack-template/app/ui-kit/src/ui/pick-list/pick-list.stories.tsx +59 -0
  542. package/stack-template/app/ui-kit/src/ui/pick-list/pick-list.test.tsx +94 -0
  543. package/stack-template/app/ui-kit/src/ui/popconfirm/index.tsx +102 -0
  544. package/stack-template/app/ui-kit/src/ui/popconfirm/popconfirm.stories.tsx +73 -0
  545. package/stack-template/app/ui-kit/src/ui/popconfirm/popconfirm.test.tsx +127 -0
  546. package/stack-template/app/ui-kit/src/ui/popover/index.tsx +136 -0
  547. package/stack-template/app/ui-kit/src/ui/popover/popover.stories.tsx +114 -0
  548. package/stack-template/app/ui-kit/src/ui/popover/popover.test.tsx +172 -0
  549. package/stack-template/app/ui-kit/src/ui/progress/index.tsx +46 -0
  550. package/stack-template/app/ui-kit/src/ui/progress/progress.stories.tsx +57 -0
  551. package/stack-template/app/ui-kit/src/ui/progress/progress.test.tsx +90 -0
  552. package/stack-template/app/ui-kit/src/ui/qr-code/index.tsx +88 -0
  553. package/stack-template/app/ui-kit/src/ui/qr-code/qr-code.stories.tsx +109 -0
  554. package/stack-template/app/ui-kit/src/ui/qr-code/qr-code.test.tsx +155 -0
  555. package/stack-template/app/ui-kit/src/ui/qr-code/qrcode-core.ts +56 -0
  556. package/stack-template/app/ui-kit/src/ui/qr-code/qrcode-generator.vendor.ts +2300 -0
  557. package/stack-template/app/ui-kit/src/ui/radio/index.tsx +62 -0
  558. package/stack-template/app/ui-kit/src/ui/radio/radio.stories.tsx +94 -0
  559. package/stack-template/app/ui-kit/src/ui/radio/radio.test.tsx +83 -0
  560. package/stack-template/app/ui-kit/src/ui/rating/index.tsx +36 -0
  561. package/stack-template/app/ui-kit/src/ui/rating/rating.stories.tsx +42 -0
  562. package/stack-template/app/ui-kit/src/ui/rating/rating.test.tsx +45 -0
  563. package/stack-template/app/ui-kit/src/ui/result/index.tsx +72 -0
  564. package/stack-template/app/ui-kit/src/ui/result/result.stories.tsx +82 -0
  565. package/stack-template/app/ui-kit/src/ui/result/result.test.tsx +57 -0
  566. package/stack-template/app/ui-kit/src/ui/reveal/index.tsx +83 -0
  567. package/stack-template/app/ui-kit/src/ui/reveal/reveal.stories.tsx +91 -0
  568. package/stack-template/app/ui-kit/src/ui/reveal/reveal.test.tsx +148 -0
  569. package/stack-template/app/ui-kit/src/ui/schedule/index.tsx +104 -0
  570. package/stack-template/app/ui-kit/src/ui/schedule/schedule.fc.test.tsx +95 -0
  571. package/stack-template/app/ui-kit/src/ui/schedule/schedule.stories.tsx +61 -0
  572. package/stack-template/app/ui-kit/src/ui/schedule/schedule.test.tsx +41 -0
  573. package/stack-template/app/ui-kit/src/ui/scroll-page/index.tsx +46 -0
  574. package/stack-template/app/ui-kit/src/ui/scroll-page/scroll-page.stories.tsx +92 -0
  575. package/stack-template/app/ui-kit/src/ui/scroll-page/scroll-page.test.tsx +51 -0
  576. package/stack-template/app/ui-kit/src/ui/scroll-panel/index.tsx +16 -0
  577. package/stack-template/app/ui-kit/src/ui/scroll-panel/scroll-panel.stories.tsx +37 -0
  578. package/stack-template/app/ui-kit/src/ui/scroll-panel/scroll-panel.test.tsx +41 -0
  579. package/stack-template/app/ui-kit/src/ui/scrolltop/index.tsx +27 -0
  580. package/stack-template/app/ui-kit/src/ui/scrolltop/scrolltop.stories.tsx +41 -0
  581. package/stack-template/app/ui-kit/src/ui/scrolltop/scrolltop.test.tsx +37 -0
  582. package/stack-template/app/ui-kit/src/ui/segmented/index.tsx +47 -0
  583. package/stack-template/app/ui-kit/src/ui/segmented/segmented.stories.tsx +126 -0
  584. package/stack-template/app/ui-kit/src/ui/segmented/segmented.test.tsx +77 -0
  585. package/stack-template/app/ui-kit/src/ui/select/index.tsx +302 -0
  586. package/stack-template/app/ui-kit/src/ui/select/select.stories.tsx +268 -0
  587. package/stack-template/app/ui-kit/src/ui/select/select.test.tsx +226 -0
  588. package/stack-template/app/ui-kit/src/ui/sidebar/index.tsx +83 -0
  589. package/stack-template/app/ui-kit/src/ui/sidebar/sidebar.stories.tsx +71 -0
  590. package/stack-template/app/ui-kit/src/ui/sidebar/sidebar.test.tsx +101 -0
  591. package/stack-template/app/ui-kit/src/ui/skeleton/index.tsx +55 -0
  592. package/stack-template/app/ui-kit/src/ui/skeleton/skeleton.stories.tsx +110 -0
  593. package/stack-template/app/ui-kit/src/ui/skeleton/skeleton.test.tsx +74 -0
  594. package/stack-template/app/ui-kit/src/ui/slide-menu/index.tsx +103 -0
  595. package/stack-template/app/ui-kit/src/ui/slide-menu/slide-menu.stories.tsx +92 -0
  596. package/stack-template/app/ui-kit/src/ui/slide-menu/slide-menu.test.tsx +120 -0
  597. package/stack-template/app/ui-kit/src/ui/slider/index.tsx +90 -0
  598. package/stack-template/app/ui-kit/src/ui/slider/slider.stories.tsx +60 -0
  599. package/stack-template/app/ui-kit/src/ui/slider/slider.test.tsx +66 -0
  600. package/stack-template/app/ui-kit/src/ui/space/index.tsx +32 -0
  601. package/stack-template/app/ui-kit/src/ui/space/space.stories.tsx +66 -0
  602. package/stack-template/app/ui-kit/src/ui/space/space.test.tsx +56 -0
  603. package/stack-template/app/ui-kit/src/ui/speed-dial/index.tsx +32 -0
  604. package/stack-template/app/ui-kit/src/ui/speed-dial/speed-dial.stories.tsx +34 -0
  605. package/stack-template/app/ui-kit/src/ui/speed-dial/speed-dial.test.tsx +34 -0
  606. package/stack-template/app/ui-kit/src/ui/spinner/index.tsx +74 -0
  607. package/stack-template/app/ui-kit/src/ui/spinner/spinner.stories.tsx +64 -0
  608. package/stack-template/app/ui-kit/src/ui/spinner/spinner.test.tsx +66 -0
  609. package/stack-template/app/ui-kit/src/ui/split-button/index.tsx +155 -0
  610. package/stack-template/app/ui-kit/src/ui/split-button/split-button.stories.tsx +137 -0
  611. package/stack-template/app/ui-kit/src/ui/split-button/split-button.test.tsx +152 -0
  612. package/stack-template/app/ui-kit/src/ui/splitter/index.tsx +49 -0
  613. package/stack-template/app/ui-kit/src/ui/splitter/splitter.stories.tsx +24 -0
  614. package/stack-template/app/ui-kit/src/ui/splitter/splitter.test.tsx +21 -0
  615. package/stack-template/app/ui-kit/src/ui/statistic/index.tsx +28 -0
  616. package/stack-template/app/ui-kit/src/ui/statistic/statistic.stories.tsx +112 -0
  617. package/stack-template/app/ui-kit/src/ui/statistic/statistic.test.tsx +39 -0
  618. package/stack-template/app/ui-kit/src/ui/steps/index.tsx +50 -0
  619. package/stack-template/app/ui-kit/src/ui/steps/steps.stories.tsx +57 -0
  620. package/stack-template/app/ui-kit/src/ui/steps/steps.test.tsx +55 -0
  621. package/stack-template/app/ui-kit/src/ui/switch/index.tsx +87 -0
  622. package/stack-template/app/ui-kit/src/ui/switch/switch.stories.tsx +123 -0
  623. package/stack-template/app/ui-kit/src/ui/switch/switch.test.tsx +98 -0
  624. package/stack-template/app/ui-kit/src/ui/tab-menu/index.tsx +33 -0
  625. package/stack-template/app/ui-kit/src/ui/tab-menu/tab-menu.stories.tsx +49 -0
  626. package/stack-template/app/ui-kit/src/ui/tab-menu/tab-menu.test.tsx +50 -0
  627. package/stack-template/app/ui-kit/src/ui/table/index.tsx +690 -0
  628. package/stack-template/app/ui-kit/src/ui/table/table-advanced.stories.tsx +91 -0
  629. package/stack-template/app/ui-kit/src/ui/table/table-advanced.test.tsx +188 -0
  630. package/stack-template/app/ui-kit/src/ui/table/table-expandable.stories.tsx +91 -0
  631. package/stack-template/app/ui-kit/src/ui/table/table-expandable.test.tsx +143 -0
  632. package/stack-template/app/ui-kit/src/ui/table/table.stories.tsx +342 -0
  633. package/stack-template/app/ui-kit/src/ui/table/table.test.tsx +465 -0
  634. package/stack-template/app/ui-kit/src/ui/table/types.ts +173 -0
  635. package/stack-template/app/ui-kit/src/ui/tabs/index.tsx +118 -0
  636. package/stack-template/app/ui-kit/src/ui/tabs/tabs.stories.tsx +113 -0
  637. package/stack-template/app/ui-kit/src/ui/tabs/tabs.test.tsx +77 -0
  638. package/stack-template/app/ui-kit/src/ui/tag/index.tsx +68 -0
  639. package/stack-template/app/ui-kit/src/ui/tag/tag.stories.tsx +88 -0
  640. package/stack-template/app/ui-kit/src/ui/tag/tag.test.tsx +126 -0
  641. package/stack-template/app/ui-kit/src/ui/team/debt-board/debt-board.stories.tsx +52 -0
  642. package/stack-template/app/ui-kit/src/ui/team/debt-board/debt-board.test.tsx +72 -0
  643. package/stack-template/app/ui-kit/src/ui/team/debt-board/index.tsx +125 -0
  644. package/stack-template/app/ui-kit/src/ui/team/inbox-thread/inbox-thread.stories.tsx +70 -0
  645. package/stack-template/app/ui-kit/src/ui/team/inbox-thread/inbox-thread.test.tsx +56 -0
  646. package/stack-template/app/ui-kit/src/ui/team/inbox-thread/index.tsx +107 -0
  647. package/stack-template/app/ui-kit/src/ui/team/ping-feed/index.tsx +102 -0
  648. package/stack-template/app/ui-kit/src/ui/team/ping-feed/ping-feed.stories.tsx +57 -0
  649. package/stack-template/app/ui-kit/src/ui/team/ping-feed/ping-feed.test.tsx +60 -0
  650. package/stack-template/app/ui-kit/src/ui/team/stage-pipeline/index.tsx +60 -0
  651. package/stack-template/app/ui-kit/src/ui/team/stage-pipeline/stage-pipeline.stories.tsx +68 -0
  652. package/stack-template/app/ui-kit/src/ui/team/stage-pipeline/stage-pipeline.test.tsx +50 -0
  653. package/stack-template/app/ui-kit/src/ui/team/team-dashboard/index.tsx +103 -0
  654. package/stack-template/app/ui-kit/src/ui/team/team-dashboard/team-dashboard.stories.tsx +72 -0
  655. package/stack-template/app/ui-kit/src/ui/team/team-dashboard/team-dashboard.test.tsx +72 -0
  656. package/stack-template/app/ui-kit/src/ui/time-picker/index.tsx +143 -0
  657. package/stack-template/app/ui-kit/src/ui/time-picker/time-picker.stories.tsx +90 -0
  658. package/stack-template/app/ui-kit/src/ui/time-picker/time-picker.test.tsx +64 -0
  659. package/stack-template/app/ui-kit/src/ui/timeline/index.tsx +91 -0
  660. package/stack-template/app/ui-kit/src/ui/timeline/timeline.stories.tsx +209 -0
  661. package/stack-template/app/ui-kit/src/ui/timeline/timeline.test.tsx +116 -0
  662. package/stack-template/app/ui-kit/src/ui/timesheet/index.tsx +277 -0
  663. package/stack-template/app/ui-kit/src/ui/timesheet/timesheet.stories.tsx +97 -0
  664. package/stack-template/app/ui-kit/src/ui/timesheet/timesheet.test.tsx +103 -0
  665. package/stack-template/app/ui-kit/src/ui/toggle-button/index.tsx +28 -0
  666. package/stack-template/app/ui-kit/src/ui/toggle-button/toggle-button-group.stories.tsx +85 -0
  667. package/stack-template/app/ui-kit/src/ui/toggle-button/toggle-button-group.test.tsx +97 -0
  668. package/stack-template/app/ui-kit/src/ui/toggle-button/toggle-button-group.tsx +81 -0
  669. package/stack-template/app/ui-kit/src/ui/toggle-button/toggle-button.stories.tsx +46 -0
  670. package/stack-template/app/ui-kit/src/ui/toggle-button/toggle-button.test.tsx +38 -0
  671. package/stack-template/app/ui-kit/src/ui/toolbar/index.tsx +18 -0
  672. package/stack-template/app/ui-kit/src/ui/toolbar/toolbar.stories.tsx +35 -0
  673. package/stack-template/app/ui-kit/src/ui/toolbar/toolbar.test.tsx +11 -0
  674. package/stack-template/app/ui-kit/src/ui/tooltip/index.tsx +61 -0
  675. package/stack-template/app/ui-kit/src/ui/tooltip/tooltip.stories.tsx +81 -0
  676. package/stack-template/app/ui-kit/src/ui/tooltip/tooltip.test.tsx +120 -0
  677. package/stack-template/app/ui-kit/src/ui/tour/index.tsx +210 -0
  678. package/stack-template/app/ui-kit/src/ui/tour/tour.stories.tsx +153 -0
  679. package/stack-template/app/ui-kit/src/ui/tour/tour.test.tsx +131 -0
  680. package/stack-template/app/ui-kit/src/ui/transition/index.tsx +377 -0
  681. package/stack-template/app/ui-kit/src/ui/transition/transition.stories.tsx +254 -0
  682. package/stack-template/app/ui-kit/src/ui/transition/transition.test.tsx +285 -0
  683. package/stack-template/app/ui-kit/src/ui/tree/index.tsx +68 -0
  684. package/stack-template/app/ui-kit/src/ui/tree/tree.stories.tsx +139 -0
  685. package/stack-template/app/ui-kit/src/ui/tree/tree.test.tsx +77 -0
  686. package/stack-template/app/ui-kit/src/ui/tree-select/index.tsx +251 -0
  687. package/stack-template/app/ui-kit/src/ui/tree-select/tree-select.stories.tsx +105 -0
  688. package/stack-template/app/ui-kit/src/ui/tree-select/tree-select.test.tsx +174 -0
  689. package/stack-template/app/ui-kit/src/ui/tree-table/index.tsx +229 -0
  690. package/stack-template/app/ui-kit/src/ui/tree-table/tree-table.stories.tsx +111 -0
  691. package/stack-template/app/ui-kit/src/ui/tree-table/tree-table.test.tsx +137 -0
  692. package/stack-template/app/ui-kit/src/ui/typography/index.tsx +124 -0
  693. package/stack-template/app/ui-kit/src/ui/typography/typography.stories.tsx +65 -0
  694. package/stack-template/app/ui-kit/src/ui/typography/typography.test.tsx +117 -0
  695. package/stack-template/app/ui-kit/src/ui/upload/index.tsx +39 -0
  696. package/stack-template/app/ui-kit/src/ui/upload/upload-core.tsx +204 -0
  697. package/stack-template/app/ui-kit/src/ui/upload/upload-dropzone.tsx +79 -0
  698. package/stack-template/app/ui-kit/src/ui/upload/upload.stories.tsx +67 -0
  699. package/stack-template/app/ui-kit/src/ui/upload/upload.test.tsx +204 -0
  700. package/stack-template/app/ui-kit/src/ui/virtual-scroll/index.tsx +86 -0
  701. package/stack-template/app/ui-kit/src/ui/virtual-scroll/virtual-scroll.stories.tsx +111 -0
  702. package/stack-template/app/ui-kit/src/ui/virtual-scroll/virtual-scroll.test.tsx +125 -0
  703. package/stack-template/app/ui-kit/src/ui/watermark/index.tsx +182 -0
  704. package/stack-template/app/ui-kit/src/ui/watermark/watermark.stories.tsx +96 -0
  705. package/stack-template/app/ui-kit/src/ui/watermark/watermark.test.tsx +120 -0
  706. package/stack-template/app/ui-kit/src/utils/array.test.ts +88 -0
  707. package/stack-template/app/ui-kit/src/utils/array.ts +51 -0
  708. package/stack-template/app/ui-kit/src/utils/dom.test.tsx +69 -0
  709. package/stack-template/app/ui-kit/src/utils/dom.ts +38 -0
  710. package/stack-template/app/ui-kit/src/utils/format.test.ts +63 -0
  711. package/stack-template/app/ui-kit/src/utils/format.ts +81 -0
  712. package/stack-template/app/ui-kit/tests/setup.ts +15 -0
  713. package/stack-template/app/ui-kit/tsconfig.json +18 -0
  714. package/stack-template/app/ui-kit/tsup.config.ts +37 -0
  715. package/stack-template/app/ui-kit/vercel.json +6 -0
  716. package/stack-template/app/ui-kit/vitest.config.ts +22 -0
  717. package/stack-template/contracts/auth/token-contract.md +119 -0
  718. package/stack-template/contracts/auth/users.json +35 -0
  719. package/stack-template/contracts/db/tasks-schema.sql +62 -0
  720. package/stack-template/contracts/events/fixtures/task.assigned.json +11 -0
  721. package/stack-template/contracts/events/fixtures/task.assignment_failed.json +11 -0
  722. package/stack-template/contracts/events/fixtures/task.created.json +12 -0
  723. package/stack-template/contracts/events/fixtures/task.deleted.json +10 -0
  724. package/stack-template/contracts/events/fixtures/task.updated.json +12 -0
  725. package/stack-template/contracts/events/task-events.md +80 -0
  726. package/stack-template/contracts/openapi/activity.yaml +196 -0
  727. package/stack-template/contracts/openapi/auth.yaml +310 -0
  728. package/stack-template/contracts/openapi/tasks.yaml +316 -0
  729. package/stack-template/contracts/openapi/users.yaml +345 -0
  730. package/stack-template/docs/adr/0001-mixed-stack.md +14 -0
  731. package/stack-template/docs/adr/0002-mf-rspack.md +14 -0
  732. package/stack-template/docs/adr/0003-contract-first.md +14 -0
  733. package/stack-template/docs/adr/0004-readonly-schema-tradeoff.md +14 -0
  734. package/stack-template/docs/adr/0005-fail-closed.md +14 -0
  735. package/stack-template/docs/adr/0006-fire-and-forget-events.md +14 -0
  736. package/stack-template/docs/adr/0007-fork-not-upgrade.md +14 -0
  737. package/stack-template/docs/adr/0008-kafka-outbox-saga.md +24 -0
  738. package/stack-template/docs/adr/0009-ui-kit-split.md +39 -0
  739. package/stack-template/docs/adr/README.md +15 -0
  740. package/stack-template/docs/ai/recipes.md +956 -0
  741. package/stack-template/docs/ai/table-Theming.md +25 -0
  742. package/stack-template/docs/ai/table-datadisplay-mz.md +20 -0
  743. package/stack-template/docs/ai/table-feedback.md +20 -0
  744. package/stack-template/docs/ai/table-forms.md +26 -0
  745. package/stack-template/docs/git-flow.md +70 -0
  746. package/stack-template/docs/parity-matrix.md +102 -0
  747. package/stack-template/docs/superpowers/contexts/auth-real/gap-answer.md +195 -0
  748. package/stack-template/docs/superpowers/contexts/auth-real/sf-1.md +21 -0
  749. package/stack-template/docs/superpowers/contexts/auth-real/sf-2.md +21 -0
  750. package/stack-template/docs/superpowers/contexts/auth-real/sf-3.md +17 -0
  751. package/stack-template/docs/superpowers/contexts/auth-real/sf-4.md +20 -0
  752. package/stack-template/docs/superpowers/contexts/auth-real/sf-5.md +21 -0
  753. package/stack-template/docs/superpowers/contexts/experience-design.md +85 -0
  754. package/stack-template/docs/superpowers/contexts/sf-1.md +39 -0
  755. package/stack-template/docs/superpowers/contexts/sf-2.md +42 -0
  756. package/stack-template/docs/superpowers/contexts/sf-3.md +42 -0
  757. package/stack-template/docs/superpowers/contexts/sf-4.md +26 -0
  758. package/stack-template/docs/superpowers/contexts/sf-5.md +36 -0
  759. package/stack-template/docs/superpowers/contexts/sf-6.md +36 -0
  760. package/stack-template/docs/superpowers/contexts/sf-7.md +35 -0
  761. package/stack-template/docs/superpowers/contexts/sf-cin-overview.md +21 -0
  762. package/stack-template/docs/superpowers/contexts/ui-redesign/sf-1.md +46 -0
  763. package/stack-template/docs/superpowers/contexts/ui-redesign/sf-2.md +44 -0
  764. package/stack-template/docs/superpowers/contexts/ui-redesign/sf-3.md +47 -0
  765. package/stack-template/docs/superpowers/contexts/ui-redesign/sf-4.md +44 -0
  766. package/stack-template/docs/superpowers/contexts/ui-redesign/sf-5.md +36 -0
  767. package/stack-template/docs/superpowers/designs/direction-approved.md +11 -0
  768. package/stack-template/docs/superpowers/designs/ui-redesign/drafts/a-roulette-soundviz.html +353 -0
  769. package/stack-template/docs/superpowers/designs/ui-redesign/drafts/b-reference.html +347 -0
  770. package/stack-template/docs/superpowers/designs/ui-redesign/drafts/c-designer.html +375 -0
  771. package/stack-template/docs/superpowers/designs/ui-redesign/ds-demo.html +140 -0
  772. package/stack-template/docs/superpowers/designs/ui-redesign-direction.md +93 -0
  773. package/stack-template/docs/superpowers/improvements-log.md +158 -0
  774. package/stack-template/docs/superpowers/mindmaps/auth-real.wakii +115 -0
  775. package/stack-template/docs/superpowers/mindmaps/kafka-outbox-saga.wakii +110 -0
  776. package/stack-template/docs/superpowers/mindmaps/micro-boilerplate.wakii +171 -0
  777. package/stack-template/docs/superpowers/mindmaps/ui-redesign.wakii +116 -0
  778. package/stack-template/docs/superpowers/mindmaps/vu53-cinematic-experience.wakii +32 -0
  779. package/stack-template/docs/superpowers/plans/2026-10-12-sf-1-contracts-platform-plan.md +44 -0
  780. package/stack-template/docs/superpowers/plans/2026-10-12-sf-3-spring-svc-impact.md +69 -0
  781. package/stack-template/docs/superpowers/plans/2026-10-12-sf-3-spring-svc-plan.md +27 -0
  782. package/stack-template/docs/superpowers/plans/2026-10-12-sf-4-go-svc-plan.md +99 -0
  783. package/stack-template/docs/superpowers/plans/2026-10-12-sf-5-fe-shell-plan.md +64 -0
  784. package/stack-template/docs/superpowers/plans/2026-10-12-sf-6-fe-remotes-plan.md +83 -0
  785. package/stack-template/docs/superpowers/plans/2026-10-12-sf-7-convergence-plan.md +59 -0
  786. package/stack-template/docs/superpowers/plans/2026-10-12-sf2-node-svc-plan.md +19 -0
  787. package/stack-template/docs/superpowers/plans/2026-10-13-sf-1-kafka-foundation-plan.md +30 -0
  788. package/stack-template/docs/superpowers/plans/2026-10-13-sf-1-ui-redesign-plan.md +28 -0
  789. package/stack-template/docs/superpowers/plans/2026-10-13-sf-2-node-outbox-plan.md +46 -0
  790. package/stack-template/docs/superpowers/plans/2026-10-13-sf-3-go-consumer-plan.md +31 -0
  791. package/stack-template/docs/superpowers/plans/2026-10-13-sf-4-spring-tx-plan.md +96 -0
  792. package/stack-template/docs/superpowers/plans/2026-10-13-sf-5-convergence-plan.md +21 -0
  793. package/stack-template/docs/superpowers/plans/2026-10-14-sf-2-ui-redesign-plan.md +32 -0
  794. package/stack-template/docs/superpowers/plans/2026-10-14-sf-3-ui-redesign-plan.md +34 -0
  795. package/stack-template/docs/superpowers/plans/2026-10-14-sf-5-ui-redesign-plan.md +35 -0
  796. package/stack-template/docs/superpowers/plans/2026-10-17-auth-real-plan.md +112 -0
  797. package/stack-template/docs/superpowers/plans/2026-10-17-ui-kit-split-plan.md +18 -0
  798. package/stack-template/docs/superpowers/reviews/2026-10-18-data-display-coverage.md +52 -0
  799. package/stack-template/docs/superpowers/reviews/code-reviewer-sf-5-r1.md +65 -0
  800. package/stack-template/docs/superpowers/reviews/security-audit-sf-5-auth-real.md +39 -0
  801. package/stack-template/docs/superpowers/specs/2026-10-12-boilerplate-microservice-mfe.md +110 -0
  802. package/stack-template/docs/superpowers/specs/2026-10-12-sf-3-spring-svc-design.md +160 -0
  803. package/stack-template/docs/superpowers/specs/2026-10-12-sf-7-convergence-spec.md +114 -0
  804. package/stack-template/docs/superpowers/specs/2026-10-12-sf2-node-svc-spec.md +42 -0
  805. package/stack-template/docs/superpowers/specs/2026-10-13-kafka-outbox-saga.md +111 -0
  806. package/stack-template/docs/superpowers/specs/2026-10-13-ui-redesign.md +173 -0
  807. package/stack-template/docs/superpowers/specs/2026-10-14-sf-3-ui-redesign.md +46 -0
  808. package/stack-template/docs/superpowers/specs/2026-10-14-sf-5-ui-redesign.md +30 -0
  809. package/stack-template/docs/superpowers/specs/2026-10-17-antd-look-tokens.md +28 -0
  810. package/stack-template/docs/superpowers/specs/2026-10-17-auth-real-design.md +124 -0
  811. package/stack-template/docs/superpowers/specs/2026-10-17-tailwind-migration.md +32 -0
  812. package/stack-template/docs/superpowers/specs/2026-10-17-ui-kit-split.md +44 -0
  813. package/stack-template/docs/superpowers/specs/2026-10-18-0.3.0-release-notes.md +77 -0
  814. package/stack-template/docs/toolchain.md +28 -0
  815. package/stack-template/docs/wakii-playbook.md +172 -0
  816. package/stack-template/docs/walkthrough.md +204 -0
  817. package/stack-template/orca.yaml +146 -0
  818. package/stack-template/package.json +19 -0
  819. package/stack-template/platform/.env.example +72 -0
  820. package/stack-template/platform/conventions/01-dockerfile-pattern.md +78 -0
  821. package/stack-template/platform/conventions/02-healthcheck.md +26 -0
  822. package/stack-template/platform/conventions/03-logging.md +41 -0
  823. package/stack-template/platform/conventions/04-error-envelope.md +41 -0
  824. package/stack-template/platform/conventions/05-ports.md +38 -0
  825. package/stack-template/platform/conventions/06-configuration.md +25 -0
  826. package/stack-template/platform/conventions/07-cors.md +23 -0
  827. package/stack-template/platform/conventions/08-gateway-and-remotes.md +33 -0
  828. package/stack-template/platform/conventions/09-async-messaging.md +42 -0
  829. package/stack-template/platform/conventions/README.md +15 -0
  830. package/stack-template/platform/docker-compose.yml +255 -0
  831. package/stack-template/platform/gateway/nginx/nginx.conf +137 -0
  832. package/stack-template/platform/postgres/init/01-init.sh +55 -0
  833. package/stack-template/pnpm-lock.yaml +15992 -0
  834. package/stack-template/pnpm-workspace.yaml +24 -0
  835. package/stack-template/scripts/scaffold/scaffold.sh +110 -0
  836. package/stack-template/scripts/smoke/e2e.sh +305 -0
  837. package/stack-template/scripts/snapshot-stack-template.sh +84 -0
  838. package/stack-template/services/auth-svc/.dockerignore +5 -0
  839. package/stack-template/services/auth-svc/Dockerfile +32 -0
  840. package/stack-template/services/auth-svc/README.md +101 -0
  841. package/stack-template/services/auth-svc/drizzle/0000_init.sql +25 -0
  842. package/stack-template/services/auth-svc/drizzle/meta/0000_snapshot.json +190 -0
  843. package/stack-template/services/auth-svc/drizzle/meta/_journal.json +13 -0
  844. package/stack-template/services/auth-svc/drizzle.config.ts +10 -0
  845. package/stack-template/services/auth-svc/package.json +35 -0
  846. package/stack-template/services/auth-svc/pnpm-lock.yaml +2425 -0
  847. package/stack-template/services/auth-svc/src/app.test.ts +403 -0
  848. package/stack-template/services/auth-svc/src/app.ts +103 -0
  849. package/stack-template/services/auth-svc/src/auth-crypto.test.ts +32 -0
  850. package/stack-template/services/auth-svc/src/auth-crypto.ts +25 -0
  851. package/stack-template/services/auth-svc/src/db/client.ts +24 -0
  852. package/stack-template/services/auth-svc/src/db/migrate.ts +72 -0
  853. package/stack-template/services/auth-svc/src/db/schema.ts +39 -0
  854. package/stack-template/services/auth-svc/src/db/seed.ts +60 -0
  855. package/stack-template/services/auth-svc/src/env.test.ts +55 -0
  856. package/stack-template/services/auth-svc/src/env.ts +57 -0
  857. package/stack-template/services/auth-svc/src/logger.ts +31 -0
  858. package/stack-template/services/auth-svc/src/plugins/auth.ts +70 -0
  859. package/stack-template/services/auth-svc/src/repo.drizzle.integration.test.ts +182 -0
  860. package/stack-template/services/auth-svc/src/repo.drizzle.ts +144 -0
  861. package/stack-template/services/auth-svc/src/repo.test-support.ts +168 -0
  862. package/stack-template/services/auth-svc/src/repo.ts +60 -0
  863. package/stack-template/services/auth-svc/src/routes/auth.ts +193 -0
  864. package/stack-template/services/auth-svc/src/routes/health.ts +40 -0
  865. package/stack-template/services/auth-svc/src/server.ts +54 -0
  866. package/stack-template/services/auth-svc/tsconfig.json +20 -0
  867. package/stack-template/services/go-svc/.dockerignore +5 -0
  868. package/stack-template/services/go-svc/Dockerfile +19 -0
  869. package/stack-template/services/go-svc/README.md +93 -0
  870. package/stack-template/services/go-svc/cmd/server/main.go +105 -0
  871. package/stack-template/services/go-svc/go.mod +12 -0
  872. package/stack-template/services/go-svc/internal/api/auth.go +83 -0
  873. package/stack-template/services/go-svc/internal/api/auth_test.go +92 -0
  874. package/stack-template/services/go-svc/internal/api/envelope.go +61 -0
  875. package/stack-template/services/go-svc/internal/api/envelope_test.go +51 -0
  876. package/stack-template/services/go-svc/internal/api/fakes_test.go +105 -0
  877. package/stack-template/services/go-svc/internal/api/feed.go +98 -0
  878. package/stack-template/services/go-svc/internal/api/feed_test.go +118 -0
  879. package/stack-template/services/go-svc/internal/api/health.go +34 -0
  880. package/stack-template/services/go-svc/internal/api/health_test.go +46 -0
  881. package/stack-template/services/go-svc/internal/api/json.go +13 -0
  882. package/stack-template/services/go-svc/internal/api/middleware.go +82 -0
  883. package/stack-template/services/go-svc/internal/api/middleware_test.go +48 -0
  884. package/stack-template/services/go-svc/internal/api/openapi/activity.yaml +196 -0
  885. package/stack-template/services/go-svc/internal/api/openapi.go +29 -0
  886. package/stack-template/services/go-svc/internal/api/openapi_test.go +38 -0
  887. package/stack-template/services/go-svc/internal/api/router.go +86 -0
  888. package/stack-template/services/go-svc/internal/api/stats.go +63 -0
  889. package/stack-template/services/go-svc/internal/api/stats_test.go +83 -0
  890. package/stack-template/services/go-svc/internal/api/types.go +32 -0
  891. package/stack-template/services/go-svc/internal/apperr/apperr.go +9 -0
  892. package/stack-template/services/go-svc/internal/config/config.go +115 -0
  893. package/stack-template/services/go-svc/internal/config/config_test.go +92 -0
  894. package/stack-template/services/go-svc/internal/consumer/envelope.go +78 -0
  895. package/stack-template/services/go-svc/internal/consumer/envelope_test.go +154 -0
  896. package/stack-template/services/go-svc/internal/consumer/handler.go +91 -0
  897. package/stack-template/services/go-svc/internal/consumer/handler_test.go +136 -0
  898. package/stack-template/services/go-svc/internal/consumer/producer.go +117 -0
  899. package/stack-template/services/go-svc/internal/consumer/runner.go +194 -0
  900. package/stack-template/services/go-svc/internal/consumer/runner_test.go +351 -0
  901. package/stack-template/services/go-svc/internal/logging/logging.go +49 -0
  902. package/stack-template/services/go-svc/internal/model/model.go +37 -0
  903. package/stack-template/services/go-svc/internal/resolve/resolver.go +134 -0
  904. package/stack-template/services/go-svc/internal/resolve/resolver_test.go +82 -0
  905. package/stack-template/services/go-svc/internal/resolve/token.go +130 -0
  906. package/stack-template/services/go-svc/internal/resolve/token_test.go +151 -0
  907. package/stack-template/services/go-svc/internal/store/events.go +71 -0
  908. package/stack-template/services/go-svc/internal/store/migrate.go +90 -0
  909. package/stack-template/services/go-svc/internal/store/migrate_test.go +34 -0
  910. package/stack-template/services/go-svc/internal/store/migrations/0001_create_events.sql +20 -0
  911. package/stack-template/services/go-svc/internal/store/migrations/0002_widen_action_cascade.sql +14 -0
  912. package/stack-template/services/go-svc/internal/store/store.go +65 -0
  913. package/stack-template/services/go-svc/internal/store/tasks.go +109 -0
  914. package/stack-template/services/go-svc/internal/swagger/assets/LICENSE +202 -0
  915. package/stack-template/services/go-svc/internal/swagger/assets/NOTICE +2 -0
  916. package/stack-template/services/go-svc/internal/swagger/assets/favicon-16x16.png +0 -0
  917. package/stack-template/services/go-svc/internal/swagger/assets/favicon-32x32.png +0 -0
  918. package/stack-template/services/go-svc/internal/swagger/assets/swagger-ui-bundle.js +2 -0
  919. package/stack-template/services/go-svc/internal/swagger/assets/swagger-ui.css +3 -0
  920. package/stack-template/services/go-svc/internal/swagger/index.html +28 -0
  921. package/stack-template/services/go-svc/internal/swagger/swagger.go +38 -0
  922. package/stack-template/services/go-svc/test/integration/integration_test.go +523 -0
  923. package/stack-template/services/node-svc/.dockerignore +5 -0
  924. package/stack-template/services/node-svc/Dockerfile +27 -0
  925. package/stack-template/services/node-svc/README.md +155 -0
  926. package/stack-template/services/node-svc/drizzle/0000_init.sql +17 -0
  927. package/stack-template/services/node-svc/drizzle/0001_status-assignment-failed.sql +2 -0
  928. package/stack-template/services/node-svc/drizzle/0002_outbox-table.sql +7 -0
  929. package/stack-template/services/node-svc/drizzle/meta/0000_snapshot.json +136 -0
  930. package/stack-template/services/node-svc/drizzle/meta/0001_snapshot.json +136 -0
  931. package/stack-template/services/node-svc/drizzle/meta/0002_snapshot.json +180 -0
  932. package/stack-template/services/node-svc/drizzle/meta/_journal.json +27 -0
  933. package/stack-template/services/node-svc/drizzle.config.ts +10 -0
  934. package/stack-template/services/node-svc/package.json +39 -0
  935. package/stack-template/services/node-svc/pnpm-lock.yaml +2706 -0
  936. package/stack-template/services/node-svc/src/app.test.ts +611 -0
  937. package/stack-template/services/node-svc/src/app.ts +126 -0
  938. package/stack-template/services/node-svc/src/clients/spring.ts +53 -0
  939. package/stack-template/services/node-svc/src/compensation-consumer.test.ts +157 -0
  940. package/stack-template/services/node-svc/src/compensation-consumer.ts +170 -0
  941. package/stack-template/services/node-svc/src/db/client.ts +23 -0
  942. package/stack-template/services/node-svc/src/db/migrate.ts +63 -0
  943. package/stack-template/services/node-svc/src/db/schema-diff.test.ts +252 -0
  944. package/stack-template/services/node-svc/src/db/schema.ts +64 -0
  945. package/stack-template/services/node-svc/src/env.ts +52 -0
  946. package/stack-template/services/node-svc/src/logger.ts +18 -0
  947. package/stack-template/services/node-svc/src/outbox-relay.test.ts +141 -0
  948. package/stack-template/services/node-svc/src/outbox-relay.ts +182 -0
  949. package/stack-template/services/node-svc/src/plugins/auth.ts +76 -0
  950. package/stack-template/services/node-svc/src/repo.drizzle.test.ts +182 -0
  951. package/stack-template/services/node-svc/src/repo.drizzle.ts +158 -0
  952. package/stack-template/services/node-svc/src/repo.ts +73 -0
  953. package/stack-template/services/node-svc/src/routes/health.ts +42 -0
  954. package/stack-template/services/node-svc/src/routes/tasks.ts +287 -0
  955. package/stack-template/services/node-svc/src/server.ts +91 -0
  956. package/stack-template/services/node-svc/src/types/api.d.ts +391 -0
  957. package/stack-template/services/node-svc/src/types/log.ts +3 -0
  958. package/stack-template/services/node-svc/tsconfig.json +20 -0
  959. package/stack-template/services/spring-svc/.dockerignore +5 -0
  960. package/stack-template/services/spring-svc/.mvn/wrapper/maven-wrapper.properties +20 -0
  961. package/stack-template/services/spring-svc/Dockerfile +22 -0
  962. package/stack-template/services/spring-svc/README.md +121 -0
  963. package/stack-template/services/spring-svc/mvnw +332 -0
  964. package/stack-template/services/spring-svc/mvnw.cmd +206 -0
  965. package/stack-template/services/spring-svc/pom.xml +144 -0
  966. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/SpringSvcApplication.java +12 -0
  967. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/domain/Team.java +64 -0
  968. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/domain/TeamRepository.java +34 -0
  969. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/domain/User.java +72 -0
  970. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/domain/UserRepository.java +10 -0
  971. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/logging/LowercaseLevelJsonProvider.java +24 -0
  972. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/security/JwtAuthFilter.java +89 -0
  973. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/security/JwtVerifier.java +48 -0
  974. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/service/TeamService.java +84 -0
  975. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/ApiError.java +15 -0
  976. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/ApiException.java +37 -0
  977. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/DevCorsConfig.java +41 -0
  978. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/ErrorEnvelope.java +27 -0
  979. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/GlobalExceptionHandler.java +90 -0
  980. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/HealthController.java +46 -0
  981. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/ReadinessService.java +40 -0
  982. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/TeamController.java +79 -0
  983. package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/UserController.java +187 -0
  984. package/stack-template/services/spring-svc/src/main/java/db/migration/V2__SeedUsers.java +66 -0
  985. package/stack-template/services/spring-svc/src/main/resources/application.yml +42 -0
  986. package/stack-template/services/spring-svc/src/main/resources/db/migration/V1__init.sql +24 -0
  987. package/stack-template/services/spring-svc/src/main/resources/logback-spring.xml +34 -0
  988. package/stack-template/services/spring-svc/src/main/resources/openapi/users.yaml +345 -0
  989. package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/logging/LogShapeTest.java +39 -0
  990. package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/security/JwtAuthFilterTest.java +106 -0
  991. package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/seed/SeedMatchIntegrationTest.java +68 -0
  992. package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/service/TeamServiceRollbackTest.java +122 -0
  993. package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/web/DevCorsTest.java +45 -0
  994. package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/web/HealthCheckTest.java +56 -0
  995. package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/web/TeamApiTest.java +139 -0
  996. package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/web/TestPingController.java +21 -0
  997. package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/web/UserApiTest.java +182 -0
  998. package/stack-template/stack-manifest.json +285 -0
@@ -0,0 +1,116 @@
1
+ {
2
+ "wakiiMindmap": 1,
3
+ "meta": {
4
+ "story": "VU-53",
5
+ "generator": "story-workflow CREATE",
6
+ "generatedAt": "2026-10-13T23:05:00+07:00",
7
+ "dest": "story-vu53-ui-redesign",
8
+ "worktreeModel": "story-hub"
9
+ },
10
+ "nodes": [
11
+ {
12
+ "id": "epic",
13
+ "kind": "epic",
14
+ "title": "UI/UX Redesign — shell + remotes + fe-shared design system",
15
+ "summary": "Design lại toàn bộ UI micro-frontend demo: design system fe-shared (tokens + base + primitives) + restyle shell/tasks/activity + đóng UX gaps bằng API hiện có. Spec: docs/superpowers/specs/2026-10-13-ui-redesign.md (rev 3 — spec-critic GO, plan-critic GO). Linear: VU-53."
16
+ },
17
+ {
18
+ "id": "sf-1",
19
+ "kind": "sf",
20
+ "title": "Design direction + design-system nền móng",
21
+ "tier": 0,
22
+ "design": "mock-prototype",
23
+ "summary": "Phase 1/3 — shippable: nền móng đứng cạnh UI cũ (không phá hiện trạng). DESIGN GATE ĐÃ XONG ngay lúc CREATE (front-load, kit 8b): user chọn hướng B Linear-referenced dark 2026-10-13 — hand-off docs/superpowers/designs/ui-redesign-direction.md (tokens + component props API đầy đủ), gate record direction-approved.md — SF-1 KHÔNG còn designer phase, implement thẳng theo hand-off. Việc còn lại: fe-shared src/styles (tokens+base @layer) + src/ui primitives (Badge/EmptyState/Skeleton/Spinner theo props API hand-off); rspack css rule ×3 + react/jsx-runtime shared ×3 + spike duplicate-react chạy SỚM (fallback class-only); cssFilename contenthash; standalone :4001/:4002 import base+tokens; tests primitives ở shell/tests. Demo: standalone 2 remote có baseline style + trang demo primitives khớp hand-off. Context pack: docs/superpowers/contexts/ui-redesign/sf-1.md",
24
+ "linear": "VU-54"
25
+ },
26
+ {
27
+ "id": "sf-2",
28
+ "kind": "sf",
29
+ "title": "Shell — layout, login, nav, remote fallback",
30
+ "tier": 1,
31
+ "summary": "Phase 2/3 — shippable: shell restyle theo hand-off SF-1 (không gate mock riêng — direction đã user-duyệt). Layout container + header; NavBar active state (aria-current) + responsive ≤768px + user chip; HomePage dashboard + quick links + demo hints; LoginPage card (behavior + error messages giữ); RemoteSlot Suspense fallback = Skeleton + error fallback giữ text contract; styles.css rewrite scoped. Demo: login → nav active → dashboard → kill remote thấy fallback đẹp. Context pack: docs/superpowers/contexts/ui-redesign/sf-2.md",
32
+ "linear": "VU-55"
33
+ },
34
+ {
35
+ "id": "sf-3",
36
+ "kind": "sf",
37
+ "title": "Remote tasks — TasksPage redesign + UX gaps",
38
+ "tier": 1,
39
+ "summary": "Phase 2/3 — shippable: tasks UI mới đầy đủ hành vi API sẵn có. Tách TaskForm/TaskList/TaskItem/StatusSelect; card responsive + StatusBadge primitive (giữ 'Gán thất bại' role=status); per-item busy; edit inline title/description (PATCH); delete + confirm (DELETE); assignee UUID rút gọn + createdAt; 'Tải thêm' (limit+offset) + filter status (?status=); skeleton/empty primitives; api.ts mở rộng đúng tasks.yaml. Demo: CRUD + filter + pagination trên UI mới; saga 4b badge nhận diện. Context pack: docs/superpowers/contexts/ui-redesign/sf-3.md",
40
+ "linear": "VU-56"
41
+ },
42
+ {
43
+ "id": "sf-4",
44
+ "kind": "sf",
45
+ "title": "Remote activity — ActivityPage redesign",
46
+ "tier": 1,
47
+ "summary": "Phase 2/3 — shippable: activity UI mới. Stats grid responsive (aria-label giữ); feed timeline nhóm ngày + item card (badge action primitive + userName/taskTitle + time vi-VN); refresh busy state; skeleton feed/stats độc lập (giữ Promise.allSettled); EmptyState hướng dẫn sang Tasks; scoped css theo kiến trúc đích. Demo: thao tác ở Tasks → Activity phản ánh đúng badge từng action. Context pack: docs/superpowers/contexts/ui-redesign/sf-4.md",
48
+ "linear": "VU-57"
49
+ },
50
+ {
51
+ "id": "sf-5",
52
+ "kind": "sf",
53
+ "title": "Convergence — browser walkthrough + docs + security",
54
+ "tier": 2,
55
+ "summary": "Phase 3/3 — shippable: hội tụ + chứng minh. Rule 0 browser walkthrough compose :8080 đủ 8 acceptance epic (login → Tasks CRUD → Activity Kafka → saga 4b badge → re-assign bob → kill remote fallback → standalone có style) + responsive 375px; full suite 3 package test+typecheck+build xanh, lockfile không đổi, e2e smoke vẫn PASS; docs sync (walkthrough 4/4b, READMEs); security pass 0 P0/P1; scaffold sanity verify-only; improvements-log. Demo: NGƯỜI xác nhận walkthrough PASS trên UI mới (human gate cuối). Context pack: docs/superpowers/contexts/ui-redesign/sf-5.md",
56
+ "linear": "VU-58"
57
+ }
58
+ ],
59
+ "edges": [
60
+ {
61
+ "from": "epic",
62
+ "to": "sf-1",
63
+ "rel": "contains"
64
+ },
65
+ {
66
+ "from": "epic",
67
+ "to": "sf-2",
68
+ "rel": "contains"
69
+ },
70
+ {
71
+ "from": "epic",
72
+ "to": "sf-3",
73
+ "rel": "contains"
74
+ },
75
+ {
76
+ "from": "epic",
77
+ "to": "sf-4",
78
+ "rel": "contains"
79
+ },
80
+ {
81
+ "from": "epic",
82
+ "to": "sf-5",
83
+ "rel": "contains"
84
+ },
85
+ {
86
+ "from": "sf-2",
87
+ "to": "sf-1",
88
+ "rel": "depends-on"
89
+ },
90
+ {
91
+ "from": "sf-3",
92
+ "to": "sf-1",
93
+ "rel": "depends-on"
94
+ },
95
+ {
96
+ "from": "sf-4",
97
+ "to": "sf-1",
98
+ "rel": "depends-on"
99
+ },
100
+ {
101
+ "from": "sf-5",
102
+ "to": "sf-2",
103
+ "rel": "depends-on"
104
+ },
105
+ {
106
+ "from": "sf-5",
107
+ "to": "sf-3",
108
+ "rel": "depends-on"
109
+ },
110
+ {
111
+ "from": "sf-5",
112
+ "to": "sf-4",
113
+ "rel": "depends-on"
114
+ }
115
+ ]
116
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "wakiiMindmap": 1,
3
+ "meta": { "story": "VU-53-CIN", "generator": "story-workflow CREATE", "generatedAt": "2026-10-19T00:05:00+07:00", "dest": "story-vu53-cin-experience", "worktreeModel": "story-hub" },
4
+ "nodes": [
5
+ { "id": "epic", "kind": "epic", "title": "Cinematic Experience — redesign chuẩn story-workflow (ref experience.staratlas.com)" },
6
+ { "id": "sf-1", "kind": "sf", "title": "Design Contract + Mood Engine (nền tảng)", "tier": 0, "design": "figma", "linear": "", "summary": "Phase 1/4 — shippable: EXPERIENCE-DESIGN contract dùng được độc lập (typography scale REF-SPEC, palette 5 mood, spacing, motion vocabulary) + scroll-mood engine + Avatar/Getty ảnh graded chuẩn hoá. Demo: story mood-engine riêng render 5 mood đúng số đo." },
7
+ { "id": "sf-2", "kind": "sf", "title": "Hero + Starfield + Trailer Gate", "tier": 1, "design": "figma", "linear": "", "summary": "Hero ref-fidility: section NỀN SÁNG chữ navy (REF-SPEC đo), ALL-CAPS display tracking 2.4, numbered header 01-05, canvas starfield theme-aware (bông tuyết light khi dark), trailer Modal. Demo: hero story standalone giống ref-hero.png ở 1280+375." },
8
+ { "id": "sf-3", "kind": "sf", "title": "Chapter Shell + Side-nav Progress", "tier": 1, "design": "figma", "linear": "", "summary": "ChapterShell component (label mono CHƯƠNG 0X 11px/700 tracking 2.64 + ALL-CAPS title ~29px/300 + copy punchy 2 dòng + parallax nền gần-fixed speed 0.08/strength 280) + Anchor side-nav sticky single-source aria-current (fix overlap vĩnh viễn bằng cấu trúc). Demo: 1 chương generic + nav chạy scroll-spy đúng 5 mục." },
9
+ { "id": "sf-4", "kind": "sf", "title": "Ch1 Deep Focus + Ch2 Living Docs", "tier": 2, "design": "figma", "linear": "", "summary": "2 chương nội dung theo ChapterShell: CountUp 62.210 + split-text reveal + 3 feature card mask-reveal clip-path. Demo: 2 chương render đúng contract, measure transform + clip-path đổi theo scroll." },
10
+ { "id": "sf-5", "kind": "sf", "title": "Ch3 Velocity + Ch4 Ship 3D", "tier": 2, "design": "figma", "linear": "", "summary": "Ch3 workflow-cards chọn được (mood accent) + Ch4 sticky-pinned 200vh tích hợp ScrollFlythrough Scene3D (three.js peer-dep, fallback node) — chương 3D thật của website. Demo: scroll ch4 → camera bay quanh tàu, fps>=50 paste số." },
11
+ { "id": "sf-6", "kind": "sf", "title": "Ch5 Future + Sun Journey + End CTA", "tier": 2, "design": "figma", "linear": "", "summary": "Band 4 CountUp + sun-journey arc dawn->night (đã verify) làm chuyển cảnh sang End CTA glow + footer numbered + social Icon. Demo: cụm cuối hoàn chỉnh + night mode đẹp." },
12
+ { "id": "sf-7", "kind": "sf", "title": "Convergence + QA full", "tier": 3, "linear": "", "summary": "Phase 4/4: ghép index Trải Nghiệm hoàn chỉnh + responsive 4bp (375/768/1280/1440) + contrast số >=4.5:1 mọi chương 2 mode + reduced-motion + performance (fps, will-change đúng) + evidence pack + deploy alias. Demo: story chính chạy end-to-end giống ref nhất có thể, mọi số liệu paste." }
13
+ ],
14
+ "edges": [
15
+ { "from": "epic", "to": "sf-1", "rel": "contains" },
16
+ { "from": "epic", "to": "sf-2", "rel": "contains" },
17
+ { "from": "epic", "to": "sf-3", "rel": "contains" },
18
+ { "from": "epic", "to": "sf-4", "rel": "contains" },
19
+ { "from": "epic", "to": "sf-5", "rel": "contains" },
20
+ { "from": "epic", "to": "sf-6", "rel": "contains" },
21
+ { "from": "epic", "to": "sf-7", "rel": "contains" },
22
+ { "from": "sf-2", "to": "sf-1", "rel": "depends-on" },
23
+ { "from": "sf-3", "to": "sf-1", "rel": "depends-on" },
24
+ { "from": "sf-4", "to": "sf-3", "rel": "depends-on" },
25
+ { "from": "sf-5", "to": "sf-3", "rel": "depends-on" },
26
+ { "from": "sf-6", "to": "sf-3", "rel": "depends-on" },
27
+ { "from": "sf-7", "to": "sf-4", "rel": "depends-on" },
28
+ { "from": "sf-7", "to": "sf-5", "rel": "depends-on" },
29
+ { "from": "sf-7", "to": "sf-6", "rel": "depends-on" },
30
+ { "from": "sf-7", "to": "sf-2", "rel": "depends-on" }
31
+ ]
32
+ }
@@ -0,0 +1,44 @@
1
+ # Plan — SF-1 Contracts & Platform Foundation (FI-64)
2
+
3
+ > Story FI-62 · spec: `docs/superpowers/specs/2026-10-12-boilerplate-microservice-mfe.md` rev 3 · slice: `docs/superpowers/contexts/sf-1.md`
4
+ > Worktree: `__STACK_ORG__/sf-1-contracts-platform` (fork từ `__STACK_ORG__/story-fi62-micro-boilerplate`) · merge target: nhánh story (coordinator merge)
5
+ > Tier: Full (16 tasks) · Ràng buộc: dev machine KHÔNG Docker — verify docker qua CI; Java/Go không local
6
+
7
+ ## Key design decisions (contract-level — các SF sau fork từ đây)
8
+
9
+ 1. **Gateway pass-through, không rewrite prefix**: mọi service mount route dưới `/api/<svc>/...` khớp chính xác `servers.url` trong OpenAPI spec. nginx chỉ proxy + chặn thiếu-token (401) cho `/api/tasks|users|activity`; `/api/auth`, `/`, `/remotes/*` mở.
10
+ 2. **auth-mock = Fastify (Node 22)** — chạy native được trên dev machine (browser-verify swagger UI local), Dockerfile multi-stage cho CI/boot-smoke.
11
+ 3. **Spike MF** tại `frontend/spike/{host,remote}` — build + chạy thật trên Rspack, pin version = version đã test thật (ghi vào `frontend/shared/package.json` + `frontend/spike/README.md`).
12
+ 4. **Port table** (conventions + compose + README khớp nhau): gateway 8080, shell 3000, remote-tasks 4001, remote-activity 4002, node-svc 3001, spring-svc 8081, go-svc 8082, auth-mock 8090, postgres 5432.
13
+ 5. **Canonical DDL**: schema `tasks`, bảng `tasks` — `assignee_id`/`created_by` là uuid KHÔNG FK chéo schema (users thuộc schema `users` của spring-svc; validate qua REST).
14
+ 6. **Readonly grant**: `ALTER DEFAULT PRIVILEGES FOR ROLE node_svc IN SCHEMA tasks GRANT SELECT ON TABLES TO go_readonly` — hiệu lực cho bảng sinh sau bởi migration SF-2.
15
+ 7. **Users fixture**: `{id, email, roles}` — auth-mock đọc runtime; spring seed (SF-3) đọc cùng file. Login mock: email + dev password qua env `AUTH_MOCK_DEV_PASSWORD` (default ghi rõ trong token-contract, mock-only).
16
+ 8. **CI**: active cho contracts + auth-mock (spectral, schemathesis scaffold, gitleaks, compose config, boot-smoke auth-mock); CI per-service để TEMPLATE cho SF-2/3/4 (chưa bật — services chưa có code).
17
+
18
+ ## Tasks
19
+
20
+ - [x] Task 1 — Repo hygiene: `.gitignore` (node_modules, .env, dist, target, build…), `.gitattributes` (`* text=auto eol=lf`), `.editorconfig`
21
+ - [x] Task 2 — pnpm workspace root: `pnpm-workspace.yaml` (globs `frontend/*`, `frontend/spike/*`, `services/node-svc`), root `package.json`, `packageManager` pin
22
+ - [x] Task 3 — `contracts/openapi/tasks.yaml`: Task schema khớp canonical DDL; CRUD `/api/tasks`; error envelope responses
23
+ - [x] Task 4 — `contracts/openapi/users.yaml`: `/api/users` + `/api/teams` (spring-svc surface, đủ cho node-svc validate user)
24
+ - [x] Task 5 — `contracts/openapi/activity.yaml`: `POST /api/activity/events` (taskId, userId, action, timestamp) + feed response CHỨA user-display fields (userName, taskTitle) + stats
25
+ - [x] Task 6 — `contracts/openapi/auth.yaml`: `/api/auth/login`, discovery stub, fixture users list; `.spectral.yaml` ruleset
26
+ - [x] Task 7 — `contracts/db/tasks-schema.sql` canonical DDL (schema `tasks`, indexes, comment lý do không FK chéo schema)
27
+ - [x] Task 8 — `contracts/auth/users.json` fixture + `contracts/auth/token-contract.md` (HS256, claims sub/email/roles, TTL 8h, secret phân phối, enforcement 2 lớp)
28
+ - [x] Task 9 — `platform/conventions/`: dockerfile-pattern.md, healthcheck.md, logging.md (JSON shape), error-envelope.md, ports.md (port table), configuration.md (env-var rule), cors.md (dev-profile rule), gateway-routing.md (routing table + remote registry)
29
+ - [x] Task 10 — `platform/docker-compose.yml` PRE-SEED 6 services (postgres, auth-mock, gateway, node-svc, spring-svc, go-svc) + `platform/.env.example` inventory ĐẦY ĐỦ + `platform/postgres/init/01-schemas.sql` (schemas + per-service roles + `ALTER DEFAULT PRIVILEGES`)
30
+ - [x] Task 11 — `platform/gateway/nginx/`: nginx.conf theo routing table + JWT presence check (`/api/tasks|users|activity` thiếu Authorization → 401)
31
+ - [x] Task 12 — `platform/auth-mock/`: Fastify service đọc users fixture, cấp JWT theo token contract, `/healthz` `/readyz`, swagger UI `/docs`, discovery stub, disclaimer NOT-FOR-PRODUCTION, tests (node:test), Dockerfile multi-stage
32
+ - [x] Task 13 — `frontend/shared/`: api client wrapper (đính JWT + decode error envelope), token storage, MF bootstrap helper, package.json pin versions; `frontend/spike/`: host + remote hello-world trên Rspack + @module-federation/enhanced — CHẠY THẬT local, ghi kết quả pin
33
+ - [x] Task 14 — Services khung rỗng: `services/node-svc|spring-svc|go-svc/.gitkeep` + README-placeholder (SF-2/3/4 điền impl); KHÔNG code impl
34
+ - [x] Task 15 — CI: `.github/workflows/contracts.yml` (spectral + compose config + gitleaks + boot-smoke auth-mock + schemathesis scaffold) + `.github/workflows/services-ci-template.yml` (template path-filtered + boot-smoke cho SF-2/3/4)
35
+ - [x] Task 16 — README.md: Mermaid kiến trúc thật khớp cây thư mục + cách chạy từng phần + port table
36
+
37
+ ## Verification (exit criteria)
38
+
39
+ 1. CI xanh trên nhánh `__STACK_ORG__/sf-1-contracts-platform`: spectral pass, compose config validate, gitleaks pass, boot-smoke auth-mock xanh, schemathesis scaffold chạy.
40
+ 2. Từng dòng ACCEPTANCE trong `docs/superpowers/contexts/sf-1.md` kiểm riêng (Phase 5).
41
+ 3. auth-mock: chạy native local → curl login nhận JWT decode đúng claims + TTL 8h; swagger UI mở được bằng mắt (browser verify).
42
+ 4. Spike MF: host load remote hello-world thật (evidence: build output + screenshot/log).
43
+ 5. Code-reviewer độc lập trên diff SF → APPROVED (comment Linear có VERDICT APPROVED + CHECKLIST-4Q).
44
+ 6. `~/.claude/bin/story-verify sf-1` không FAIL/VIOLATION.
@@ -0,0 +1,69 @@
1
+ # Phase 0 — Impact Analysis — SF-3 spring-svc (FI-71)
2
+
3
+ > Story FI-62 · spec rev 3 · slice: `docs/superpowers/contexts/sf-3.md` · worktree `__STACK_ORG__/sf-3-spring-svc`
4
+ > Tier: Full (9 tasks). Chạy autonomous theo brief — decisions đã chốt ở epic, không hỏi lại.
5
+
6
+ ## 1. Problem framing
7
+
8
+ spring-svc chưa tồn tại (chỉ README placeholder từ SF-1) → acceptance epic #2 (node-svc validate
9
+ assignee qua REST) gãy ở integration, acceptance #4 (service tự verify JWT) không chứng minh được.
10
+ spring-svc là **source-of-truth users/teams**: seed PHẢI khớp `contracts/auth/users.json` 100%
11
+ vì auth-mock (SF-1) đọc cùng fixture — lệch id = login user A nhưng validate user id không tồn tại.
12
+
13
+ Constraints chốt: dev machine KHÔNG Docker + KHÔNG JDK (đã probe: `java`, `docker`, `mvn` đều vắng)
14
+ → mọi build/test/docker verify **qua CI**; KHÔNG sửa compose/contracts/conventions; KHÔNG Keycloak.
15
+
16
+ ## 2. Touch map
17
+
18
+ ```
19
+ services/spring-svc/** [SỞ HỮU — tạo mới: pom.xml, mvnw, src/**, Dockerfile, .dockerignore, README]
20
+ .github/workflows/services-spring-svc.yml [TẠO MỚI — copy từ .github/workflow-templates/services-ci.yml.example]
21
+ docs/superpowers/evidence/sf-3/** [TẠO MỚI — evidence convention B1+]
22
+ platform/docker-compose.yml [READ-ONLY — entry pre-seed: SPRING_DATASOURCE_*, JWT_SECRET, USERS_FIXTURE_PATH]
23
+ platform/conventions/*, contracts/** [READ-ONLY]
24
+ platform/.env.example [READ-ONLY]
25
+ ```
26
+
27
+ Drift-guard duy nhất phát sinh: snapshot `contracts/openapi/users.yaml` phải nằm trong Docker
28
+ build context (context = `services/spring-svc` — compose `build: ../services/spring-svc` không
29
+ thấy `contracts/`). Snapshot commit tại `services/spring-svc/src/main/resources/openapi/users.yaml`
30
+ (bit-identical) + CI diff-guard chặn drift. Đây là file SF-3 sở hữu, KHÔNG đụng contracts/.
31
+
32
+ ## 3. Second-order effects (multi-dimension)
33
+
34
+ | Dimension | Assessment | Risk/gap |
35
+ |-----------|-----------|----------|
36
+ | Functional | CRUD users/teams khớp users.yaml; seed 3 fixture users | Seed lệch id → acceptance #2 gãy; assert trong test là bắt buộc |
37
+ | Technical/architecture | Spring Boot 3 Web MVC + Flyway + Spring Data JPA; mount `/api/users`, `/api/teams`; healthz/readyz naked | Role `spring_svc` có `search_path=users` (init script) → Hibernate resolve đúng schema mà không đụng JDBC URL |
38
+ | Data | Schema `users`: users, teams, team_members; id UUID cố định từ fixture | Flyway Java migration đọc `USERS_FIXTURE_PATH` (env, compose mount sẵn) — đọc file thật = khớp 100% theo cấu trúc, không hardcode |
39
+ | Performance | CRUD demo-scale; limit/offset list users | Không hot path; bỏ qua tối ưu |
40
+ | Security | JWT HS256 service-side: signature + exp + iss, mọi route trừ healthz/readyz/swagger-docs | Secret từ env `JWT_SECRET` (compose inject); fail-fast khi thiếu; KHÔNG log token |
41
+ | Backward-compat | Greenfield — không consumer hiện hữu ngoài contract | node-svc (SF-2) ghép sau: GET /users/{id} 404 → UNPROCESSABLE |
42
+ | UX | Swagger UI qua host port 8081 | Gateway chỉ route `/api/users/*` có presence-check → swagger KHÔNG truy cập được qua :8080 (giới hạn gateway SF-1, không phải bug SF-3) |
43
+ | Maintenance | mvnw wrapper committed; codegen maven plugin types-only | Local không JDK → mvnw không chạy native; toolchain-in-Docker trong CI là đường chính (đúng brief) |
44
+ | Operational | /healthz liveness + /readyz (Flyway xong + DB query thật); logback LogstashEncoder JSON shape conventions/03; error envelope conventions/04 | Compose entry spring-svc KHÔNG có block `healthcheck` (pre-seed SF-1) → FLAG (mention) cho coordinator, SF-3 không tự sửa |
45
+ | Business | Bước bắt buộc Phase 1 checkpoint | Trễ SF-3 → SF-7 convergence trễ |
46
+
47
+ **Skips có chủ đích**: Performance (demo boilerplate, không SLA), Business (tier position đã chốt ở epic).
48
+
49
+ ## 4. Alternatives (design forks)
50
+
51
+ - **A. Seed bằng SQL tĩnh hardcode id**: nhanh nhưng lệch fixture khi fixture đổi — vi phạm "đọc cùng file". LOẠI.
52
+ - **B. Flyway Java migration đọc `USERS_FIXTURE_PATH` runtime (CHỌN)**: đọc file thật qua mount compose; id khớp theo cấu trúc; test assert DB == fixture. Trade-off: Java migration phức tạp hơn SQL — chấp nhận vì đúng chữ spec.
53
+ - **C. App-level runner (CommandLineRunner) seed**: seed ngoài Flyway = mất idempotent-versioning, /readyz không gate được "seed xong". LOẠI.
54
+ - **JWT verify: jjwt + filter tự viết (CHỌN) vs spring-security-oauth2-resource-server**: 1 secret HS256 + 3 claims — resource server kéo cả security filter chain + config magic; filter ~80 dòng kiểm soát rõ, envelope 401 đúng conventions/04 dễ map. Trade-off ghi ADR trong README (điểm cắm OIDC: đổi filter sang JWKS sau).
55
+
56
+ ## 5. Risks / unknowns
57
+
58
+ | Risk | Mitigation |
59
+ |------|-----------|
60
+ | Không build/test local được (không JDK, không Docker) | Vòng verify = push + watch `gh run watch` (gh auth OK); chi phí mỗi vòng ~5-8 phút → viết test cẩn thận trước, gom commit hợp lý |
61
+ | Flyway Java migration + Hibernate schema resolution trên role search_path | Đã verify init script: `ALTER ROLE spring_svc SET search_path = users` + GRANT USAGE, CREATE |
62
+ | Snapshot users.yaml drift với contracts/ | CI job thêm bước `diff` 2 file — fail nếu lệch |
63
+ | H2 compat cho @SpringBootTest | Tránh rủi ro: CI build-test job dùng **postgres service container** thật (GitHub Actions `services:`); không phụ thuộc H2 |
64
+ | mvnw binary trên Windows | CI chạy Linux; mvnw là shell script chuẩn — không cần .cmd cho CI (kèm luôn mvnw.cmd cho dev có JDK) |
65
+
66
+ ## Verdict
67
+
68
+ GO — scope khớp context pack, không gap cần hỏi lại epic. Direction B+jjwt (mục 4) là lựa chọn
69
+ duy nhất khớp nguyên văn spec slice (seed ĐỌC file fixture; codegen qua maven plugin).
@@ -0,0 +1,27 @@
1
+ # Plan — SF-3 spring-svc — user API (FI-71)
2
+
3
+ > Story FI-62 · spec slice: `docs/superpowers/specs/2026-10-12-sf-3-spring-svc-design.md` · impact: `2026-10-12-sf-3-spring-svc-impact.md` · context: `docs/superpowers/contexts/sf-3.md`
4
+ > Worktree: `__STACK_ORG__/sf-3-spring-svc` (fork từ dest `__STACK_ORG__/story-fi62-micro-boilerplate`) — KHÔNG merge dest, coordinator merge.
5
+ > Tier: Full (9 tasks) · Verify: CI-only (dev machine không Docker/JDK) · Commit: atomic per task, `feat(sf-3): …`
6
+ > Ghi chú verify: Exit "green (CI)" của T1-T8 là **back-verified ở run đầu của T9** (workflow tồn tại từ T9) — không watch-CI per-task ở T1-T8. README T8 thêm ADR: mirror /api/users/healthz là pattern conventions/02 (như auth-mock), probe dùng naked.
7
+
8
+ ## Tasks
9
+
10
+ - [ ] Task 1 — Scaffold: `pom.xml` (Boot 3.5.x Web MVC, Java 21, validation/actuator/data-jpa/flyway+pg/jjwt 0.12/logstash-logback-encoder/springdoc; openapi-generator-maven-plugin spring `interfaceOnly useSpringBoot3` trên snapshot), mvnw wrapper 3.3.x script-only, `application.yml` env fail-fast, snapshot `src/main/resources/openapi/users.yaml` **BIT-IDENTICAL — không thêm comment/header** (provenance ghi README). Exit: codegen + compile green (CI).
11
+ - [ ] Task 2 — `V1__init.sql` (users/teams/team_members — uuid PK, roles text[], snake_case) + entities + Spring Data repos; `ddl-auto: none`. Exit: context boot + repo green trên CI postgres.
12
+ - [ ] Task 3 — `V2__SeedUsers.java` BaseJavaMigration đọc `USERS_FIXTURE_PATH` (Jackson `FAIL_ON_UNKNOWN_PROPERTIES=false` — fixture có `$comment` + JDBC `createArrayOf`), fail-fast thiếu/sai file; **SeedMatchIntegrationTest** — DB == `contracts/auth/users.json` 100% (id/email/displayName/roles); test không transactional. Exit: THE seed exit criterion green.
13
+ - [ ] Task 4 — `JwtVerifier` (jjwt HS256 UTF-8 secret, exp, iss=`auth-mock`) + `JwtAuthFilter` (skip `/healthz`,`/readyz`,`/actuator/**`,`/v3/api-docs/**`,`/swagger-ui/**` + mọi OPTIONS preflight; fail → 401 envelope `UNAUTHORIZED` + requestId). Tests: valid/expired/garbage/missing/wrong-iss + OPTIONS. Exit: 401 TỪ SERVICE green.
14
+ - [ ] Task 5 — Users API **FINAL path table** (contract-resolved: `/api/users/users`, `/api/users/users/{userId}`): list(limit/offset, @Validated 400 ngoài [1,100])/POST(201; **thiếu roles → default ["user"] server-side**; 409 CONFLICT)/GET(200,404)/PATCH(200; 400 body rỗng); `@RestControllerAdvice` envelope (VALIDATION_ERROR/NOT_FOUND/CONFLICT/INTERNAL) + echo `X-Request-Id` + MDC. Tests MockMvc **@Transactional (rollback)**. Exit: users tests green.
15
+ - [ ] Task 6 — Teams API (final paths `/api/users/teams`, `/api/users/teams/{teamId}`): list/POST(name+memberIds, **dedupe trước insert**)/GET kèm memberIds/404. Tests (@Transactional). Exit: teams tests green.
16
+ - [ ] Task 7 — Health/log/CORS: `/healthz` `{"status":"ok"}` naked (hand-written; generated getHealthz mirror); `/readyz` DB thật (503 envelope); actuator liveness probes; logback `LogstashEncoder` (`ts`,`msg`,customFields `service=spring-svc`, MDC requestId, LOG_LEVEL env, **level lowercase qua custom `LowercaseLevelJsonProvider`**); CORS `@Profile("dev")` đọc `CORS_DEV_ORIGIN`. Tests shape. Exit: green.
17
+ - [ ] Task 8 — Swagger (springdoc host-port 8081; api-docs chứa đúng FINAL path table) + Dockerfile multi-stage conventions/01 + `.dockerignore` + README standalone (chạy CI/toolchain, env table, API, ADR: JWT filter tự viết + snapshot bit-identical + fixture evolution V3 + email case-sensitivity). Exit: docker-build pass CI.
18
+ - [ ] Task 9 — CI: `.github/workflows/services-spring-svc.yml` — build-test (mvnw verify + postgres service container **env ĐỦ 4 DB password** + init mount + `USERS_FIXTURE_PATH` + datasource test spring_svc@localhost:5432), docker-build, boot-smoke (compose up postgres+auth-mock+spring-svc+gateway → naked healthz/readyz → login → GET `/api/users/users/{aliceId}` 200 → direct :8081 no-token/garbage → 401), drift-guard diff; **path-filter thêm `contracts/openapi/users.yaml`**; evidence `docs/superpowers/evidence/sf-3/test-run.txt`. Exit: CI 4/4 green.
19
+
20
+ ## Verification (exit criteria — checklist ACCEPTANCE sf-3.md)
21
+
22
+ 1. CI xanh (build-test + docker-build + boot-smoke + drift-guard) — runs trên `__STACK_ORG__/sf-3-spring-svc`.
23
+ 2. Từng dòng ACCEPTANCE `docs/superpowers/contexts/sf-3.md` kiểm riêng (Phase 5 verifier).
24
+ 3. Rule 0: swagger UI + web port — browser verify khi khả thi; không khả thi (no Docker/JDK local) → CI curl evidence + khai báo trung thực trong evidence + nhờ user nhìn thêm.
25
+ 4. Code-reviewer độc lập APPROVED (rolling theo nhóm task 1-3 / 4-7 / 8-9; comment Linear VERDICT + CHECKLIST-4Q).
26
+ 5. `~/.claude/bin/story-verify sf-3` sạch; evidence convention B1+ (hash + `tdd:` line).
27
+ 6. KHÔNG set Linear Done; KHÔNG merge dest; report DONE qua orchestration message + comment FI-71.
@@ -0,0 +1,99 @@
1
+ # Plan: SF-4 go-svc — activity API (Go 1.24 + chi)
2
+ Date: 2026-10-12 | Linear: FI-72 | Worktree: sf-4-go-svc (branch `__STACK_ORG__/sf-4-go-svc`)
3
+ Spec: epic `docs/superpowers/specs/2026-10-12-boilerplate-microservice-mfe.md` rev 3 §SF-4 + context pack `docs/superpowers/contexts/sf-4.md`
4
+ > Rev 2 — sau plan-critic (FIX-P0-FIRST): P0-1 boot-smoke apply canonical DDL bằng role node_svc + negative readyz check; P0-2 compose pre-seed DATABASE_URL sai credentials (platform defect SF-1 — FLAG, không tự sửa; CI dùng override file do SF-4 sở hữu). P1: DAG edge T5←T4; swagger docs auth-exempt + curl boot-smoke; schemathesis kèm JWT (login auth-mock); CI build-test từ T1 (compile feedback sớm); go.sum strategy.
5
+
6
+ ## 0. Root cause analysis (WHY)
7
+
8
+ ### Root cause
9
+ Epic acceptance #3 ("activity phản ánh task vừa tạo") chưa có service nào sở hữu activity: node-svc mutate task nhưng không nơi nào ghi nhận event, và stats phải đọc data do service KHÁC sở hữu (schema `tasks` của node-svc) — cần chứng minh multi-repo convention hoạt động xuyên DB permission boundary (readonly role).
10
+
11
+ ### Current state (before feature)
12
+ `services/go-svc/` chỉ có README placeholder. Compose entry `go-svc` đã pre-seed (SF-1) — build fail đến khi có code. Postgres init đã tạo sẵn schema `activity` + role `go_svc` (owner) + `go_readonly` (SELECT qua ALTER DEFAULT PRIVILEGES FOR ROLE node_svc).
13
+
14
+ ### Expected outcome
15
+ POST /activity/events nhận event fire-and-forget từ node-svc → feed hiển thị kèm user-display fields (userName, taskTitle) → stats phản ánh đúng rows `tasks` (seed bằng owner role). CI xanh: build + test + docker build + boot-smoke.
16
+
17
+ ### Constraints & hardships
18
+ - Dev machine KHÔNG Docker, KHÔNG Go toolchain → mọi verify (go test, docker build, boot-smoke) qua CI.
19
+ - KHÔNG sửa compose/contracts/conventions; KHÔNG migrate schema `tasks`; KHÔNG message broker.
20
+ - go_readonly CHỈ có SELECT schema `tasks` — userName phải resolve qua spring-svc REST (init script chốt).
21
+ - ALTER DEFAULT PRIVILEGES chỉ hiệu lực cho bảng do `node_svc` tạo → test seed phải chạy DDL bằng role `node_svc`, không phải superuser.
22
+
23
+ ### High-level strategy
24
+ Single Go module `services/go-svc`, chi router, layering: `cmd/server` → `internal/{config,logging,auth,store,api}`. Migration SQL embedded, chạy lúc boot. Test strategy: unit (httptest, không DB) local-nếu-có / chắc chắn CI; integration (đụng Postgres) chạy trong CI job với postgres service container; contract (schemathesis) trong boot-smoke job. Execute inline (Go tests chỉ CI-bound — dispatch subagent không thêm khả năng verify), review rolling theo nhóm.
25
+
26
+ ## 1. Problem (intent)
27
+ Dev copy boilerplate cần service Go mẫu hoàn chỉnh: nhận event, serve feed/stats đúng contract `contracts/openapi/activity.yaml`, tự verify JWT, chứng minh readonly-read hoạt động — không phải tự nghĩ lại từ đầu.
28
+
29
+ ## 2. Scope
30
+ - **In scope**: scaffold go-svc; feed/stats/events endpoints; migration schema `activity`; JWT verify; healthcheck; slog JSON; error envelope; CORS dev; tests (unit + integration readonly-exit + contract); Dockerfile multi-stage distroless; boot-smoke CI job; swagger-ui static serve spec; README standalone.
31
+ - **Out of scope**: node/spring/FE impl; schema `tasks` migration; compose/contracts/conventions sửa; message broker; k8s; UI thật (SF-6).
32
+ - **Success criteria (observable, từ context pack ACCEPTANCE)**:
33
+ 1. Swagger-ui go-svc mở được; POST event → event hiện trong feed.
34
+ 2. Stats đúng rows seeded bằng owner role `node_svc` (canonical DDL).
35
+ 3. Negative: không có readonly grant → query tasks fail rõ ràng (503 `DEPENDENCY_DOWN` envelope).
36
+ 4. Token sai/hết hạn → 401 từ go-svc (không phụ thuộc gateway).
37
+ 5. CI xanh: build-test (go vet + unit + integration với postgres) + docker-build + boot-smoke (up + health + migration xong + schemathesis).
38
+
39
+ ## 3. Touch map
40
+ - **Modify/create**: `services/go-svc/**` (SỞ HỮU — module, cmd, internal, test, Dockerfile, README); `.github/workflows/services-go-svc.yml` (tạo từ template); `docs/superpowers/evidence/sf-4-go-svc/test-run.txt`.
41
+ - **Consumers/regression**: node-svc (SF-2 — POST /events contract), FE remote activity (SF-6 — feed/stats shape), SF-7 smoke.
42
+ - **Shared surfaces (READ-ONLY)**: `contracts/openapi/activity.yaml`, `contracts/db/tasks-schema.sql`, `platform/docker-compose.yml` (entry pre-seed env: PORT, DATABASE_URL, DATABASE_READONLY_URL, JWT_SECRET, SPRING_SVC_URL, CORS_DEV_ORIGIN, LOG_LEVEL), `platform/conventions/*`, `platform/postgres/init/01-init.sh`.
43
+
44
+ ## 4. Design
45
+ - **Approach A (chọn)**: swagger-ui-dist vendored + `go:embed` + bản copy spec `internal/api/openapi/activity.yaml` (sync-check test). Offline hoàn toàn, distroless-compatible. Alternative B (CDN html) dismissed: phụ thuộc internet lúc demo, lệch "static serve".
46
+ - **userName resolution**: resolve lúc ingest + lúc đọc, best-effort: spring-svc `GET /api/users/{userId}` (display name), timeout ngắn (2s), cache in-memory TTL; khi spring down → trả `""` (degraded trung thực, không bịa placeholder — ADR ghi README). taskTitle: `SELECT title FROM tasks.tasks WHERE id=$1` bằng readonly connection; bảng chưa có → `""`.
47
+ - **Stats**: 2 query readonly: `COUNT(*)` + `GROUP BY status` trên `tasks.tasks`; `recentEvents` = COUNT events 24h qua (schema activity, owner conn). tasks unreadable (permission/bảng chưa có) → 503 `DEPENDENCY_DOWN` envelope.
48
+ - **JWT**: `golang-jwt/jwt/v5`, HS256, verify signature + `exp` + `iss=auth-mock`; fail → 401 `UNAUTHORIZED` envelope.
49
+ - **Migration**: embedded SQL (`schema activity` đã có từ init — migration tạo `activity.events`: id uuid app-generated, task_id, user_id, action CHECK enum, event_ts timestamptz, user_name, task_title, created_at). Idempotent runner (migrations table + applied tracking).
50
+ - **Fire-and-forget ingest**: validate payload theo ActivityEventInput (uuid, action enum 3 giá trị, RFC3339 timestamp) → persist inline → 202 `{"accepted":true}`. node-side không retry là trách nhiệm node-svc.
51
+ - **Edge cases**: event trùng (re-push) → chấp nhận (idempotent-friendly: không dedupe — node không retry nên trùng hiếm; log info); limit clamp 1..100; offset ≥0; spring timeout; tasks table missing; readyz = migration xong + SELECT probe tasks (fail → 503).
52
+ - **Non-functional**: port 8082 env `PORT`; healthcheck naked `/healthz`+`/readyz` ngoài prefix `/api/activity`; request slog JSON (ts/level/service/msg/requestId); requestId từ `X-Request-Id`; CORS `rs/cors` đọc `CORS_DEV_ORIGIN` (rỗng = deny-by-default); non-root distroless.
53
+
54
+ ## 5. Implementation outline
55
+
56
+ ### Tasks (ordered — DAG)
57
+ | # | Task | Deps |
58
+ |---|------|------|
59
+ | T1 | Scaffold: go.mod 1.24 (chi v5.3.2, golang-jwt v5.3.1, rs/cors), cmd/server, internal/config (env fail-fast), slog JSON logging, chi router (prefix `/api/activity` + naked health), requestId + error-envelope + CORS middleware, `/healthz`, Dockerfile distroless (conventions/01; `COPY go.mod go.sum*` + `go mod download` tự sinh go.sum in-image — dev không có Go), **+ CI workflow tối thiểu (build-test: setup-go + vet + test) cho compile feedback ngay từ commit đầu** | — |
60
+ | T2 | JWT middleware (golang-jwt/jwt/v5 HS256: sig+exp+iss) + 401 envelope + unit tests (missing/bad-sig/expired/wrong-iss/valid) | T1 |
61
+ | T3 | Embedded migration runner + `activity.events` table (app uuid v4, CHECK action enum) + `/readyz` (migration xong + readonly SELECT probe tasks → 503 envelope khi fail) + unit tests | T1 |
62
+ | T4 | POST `/events`: validation theo activity.yaml + persist + 202 EventAccepted; display-field resolver (spring REST client timeout 2s + cache TTL; taskTitle readonly lookup) + unit tests (httptest fake spring) | T2, T3 |
63
+ | T5 | GET `/feed` (limit/offset clamp, mới nhất trước, total) + GET `/stats` (COUNT + GROUP BY status readonly + recentEvents 24h; 503 DEPENDENCY_DOWN khi tasks unreadable) + repository layer + unit tests — **tiêu thụ resolver interface từ T4** | T3, T4 |
64
+ | T6 | Swagger-ui: vendored swagger-ui-dist (go:embed, Apache-2.0 license note) + spec copy `internal/api/openapi/activity.yaml` + sync-check test vs contracts + serve `/api/activity/docs` + `/api/activity/openapi.yaml` — **auth-exempt (tiền lệ auth-mock `/api/auth/docs` mở)** | T1 |
65
+ | T7 | Integration tests (CI postgres service): readonly-exit criterion — apply canonical DDL + seed bằng role `node_svc` → stats đúng (assert `tableowner='node_svc'`); REVOKE SELECT → 503 → re-grant; POST event → feed chứa event; 401 paths | T4, T5 |
66
+ | T8 | CI workflow `.github/workflows/services-go-svc.yml`: build-test (setup-go 1.24 + postgres service + go vet/test), docker-build, boot-smoke — **(P0-1) apply `contracts/db/tasks-schema.sql` bằng role `node_svc` (`docker compose exec -T postgres psql -U node_svc`) + seed trước khi boot go-svc; negative check: boot trước DDL → readyz 503 (chứng minh probe thật) → apply DDL → readyz 200**; **(P0-2) dùng compose override file `services/go-svc/ci.compose.override.yml` (SF-4 sở hữu) sửa DATABASE_URL=`go_svc:` / DATABASE_READONLY_URL=`go_readonly:` — KHÔNG đụng platform/docker-compose.yml, FLAG SF-1 fix gốc**; curl `/healthz`+`/readyz` + migration xong + POST event→feed + curl `/api/activity/docs`+`/openapi.yaml` 200; schemathesis activity.yaml **kèm JWT** (login auth-mock :8090 direct, header Authorization; venv deterministic + base-url kèm prefix `/api/activity` — 2 bài học SF-1 contracts.yml); path-filter thêm `platform/postgres/init/**`; optional: curl gateway :8080/api/activity → 401 envelope | T6, T7 |
67
+ | T9 | README standalone (chạy native, env, contract links, ADR degraded userName) + evidence `test-run.txt` (CI run URL + hash) + push + CI xanh | T8 |
68
+
69
+ ### File structure (mới)
70
+ ```
71
+ services/go-svc/
72
+ ├── cmd/server/main.go
73
+ ├── internal/
74
+ │ ├── config/config.go
75
+ │ ├── logging/logging.go
76
+ │ ├── auth/jwt.go
77
+ │ ├── store/{migrate.go,migrations/0001_events.sql,events.go,readback.go}
78
+ │ ├── resolve/resolver.go (spring REST + cache)
79
+ │ ├── api/{router.go,middleware.go,health.go,events.go,feed.go,stats.go,
80
+ │ │ envelope.go,openapi/activity.yaml,openapi_test.go}
81
+ │ └── swagger/{index.html,dist/... (vendored),swagger.go}
82
+ ├── test/integration/… (build tag integration — chạy CI)
83
+ ├── Dockerfile
84
+ ├── .dockerignore
85
+ └── README.md
86
+ .github/workflows/services-go-svc.yml
87
+ ```
88
+
89
+ ### Testing strategy
90
+ - Unit (go test, không DB): config fail-fast, jwt middleware, validation, envelope, resolver (httptest fake spring), feed/stats handlers với sqlmock-free fake store.
91
+ - Integration (CI, postgres service container + init script): readonly-exit criterion (seed `node_svc` → stats đúng; REVOKE → 503), ingest→feed roundtrip, 401.
92
+ - Contract (CI boot-smoke): schemathesis `contracts/openapi/activity.yaml` (pattern SF-1).
93
+ - Docker: CI docker-build + boot-smoke compose up thật.
94
+
95
+ ## 6. Risks & unknowns
96
+ - **Must verify**: go_readonly grant hiệu lực qua bảng do node_svc tạo (CI test T7 chứng minh); schemathesis hoạt động với activity.yaml kèm JWT (SF-1 precedent auth.yaml + contracts.yml lessons).
97
+ - **Resolved during planning**: (1) swagger-ui-dist 5.17.14 tải OK từ npm registry (verified); (2) spring display-name field = `User.displayName` (users.yaml required) — no longer unverified; (3) go.sum không sinh được local → Dockerfile `go mod download` tự sinh in-image + CI `go mod tidy` (lệch nhỏ conventions/01 template, ghi chú README).
98
+ - **FLAG đã post (P0-2)**: compose pre-seed `DATABASE_URL`/`DATABASE_READONLY_URL` dùng user `${POSTGRES_USER}` + password per-role → auth fail chắc chắn (affects SF-2 node-svc cùng pattern). SF-4 không tự sửa compose (boundary) — dùng override file `services/go-svc/ci.compose.override.yml` cho CI của mình + REQUIREMENT-GAP comment epic FI-62 để SF-1/coordinator fix gốc.
99
+ - Go/docker không có local: mọi red-green loop qua CI push — build-test job chạy từ T1 để compile feedback sớm; budget CI runs cẩn thận.
@@ -0,0 +1,64 @@
1
+ # Plan: SF-5 FE shell — MF host (Rspack)
2
+ Date: 2026-10-12 | Linear: FI-73 | Worktree: __STACK_ORG__/sf-5-fe-shell | Story: FI-62
3
+
4
+ ## 0. Root cause analysis (WHY)
5
+
6
+ ### Root cause
7
+ Boilerplate epic cần FE entry-point: shell là MF host duy nhất — remotes (SF-6) không tự đứng, load vào host. Không có host = epic acceptance #1 (mở shell → login → nav + 2 remote render) không thể demo.
8
+
9
+ ### Current state (before feature)
10
+ SF-1 đã merge: `frontend/shared` (api-client, token-storage, mf-bootstrap), spike MF đã test pin versions (evidence PNG), compose PRE-SEED khung (FE entries CHƯA có — gap flag), gateway routing `/` → `shell:3000` (502 đến khi shell tồn tại).
11
+
12
+ ### Expected outcome
13
+ `frontend/shell/` chạy dev native :3000 → login fixture user qua gateway `/api/auth/login` → nav + layout; route `/tasks` `/activity` hiện fallback remote-down (SF-5 standalone, remote chưa có); vitest pass (focus + skip-link + login); CI xanh (build + tests + boot-smoke).
14
+
15
+ ### Constraints & hardships
16
+ - fe-shared/catalog/compose/contracts READ-ONLY — thiếu gì = FLAG, không tự sửa.
17
+ - Không Docker trên dev machine — verify docker qua CI.
18
+ - Pin matrix bắt buộc: react 19.3.0, rspack 1.7.12, mf-enhanced 0.21.6 (nâng cấp = re-spike).
19
+ - SF-6 chạy SONG SONG — không cướp `pnpm-lock.yaml` semantics (commit bình thường, coordinator resolve).
20
+
21
+ ### High-level strategy
22
+ Scaffold host từ pattern spike đã test (async boundary `import('./bootstrap')`, automatic JSX runtime), đóng gói remote loading qua `loadRemoteModule` + error boundary, routing react-router với lazy remote slots. Không design system — UI tối giản sạch.
23
+
24
+ ## 1. Problem
25
+ Dev team copy boilerplate cần shell demo được login + nav ngay khi mở — không có shell thì toàn bộ FE demo epic sập từ cửa vào.
26
+
27
+ ## 2. Scope
28
+ - **In scope:** scaffold `frontend/shell/` (Rspack + MF host + React 19 + TS + pnpm); re-validation spike + fe-shared fit-check (task đầu); catalog singleton deps; routing + layout + nav (`/`, `/tasks`, `/activity`); login qua fe-shared; a11y baseline CÓ TEST (route focus + skip link); error boundary + fallback remote-down; vitest + testing-library; Dockerfile nginx static; boot-smoke CI job; README; compose entry gap → FLAG (không tự sửa).
29
+ - **Out of scope:** implement remote apps (SF-6); sửa fe-shared/catalog/compose/contracts; design system phức tạp; docker local; i18n.
30
+ - **Success criteria (observable):** ACCEPTANCE trong `docs/superpowers/contexts/sf-5.md` — từng dòng verify + BROWSER VERIFY Rule 0 (login thật fixture user + nav + fallback remote-down, screenshot bằng chứng).
31
+
32
+ ## 3. Touch map
33
+ - **Tạo:** `frontend/shell/**` (src, rspack.config.mjs, package.json, tsconfig, index.html, Dockerfile, nginx.conf, README.md, vitest config + tests), `.github/workflows/shell.yml`, evidence `docs/superpowers/evidence/sf-5-fe-shell/`.
34
+ - **READ-ONLY:** `frontend/shared/**`, `pnpm-workspace.yaml`, `platform/docker-compose.yml`, `platform/conventions/*`, `platform/.env.example`, `contracts/**`.
35
+ - **Shared-regen:** `pnpm-lock.yaml` (cả SF-6).
36
+ - **Consumers:** SF-6 (remotes load vào host này), gateway `/` route, CI pipeline.
37
+
38
+ ## 4. Design
39
+ - **Approach:** host = Rspack + `ModuleFederationPlugin` (name `shell`), entry async boundary (`index.tsx` → `import('./bootstrap')` — bài học spike RUNTIME-006 loadShareSync), remote slots lazy-load qua `loadRemoteModule` (fe-shared) + React error boundary per route, remote URLs inject build-time qua DefinePlugin (`__REMOTE_URLS__`), fallback prod `/remotes/<name>/remoteEntry.js` (fe-shared `resolveRemoteUrl` đã handle).
40
+ - **Alternatives dismissed:** (A) hardcode remote URL — vi phạm conventions/08 rule 1; (B) static import remote — mất runtime fallback remote-down; (C) Vite-MF — epic chốt Rspack, KHÔNG trộn bundler.
41
+ - **Edge cases:** remote down giữa session (error boundary + retry button); token hết hạn (fe-shared `isExpired` → clear + redirect login); login sai (error envelope decode → hiện lỗi); refresh trang giữ login (localStorage persist).
42
+ - **Non-functional:** a11y (route focus management + skip link — CÓ TEST vitest); security (JWT không verify phía FE — chỉ decode claims hiển thị, verify là việc BE); perf (singleton react qua catalog + shared config MF).
43
+
44
+ ## 5. Implementation outline
45
+ - **File structure:** `frontend/shell/src/` (index.tsx, bootstrap.tsx, App.tsx, routes, components/{Layout,NavBar,LoginPage,RemoteSlot,ErrorBoundary}), `frontend/shell/tests/`, config files root của `frontend/shell/`.
46
+ - **Testing strategy:** vitest + @testing-library/react — unit (login flow mocked api, token lưu), a11y (route focus + skip link), error boundary (remote reject → fallback UI). Boot-smoke = CI (static serve + 200). BROWSER VERIFY Rule 0 = walkthrough thật bằng mắt + screenshot.
47
+
48
+ ### Tasks (9 — ordered, DAG)
49
+ | # | Task | Deps |
50
+ |---|------|------|
51
+ | 1 | Re-validation spike + fe-shared fit-check (pin còn đúng? export đủ dùng? lệch = FLAG ngay) | — |
52
+ | 2 | Scaffold `frontend/shell/` — Rspack + MF host + React 19 + TS + catalog singletons, chạy được hello shell :3000 | 1 |
53
+ | 3 | Routing + layout + nav (`/`, `/tasks`, `/activity`) + route focus + skip link; tạo sẵn route `/login` stub + Layout mount (chống đụng file với T4); **kèm a11y vitest riêng (route focus + skip link)** | 2 |
54
+ | 4 | **Chỉ `LoginPage.tsx` + login vitest riêng** (mocked api + token persist); dev API base = env `API_BASE_URL` default `http://localhost:8090` (auth-mock trực tiếp — native không có gateway, conventions/05 rule 3 + CORS 07: auth-mock luôn mở dev origin); prod = same-origin `""` qua gateway `/api/auth/login` | 2 |
55
+ | 5 | Remote slots + error boundary + fallback remote-down + retry; **kèm error-boundary vitest riêng** | 3 |
56
+ | 6 | Suite-green toàn bộ + 1 integration test cross-cutting (login → nav → remote-down fallback) | 3,4,5 |
57
+ | 7 | Dockerfile (nginx static) + nginx.conf + README `frontend/shell/` | 2 |
58
+ | 8 | CI `shell.yml` — build + tests + boot-smoke static (up + 200) | 6,7 |
59
+ | 9 | BROWSER VERIFY Rule 0 walkthrough + screenshot evidence + ACCEPTANCE line-by-line + verifier. Tiền tố walkthrough: start auth-mock native :8090 (fixture user + dev password). DONE report phải chứa FLAG: compose thiếu entry `shell` (claim pre-seed sai) — owner: coordinator/SF-7; SF-5 không đụng compose | 8 |
60
+
61
+ ## 6. Risks & unknowns
62
+ - **Must verify (Task 1):** pin versions còn cài được; fe-shared export đủ (ApiClient, tokenStorage, readClaims, isExpired, loadRemoteModule, resolveRemoteUrl, REMOTE_NAMES) cho mọi nhu cầu shell.
63
+ - **Gap đã phát hiện (Phase 0):** compose CHƯA có entry `shell` (comment compose nói pre-seed riêng, context pack nói đã pre-seed) → FLAG coordinator, KHÔNG tự sửa. Boot-smoke CI không phụ thuộc compose (serve static trực tiếp).
64
+ - **Unverified assumption:** auth-mock contract `/api/auth/login` request/response shape — đọc `contracts/openapi/auth.yaml` trước khi code Task 4.
@@ -0,0 +1,83 @@
1
+ # Plan: SF-6 FE remotes — tasks + activity (FI-74)
2
+ Date: 2026-10-12 | Linear: FI-74 | Worktree: __STACK_ORG__/sf-6-fe-remotes | Story: FI-62
3
+ Spec slice: docs/superpowers/specs/2026-10-12-boilerplate-microservice-mfe.md rev 3 §SF-6 | Context pack: docs/superpowers/contexts/sf-6.md
4
+
5
+ ## 0. Root cause analysis (WHY)
6
+
7
+ ### Root cause
8
+ Shell (SF-5) đã merge với 2 remote slots trống (`RemoteSlot` load registry `tasks`/`activity`). BE thật đã có (node-svc/spring-svc/go-svc Done). Epic acceptance #1/#2/#3 (remote render → tạo task qua node-svc → feed phản ánh qua go-svc) chết ở chỗ: KHÔNG có remote app nào để fill slot.
9
+
10
+ ### Current state (before feature)
11
+ - Shell :3000 expose `/tasks` `/activity` qua `RemoteSlot name={tasks|activity} exposedModule={./TasksPage|./ActivityPage}` + error boundary remote-down (evidence sf-5: `04-tasks-remote-down.png`).
12
+ - fe-shared (READ-ONLY): `ApiClient` (JWT + envelope decode), `tokenStorage`, `resolveRemoteUrl`, `loadRemoteModule`, `REMOTE_NAMES`.
13
+ - Compose PRE-SEED: entry `shell` có (SF-5 gap-answer), **remote-tasks/remote-activity CHƯA có** — BRIEF ủy quyền SF-6 tự thêm đúng 2 entry.
14
+ - Conventions: port table (4001/4002), registry (expose `./TasksPage`/`./ActivityPage`), CORS dev, error envelope, Dockerfile pattern.
15
+ - Catalog: react 19.3.0 / react-dom 19.3.0 / react-router ^7.9.0 / mf-enhanced 0.21.6 / rspack 1.7.12.
16
+
17
+ ### Expected outcome
18
+ 2 remote chạy dev native :4001/:4002, load vào shell qua slot; `/tasks` CRUD qua `/api/tasks` (node-svc thật, JWT, validate user qua spring thật); `/activity` feed + stats qua `/api/activity` (go-svc thật); vitest pass cả 2; CI xanh (build + test + boot-smoke: up + 200 + fetch được remoteEntry.js); compose có 2 entry remote.
19
+
20
+ ### Constraints & hardships
21
+ - READ-ONLY: shell/fe-shared/catalog/compose (trừ 2 entry remote)/contracts/conventions — đụng khác = FLAG.
22
+ - KHÔNG Docker trên dev machine — verify docker qua CI; local demo native.
23
+ - KHÔNG thêm remote thứ 3.
24
+ - Pin matrix bắt buộc (nâng cấp = re-spike): react 19.3.0, rspack 1.7.12, mf-enhanced 0.21.6.
25
+ - Rule 0 BROWSER VERIFY: tự thấy login → tạo task (node-svc thật) → feed phản ánh (go-svc thật) — screenshot làm bằng chứng, KHÔNG tự kết luận từ DOM query.
26
+ - Linear rate-limited (39 ops queue) — sync qua linear-rate-limit runner, flush khi hết limit.
27
+
28
+ ### High-level strategy
29
+ Clone pattern đã-test (spike remote + shell config) × 2 remote apps; UI tối giản (list + form + inline error, cùng class shell dùng); API layer mỏng bọc fe-shared ApiClient; singleton qua catalog:; tests vitest + testing-library mirror shell suite; Dockerfile/nginx/CI mirror shell.
30
+
31
+ ## 1. Problem
32
+ Dev team copy boilerplate cần chứng minh micro-frontend + microservice chạy xuyên được: remote render trong host và gọi service thật qua gateway — không có remote thì epic chỉ là host trống.
33
+
34
+ ## 2. Scope
35
+ - **In scope:** scaffold `frontend/remotes/tasks/` + `frontend/remotes/activity/` (Rspack + MF REMOTE + React 19 + TS, catalog: refs); tasks remote: list + tạo/sửa qua `/api/tasks` + JWT + error envelope → inline error; activity remote: feed + stats qua `/api/activity`, render userName/taskTitle từ response; shared singletons đúng MF 2.0; vitest per remote (component + api mocked); Dockerfile nginx static + nginx.conf + README standalone ×2; boot-smoke CI per remote; compose điền 2 entry pre-seed (gap-answer); BROWSER VERIFY Rule 0 e2e thật + evidence.
36
+ - **Out of scope:** service-side (SF-2/3/4 Done); sửa shell/fe-shared/catalog/contracts/conventions; remote thứ 3; docker local; i18n; OIDC thật.
37
+ - **Success criteria:** từng dòng ACCEPTANCE trong `docs/superpowers/contexts/sf-6.md` verify được + browser flow e2e thật có screenshot + TESTER REVIEW ĐỘC LẬP materialize `/tmp/story/fi62/code-reviewer-sf-6-fe-remotes.md` (VERDICT: APPROVED) + `story-verify sf-6` sạch B1-B3.
38
+
39
+ ## 3. Touch map
40
+ - **Tạo (SỞ HỮU):** `frontend/remotes/tasks/**`, `frontend/remotes/activity/**`, `.github/workflows/remotes-tasks.yml`, `.github/workflows/remotes-activity.yml`, evidence `docs/superpowers/evidence/sf-6-fe-remotes/`.
41
+ - **Đụng có chủ (gap-answer ủy quyền BRIEF):** `platform/docker-compose.yml` — CHỈ thêm 2 entry `remote-tasks`/`remote-activity` (mirror entry `shell`: context repo root, healthcheck wget static).
42
+ - **READ-ONLY:** `frontend/shell/**`, `frontend/shared/**`, `pnpm-workspace.yaml`, `contracts/**`, `platform/conventions/*`, `platform/.env.example`, `platform/gateway/**`.
43
+ - **Shared-regen:** `pnpm-lock.yaml` (chung SF-5 — commit bình thường, coordinator resolve khi merge).
44
+ - **Consumers:** shell slots (registry :4001/:4002, expose names), gateway `/remotes/<name>/` route, CI, SF-7 e2e smoke.
45
+
46
+ ## 4. Design
47
+ - **Approach:** mỗi remote = app Rspack + `ModuleFederationPlugin` (name `tasks`/`activity`, `filename: remoteEntry.js`, `exposes: {'./TasksPage'|'./ActivityPage'}`), `shared: {react, react-dom singleton}` với deps `catalog:`; standalone `index.html` + entry (dev mở trực tiếp :4001/:4002 debug được); page component nhận API base qua DefinePlugin `__API_BASE_URL__` (dev native: `http://localhost:3001`|`:8082`; prod: `''` same-origin qua gateway) — mirror shell `src/api.ts`; UI: list + form + inline error, tái dùng class `error-banner` phong cách shell; `publicPath` tuyệt đối dev (`http://localhost:4001/` — bài học spike) , prod relative `/remotes/<name>/`. **Remotes KHÔNG import react-router** (shell chỉ share react/react-dom — remote cần router hook thì phải thêm vào shared, tránh trùng instance; cả 2 trang đều không cần routing nội bộ).
48
+ - **Alternatives dismissed:** (A) hardcode URL API — vi phạm conventions/06; (B) 1 app 2 expose — phá registry/port table/boot-smoke per remote; (C) remote tự quản token — trùng tokenStorage, remote render trong shell nên cùng origin localStorage; (D) fetch raw thay fe-shared ApiClient — mất envelope decode + JWT, vi phạm spec slice mục 3.
49
+ - **Edge cases:** task title rỗng/>200 (client-side chặn + server 400 envelope → inline); node-svc 503 (spring down khi validate) → error message từ envelope; feed rỗng → empty state; stats lỗi → inline error, feed vẫn render; remote dev server đứng một mình (standalone index.html báo "chạy trong shell"); 1 remote down trong shell → error boundary shell-side + remote kia vẫn chạy (walkthrough test).
50
+ - **Non-functional:** a11y (label form, role=alert cho error — mirror shell); security (JWT không verify FE; không secret mới; title escape qua React mặc định); perf (singleton react, lazy remote từ shell-side); maintenance (2 remote cùng pattern, README standalone copy kèm fe-shared).
51
+
52
+ ## 5. Implementation outline
53
+ - **File structure:** `frontend/remotes/<name>/` = `src/{index.tsx (standalone entry), bootstrap.tsx, api.ts, <Name>Page.tsx, components/*}`, `tests/*`, `rspack.config.mjs`, `package.json`, `tsconfig.json`, `index.html`, `vitest.config.ts`, `Dockerfile`, `nginx.conf`, `README.md`.
54
+ - **Testing strategy:** vitest + @testing-library/react mirror shell — mock fe-shared ApiClient (component test) + assert api call shape (api layer test); boot-smoke = CI docker (up + 200 + remoteEntry.js fetch). BROWSER VERIFY Rule 0 = walkthrough thật + screenshot.
55
+
56
+ ### Tasks (10 — ordered, DAG)
57
+ | # | Task | Deps |
58
+ |---|------|------|
59
+ | 1 | Fit-check + probes: fe-shared exports đủ cho remote; đọc conventions 04/06/07 + shell nginx/Dockerfile pattern; **probe workspace-glob gap** (empirical: `pnpm m ls` sau scaffold thử nghiệm) → nếu gap thật: REQUIREMENT-GAP comment FI-62 + gap-answer 1 dòng globs (FLAG coordinator duyệt, không đụng catalog); **probe ĐỦ toolchain e2e (plan-critic P0-1): Postgres :5432 + `java`/JDK 21 (spring-svc mvnw) + `go` (go-svc) + node dev-scripts node-svc/auth-mock** — thiếu → cài portable user-local (~/Tools/sf6-e2e, không admin, xoá-là-sạch) + ghi escalation nếu vẫn thiếu | — |
60
+ | 2 | Scaffold `frontend/remotes/tasks/` — Rspack + MF remote + catalog singletons + standalone entry; dev :4001 hello page chạy được; workspace membership xanh | 1 |
61
+ | 3 | Tasks feature: api layer (list/create/update qua fe-shared ApiClient) + TasksPage UI (list + tạo + sửa status) + inline error envelope | 2 |
62
+ | 4 | Vitest `frontend/remotes/tasks` — component (mocked api) + api call shape | 3 |
63
+ | 5 | Scaffold `frontend/remotes/activity/` + api layer (feed/stats) + ActivityPage UI (feed render userName/taskTitle + stats tiles) | 2 |
64
+ | 6 | Vitest `frontend/remotes/activity` — component (mocked api) + api call shape | 5 |
65
+ | 7 | Dockerfile ×2 (nginx static, context repo root) + nginx.conf ×2 + README standalone ×2 | 4,6 |
66
+ | 8 | CI `remotes-tasks.yml` + `remotes-activity.yml` — typecheck + vitest + build + boot-smoke (up + 200 + fetch remoteEntry.js) | 7 |
67
+ | 9 | Compose: thêm ĐÚNG 2 entry `remote-tasks`/`remote-activity` (mirror `shell`, healthcheck wget static) — gap-answer BRIEF ủy quyền | 7 |
68
+ | 10 | E2E BROWSER VERIFY Rule 0: start native (postgres + auth-mock + node-svc + spring + go-svc + shell + 2 remotes) → login → tạo task → feed/stats phản ánh → remote-down case; screenshot evidence + ACCEPTANCE line-by-line + test-run.txt; TESTER REVIEW ĐỘC LẬP (code-reviewer → OUTBOX `/tmp/story/fi62/code-reviewer-sf-6-fe-remotes.md`) | 3,5,8,9 |
69
+
70
+ ## 6. Risks & unknowns
71
+ - **[plan-critic P0-2 — GIẢI QUYẾT] Mâu thuẫn "qua gateway" vs native:** spec-slice mục 2 nói "native không cần CORS mở (dev proxy)" + ACCEPTANCE nói "qua gateway", NHƯNG conventions/07:5-7 + shell precedent (`API_BASE_URL` dev = service trực tiếp) + BRIEF.md:8 đều chốt native = gọi thẳng service port với CORS dev mở; gateway nginx KHÔNG chạy native được (không Docker). **Interpretation ghi REQUIREMENT-GAP FI-62:** e2e native của SF-6 đi thẳng service theo conventions/07; chân "qua gateway" do CI compose + SF-7 e2e smoke bảo chứng. KHÔNG tự sửa spec/conventions.
72
+ - **Workspace glob gap (Phase 0, plan-critic P1):** `frontend/remotes/*` KHÔNG có trong globs → `catalog:` protocol cần membership nên gap này là binary. Giải pháp gap-answer: thêm đúng 1 dòng globs (KHÔNG đụng catalog) + FLAG coordinator duyệt — nếu coordinator từ chối → toàn bộ singleton strategy phải rework, báo dừng.
73
+ - **Toolchain e2e (plan-critic P0-1):** máy KHÔNG có Java/Go/Postgres/Docker. Node-svc fail-closed 503 khi spring down → Rule 0 bắt buộc spring thật. Giải pháp: portable toolchain user-local `~/Tools/sf6-e2e/` (Temurin JDK 21 + Go 1.24 + Postgres 16 binaries — không admin, xoá-là-sạch); spring chạy qua `mvnw` (tự tải Maven); escalation nếu mvnw/JDK lệch version spring-svc yêu cầu → REQUIREMENT-GAP.
74
+ - **shell Dockerfile ảnh hưởng ở MERGE (coordinator):** lockfile mới có 2 importer `frontend/remotes/*` → Dockerfile shell (COPY từng package.json importer) cần thêm 2 dòng COPY khi merge — FLAG trong REQUIREMENT-GAP, SF-6 KHÔNG tự sửa.
75
+ - **Lockfile xung đột SF-5:** dự liệu sẵn — commit bình thường.
76
+ - **Assumption phải verify bằng đọc:** nginx.conf shell pattern (SPA fallback cho `/remotes/<name>/` static), 07-cors.md (CORS_DEV_ORIGIN set đúng khi start service native), Dockerfile-pattern conventions.
77
+
78
+ ### T10 preflight checklist (plan-critic P1 — bắt buộc trước khi start e2e)
79
+ 1. `CORS_DEV_ORIGIN=http://localhost:3000,http://localhost:4001,http://localhost:4002` trên node-svc + go-svc (+ spring).
80
+ 2. **CÙNG MỘT `JWT_SECRET`** cho auth-mock + node-svc + spring-svc + go-svc (services tự verify — lệch secret = 401 toàn bộ).
81
+ 3. Postgres roles/passwords đúng `.env.example` + init script SF-1 chạy trước migration.
82
+ 4. Thứ tự boot: postgres → spring → node-svc → go-svc → auth-mock → shell → 2 remotes.
83
+ 5. CI/boot-smoke exit criteria = structural mirror `shell.yml` (CI xanh quan sát ở story-level sau push — không Docker local).