create-wakii-stack 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -2
- package/dist/chunk-7XGW4UJ5.js +75 -0
- package/dist/chunk-AKPWS7FJ.js +76 -0
- package/dist/chunk-ELM6GGC5.js +50 -0
- package/dist/chunk-ON2WTGZH.js +77 -0
- package/dist/index.js +385 -0
- package/dist/manifest-2JVLRMDB.js +10 -0
- package/dist/manifest-O35TPW73.js +10 -0
- package/dist/manifest-TXTY67BF.js +10 -0
- package/dist/manifest-XWHR7Y3F.js +10 -0
- package/package.json +23 -4
- package/stack-template/.changeset/config.json +15 -0
- package/stack-template/.changeset/vu53-ui-redesign.md +11 -0
- package/stack-template/.claude/agents/be-dev.md +56 -0
- package/stack-template/.claude/agents/contracts-keeper.md +51 -0
- package/stack-template/.claude/agents/e2e-runner.md +61 -0
- package/stack-template/.claude/agents/fe-dev.md +53 -0
- package/stack-template/.claude/settings.json +77 -0
- package/stack-template/.claude/settings.local.json +9 -0
- package/stack-template/.claude/skills/add-service/SKILL.md +81 -0
- package/stack-template/.claude/skills/sync-contracts/SKILL.md +74 -0
- package/stack-template/.editorconfig +21 -0
- package/stack-template/.gitattributes +10 -0
- package/stack-template/.github/pull_request_template.md +26 -0
- package/stack-template/.github/workflow-templates/services-ci.yml.example +69 -0
- package/stack-template/.github/workflows/contracts.yml +133 -0
- package/stack-template/.github/workflows/convergence.yml +209 -0
- package/stack-template/.github/workflows/git-guard.yml +44 -0
- package/stack-template/.github/workflows/publish-uikit.yml +96 -0
- package/stack-template/.github/workflows/remotes-activity.yml +82 -0
- package/stack-template/.github/workflows/remotes-tasks.yml +82 -0
- package/stack-template/.github/workflows/services-auth-svc.yml +153 -0
- package/stack-template/.github/workflows/services-go-svc.yml +281 -0
- package/stack-template/.github/workflows/services-node-svc.yml +173 -0
- package/stack-template/.github/workflows/services-spring-svc.yml +132 -0
- package/stack-template/.github/workflows/shell.yml +78 -0
- package/stack-template/.github/workflows/ui-kit.yml +51 -0
- package/stack-template/.husky/commit-msg +14 -0
- package/stack-template/.husky/pre-push +51 -0
- package/stack-template/.spectral.yaml +17 -0
- package/stack-template/AGENTS.md +197 -0
- package/stack-template/CLAUDE.md +114 -0
- package/stack-template/README.md +172 -0
- package/stack-template/app/admin/index.html +12 -0
- package/stack-template/app/admin/package.json +40 -0
- package/stack-template/app/admin/scripts/verify-chart.mjs +49 -0
- package/stack-template/app/admin/src/App.test.tsx +70 -0
- package/stack-template/app/admin/src/App.tsx +33 -0
- package/stack-template/app/admin/src/data/users.ts +47 -0
- package/stack-template/app/admin/src/layout/AdminLayout.tsx +212 -0
- package/stack-template/app/admin/src/main.tsx +17 -0
- package/stack-template/app/admin/src/pages/ComponentsDemo.tsx +138 -0
- package/stack-template/app/admin/src/pages/Dashboard.tsx +182 -0
- package/stack-template/app/admin/src/pages/HooksDemo.tsx +153 -0
- package/stack-template/app/admin/src/pages/Settings.tsx +156 -0
- package/stack-template/app/admin/src/pages/UploadPage.tsx +34 -0
- package/stack-template/app/admin/src/pages/Users.test.tsx +66 -0
- package/stack-template/app/admin/src/pages/Users.tsx +245 -0
- package/stack-template/app/admin/src/styles.css +9 -0
- package/stack-template/app/admin/src/tests/setup.ts +15 -0
- package/stack-template/app/admin/tsconfig.json +18 -0
- package/stack-template/app/admin/vite.config.ts +11 -0
- package/stack-template/app/admin/vitest.config.ts +14 -0
- package/stack-template/app/create-wakii-app/README.md +71 -0
- package/stack-template/app/create-wakii-app/package.json +27 -0
- package/stack-template/app/create-wakii-app/scripts/publish-npm.sh +38 -0
- package/stack-template/app/create-wakii-app/src/index.ts +127 -0
- package/stack-template/app/create-wakii-app/src/options.test.ts +80 -0
- package/stack-template/app/create-wakii-app/src/options.ts +117 -0
- package/stack-template/app/create-wakii-app/src/scaffold.test.ts +143 -0
- package/stack-template/app/create-wakii-app/src/scaffold.ts +194 -0
- package/stack-template/app/create-wakii-app/tsconfig.json +17 -0
- package/stack-template/app/create-wakii-app/vitest.config.ts +9 -0
- package/stack-template/app/create-wakii-stack/package.json +27 -0
- package/stack-template/app/create-wakii-stack/src/manifest.ts +101 -0
- package/stack-template/app/create-wakii-stack/src/options.ts +106 -0
- package/stack-template/app/create-wakii-stack/src/scaffold.ts +315 -0
- package/stack-template/app/create-wakii-stack/tsconfig.json +17 -0
- package/stack-template/app/create-wakii-stack/vitest.config.ts +9 -0
- package/stack-template/app/remotes/activity/Dockerfile +36 -0
- package/stack-template/app/remotes/activity/README.md +59 -0
- package/stack-template/app/remotes/activity/index.html +11 -0
- package/stack-template/app/remotes/activity/nginx.conf +35 -0
- package/stack-template/app/remotes/activity/package.json +40 -0
- package/stack-template/app/remotes/activity/rspack.config.mjs +152 -0
- package/stack-template/app/remotes/activity/src/ActivityPage.tsx +139 -0
- package/stack-template/app/remotes/activity/src/api.ts +63 -0
- package/stack-template/app/remotes/activity/src/app.css +7 -0
- package/stack-template/app/remotes/activity/src/components/FeedItem.tsx +39 -0
- package/stack-template/app/remotes/activity/src/components/StatTile.tsx +24 -0
- package/stack-template/app/remotes/activity/src/components/Timeline.tsx +53 -0
- package/stack-template/app/remotes/activity/src/components/time.ts +30 -0
- package/stack-template/app/remotes/activity/src/env.d.ts +5 -0
- package/stack-template/app/remotes/activity/src/index.tsx +12 -0
- package/stack-template/app/remotes/activity/src/standalone.tsx +36 -0
- package/stack-template/app/remotes/activity/tests/ActivityPage.test.tsx +260 -0
- package/stack-template/app/remotes/activity/tests/api.test.ts +61 -0
- package/stack-template/app/remotes/activity/tests/setup.ts +1 -0
- package/stack-template/app/remotes/activity/tests/test-utils.tsx +16 -0
- package/stack-template/app/remotes/activity/tsconfig.json +26 -0
- package/stack-template/app/remotes/activity/vitest.config.ts +38 -0
- package/stack-template/app/remotes/tasks/Dockerfile +36 -0
- package/stack-template/app/remotes/tasks/README.md +59 -0
- package/stack-template/app/remotes/tasks/index.html +11 -0
- package/stack-template/app/remotes/tasks/nginx.conf +35 -0
- package/stack-template/app/remotes/tasks/package.json +41 -0
- package/stack-template/app/remotes/tasks/rspack.config.mjs +153 -0
- package/stack-template/app/remotes/tasks/src/TasksPage.tsx +284 -0
- package/stack-template/app/remotes/tasks/src/api.ts +109 -0
- package/stack-template/app/remotes/tasks/src/app.css +7 -0
- package/stack-template/app/remotes/tasks/src/components/StatusBadge.tsx +20 -0
- package/stack-template/app/remotes/tasks/src/components/StatusSelect.tsx +27 -0
- package/stack-template/app/remotes/tasks/src/components/TaskForm.tsx +74 -0
- package/stack-template/app/remotes/tasks/src/components/TaskItem.tsx +199 -0
- package/stack-template/app/remotes/tasks/src/components/TaskList.tsx +60 -0
- package/stack-template/app/remotes/tasks/src/components/status.ts +23 -0
- package/stack-template/app/remotes/tasks/src/env.d.ts +5 -0
- package/stack-template/app/remotes/tasks/src/index.tsx +12 -0
- package/stack-template/app/remotes/tasks/src/standalone.tsx +38 -0
- package/stack-template/app/remotes/tasks/tests/TasksPage.test.tsx +445 -0
- package/stack-template/app/remotes/tasks/tests/api.test.ts +159 -0
- package/stack-template/app/remotes/tasks/tests/setup.ts +1 -0
- package/stack-template/app/remotes/tasks/tests/test-utils.tsx +16 -0
- package/stack-template/app/remotes/tasks/tsconfig.json +26 -0
- package/stack-template/app/remotes/tasks/vitest.config.ts +34 -0
- package/stack-template/app/shared/README.md +21 -0
- package/stack-template/app/shared/package.json +37 -0
- package/stack-template/app/shared/src/api-client.ts +66 -0
- package/stack-template/app/shared/src/error-envelope.ts +38 -0
- package/stack-template/app/shared/src/index.ts +21 -0
- package/stack-template/app/shared/src/mf-bootstrap.ts +89 -0
- package/stack-template/app/shared/src/refresh-client.ts +170 -0
- package/stack-template/app/shared/src/token-storage.ts +57 -0
- package/stack-template/app/shell/Dockerfile +37 -0
- package/stack-template/app/shell/README.md +79 -0
- package/stack-template/app/shell/index.html +11 -0
- package/stack-template/app/shell/nginx.conf +23 -0
- package/stack-template/app/shell/package.json +43 -0
- package/stack-template/app/shell/rspack.config.mjs +147 -0
- package/stack-template/app/shell/src/App.tsx +57 -0
- package/stack-template/app/shell/src/api.ts +36 -0
- package/stack-template/app/shell/src/app.css +11 -0
- package/stack-template/app/shell/src/bootstrap.tsx +24 -0
- package/stack-template/app/shell/src/components/Layout.tsx +35 -0
- package/stack-template/app/shell/src/components/NavBar.tsx +118 -0
- package/stack-template/app/shell/src/components/RemoteSlot.tsx +82 -0
- package/stack-template/app/shell/src/components/RequireAuth.tsx +14 -0
- package/stack-template/app/shell/src/env.d.ts +7 -0
- package/stack-template/app/shell/src/index.tsx +3 -0
- package/stack-template/app/shell/src/pages/HomePage.tsx +70 -0
- package/stack-template/app/shell/src/pages/LoginPage.tsx +217 -0
- package/stack-template/app/shell/src/remote-urls.ts +18 -0
- package/stack-template/app/shell/tests/a11y.test.tsx +53 -0
- package/stack-template/app/shell/tests/api-timeout.test.ts +43 -0
- package/stack-template/app/shell/tests/integration.test.tsx +93 -0
- package/stack-template/app/shell/tests/login.test.tsx +227 -0
- package/stack-template/app/shell/tests/mf-retry.test.ts +76 -0
- package/stack-template/app/shell/tests/refresh-client.test.ts +301 -0
- package/stack-template/app/shell/tests/remote-slot.test.tsx +109 -0
- package/stack-template/app/shell/tests/remote-urls.test.ts +26 -0
- package/stack-template/app/shell/tests/setup.ts +15 -0
- package/stack-template/app/shell/tests/shell-chrome.test.tsx +126 -0
- package/stack-template/app/shell/tsconfig.json +26 -0
- package/stack-template/app/shell/vitest.config.ts +42 -0
- package/stack-template/app/spike/README.md +35 -0
- package/stack-template/app/spike/host/index.html +11 -0
- package/stack-template/app/spike/host/package.json +17 -0
- package/stack-template/app/spike/host/rspack.config.mjs +34 -0
- package/stack-template/app/spike/host/src/bootstrap.jsx +26 -0
- package/stack-template/app/spike/host/src/index.jsx +3 -0
- package/stack-template/app/spike/remote/package.json +17 -0
- package/stack-template/app/spike/remote/rspack.config.mjs +36 -0
- package/stack-template/app/spike/remote/src/Hello.jsx +7 -0
- package/stack-template/app/spike/remote/src/index.js +2 -0
- package/stack-template/app/spike/serve.mjs +31 -0
- package/stack-template/app/starter-templates/template-feats/extras/carousel/src/DemoCarousel.tsx +99 -0
- package/stack-template/app/starter-templates/template-feats/extras/chart/src/DemoChart.tsx +84 -0
- package/stack-template/app/starter-templates/template-feats/extras/editor/src/DemoEditor.tsx +110 -0
- package/stack-template/app/starter-templates/template-feats/extras/schedule/src/DemoSchedule.tsx +81 -0
- package/stack-template/app/starter-templates/template-feats/router/src/App.tsx +332 -0
- package/stack-template/app/starter-templates/template-feats/router/src/main.tsx +14 -0
- package/stack-template/app/starter-templates/vite-js/README.md +72 -0
- package/stack-template/app/starter-templates/vite-js/index.html +12 -0
- package/stack-template/app/starter-templates/vite-js/jsconfig.json +10 -0
- package/stack-template/app/starter-templates/vite-js/package.json +22 -0
- package/stack-template/app/starter-templates/vite-js/src/App.jsx +158 -0
- package/stack-template/app/starter-templates/vite-js/src/main.jsx +10 -0
- package/stack-template/app/starter-templates/vite-js/src/styles.css +15 -0
- package/stack-template/app/starter-templates/vite-js/src/theme.js +21 -0
- package/stack-template/app/starter-templates/vite-js/vite.config.mjs +8 -0
- package/stack-template/app/starter-templates/vite-ts/README.md +53 -0
- package/stack-template/app/starter-templates/vite-ts/index.html +12 -0
- package/stack-template/app/starter-templates/vite-ts/package.json +29 -0
- package/stack-template/app/starter-templates/vite-ts/src/App.tsx +181 -0
- package/stack-template/app/starter-templates/vite-ts/src/main.tsx +12 -0
- package/stack-template/app/starter-templates/vite-ts/src/styles.css +21 -0
- package/stack-template/app/starter-templates/vite-ts/src/theme.ts +16 -0
- package/stack-template/app/starter-templates/vite-ts/tsconfig.json +25 -0
- package/stack-template/app/starter-templates/vite-ts/tsconfig.node.json +11 -0
- package/stack-template/app/starter-templates/vite-ts/vite.config.ts +10 -0
- package/stack-template/app/ui-kit/.storybook/main.ts +29 -0
- package/stack-template/app/ui-kit/.storybook/manager-head.html +97 -0
- package/stack-template/app/ui-kit/.storybook/manager.ts +138 -0
- package/stack-template/app/ui-kit/.storybook/preview-head.html +57 -0
- package/stack-template/app/ui-kit/.storybook/preview.ts +62 -0
- package/stack-template/app/ui-kit/.storybook/tailwind-preview.css +3 -0
- package/stack-template/app/ui-kit/.storybook/test-runner.config.ts +20 -0
- package/stack-template/app/ui-kit/CHANGELOG.md +137 -0
- package/stack-template/app/ui-kit/LICENSE +21 -0
- package/stack-template/app/ui-kit/MIGRATION.md +84 -0
- package/stack-template/app/ui-kit/README.md +173 -0
- package/stack-template/app/ui-kit/RELEASE.md +77 -0
- package/stack-template/app/ui-kit/USAGE.md +380 -0
- package/stack-template/app/ui-kit/eslint.config.js +47 -0
- package/stack-template/app/ui-kit/package.json +166 -0
- package/stack-template/app/ui-kit/scripts/publish-github.sh +39 -0
- package/stack-template/app/ui-kit/scripts/publish-npm.sh +76 -0
- package/stack-template/app/ui-kit/scripts/stamp-build.cjs +13 -0
- package/stack-template/app/ui-kit/src/KitchenSink.stories.tsx +576 -0
- package/stack-template/app/ui-kit/src/Tokens.stories.tsx +193 -0
- package/stack-template/app/ui-kit/src/entries/carousel.ts +7 -0
- package/stack-template/app/ui-kit/src/entries/chart.ts +4 -0
- package/stack-template/app/ui-kit/src/entries/editor.ts +4 -0
- package/stack-template/app/ui-kit/src/entries/experience3d.ts +5 -0
- package/stack-template/app/ui-kit/src/entries/schedule.ts +5 -0
- package/stack-template/app/ui-kit/src/env.d.ts +3 -0
- package/stack-template/app/ui-kit/src/hooks/form.stories.tsx +80 -0
- package/stack-template/app/ui-kit/src/hooks/hooks-new.stories.tsx +392 -0
- package/stack-template/app/ui-kit/src/hooks/hooks.stories.tsx +167 -0
- package/stack-template/app/ui-kit/src/hooks/useClickAway.test.tsx +63 -0
- package/stack-template/app/ui-kit/src/hooks/useClickAway.ts +30 -0
- package/stack-template/app/ui-kit/src/hooks/useControllableState.test.ts +36 -0
- package/stack-template/app/ui-kit/src/hooks/useControllableState.ts +41 -0
- package/stack-template/app/ui-kit/src/hooks/useCopyToClipboard.test.ts +89 -0
- package/stack-template/app/ui-kit/src/hooks/useCopyToClipboard.ts +20 -0
- package/stack-template/app/ui-kit/src/hooks/useCountdown.test.ts +88 -0
- package/stack-template/app/ui-kit/src/hooks/useCountdown.ts +38 -0
- package/stack-template/app/ui-kit/src/hooks/useDebounce.test.ts +71 -0
- package/stack-template/app/ui-kit/src/hooks/useDebounce.ts +14 -0
- package/stack-template/app/ui-kit/src/hooks/useDefault.test.ts +37 -0
- package/stack-template/app/ui-kit/src/hooks/useDefault.ts +15 -0
- package/stack-template/app/ui-kit/src/hooks/useEventListener.test.ts +47 -0
- package/stack-template/app/ui-kit/src/hooks/useEventListener.ts +28 -0
- package/stack-template/app/ui-kit/src/hooks/useFieldArray.test.tsx +160 -0
- package/stack-template/app/ui-kit/src/hooks/useFieldArray.ts +85 -0
- package/stack-template/app/ui-kit/src/hooks/useFocusTrap.ts +67 -0
- package/stack-template/app/ui-kit/src/hooks/useForm.test.tsx +192 -0
- package/stack-template/app/ui-kit/src/hooks/useForm.ts +119 -0
- package/stack-template/app/ui-kit/src/hooks/useFullscreen.test.tsx +71 -0
- package/stack-template/app/ui-kit/src/hooks/useFullscreen.ts +68 -0
- package/stack-template/app/ui-kit/src/hooks/useHover.test.tsx +30 -0
- package/stack-template/app/ui-kit/src/hooks/useHover.ts +23 -0
- package/stack-template/app/ui-kit/src/hooks/useInView.test.tsx +70 -0
- package/stack-template/app/ui-kit/src/hooks/useInView.ts +55 -0
- package/stack-template/app/ui-kit/src/hooks/useInfiniteScroll.test.tsx +72 -0
- package/stack-template/app/ui-kit/src/hooks/useInfiniteScroll.ts +45 -0
- package/stack-template/app/ui-kit/src/hooks/useIsFirstRender.test.ts +30 -0
- package/stack-template/app/ui-kit/src/hooks/useIsFirstRender.ts +14 -0
- package/stack-template/app/ui-kit/src/hooks/useKeyPress.test.ts +45 -0
- package/stack-template/app/ui-kit/src/hooks/useKeyPress.ts +31 -0
- package/stack-template/app/ui-kit/src/hooks/useLocalStorage.test.ts +102 -0
- package/stack-template/app/ui-kit/src/hooks/useLocalStorage.ts +34 -0
- package/stack-template/app/ui-kit/src/hooks/useLockBodyScroll.test.ts +42 -0
- package/stack-template/app/ui-kit/src/hooks/useLockBodyScroll.ts +13 -0
- package/stack-template/app/ui-kit/src/hooks/useMeasure.test.tsx +57 -0
- package/stack-template/app/ui-kit/src/hooks/useMeasure.ts +32 -0
- package/stack-template/app/ui-kit/src/hooks/useMediaQuery.test.ts +73 -0
- package/stack-template/app/ui-kit/src/hooks/useMediaQuery.ts +20 -0
- package/stack-template/app/ui-kit/src/hooks/useMountEffect.test.ts +22 -0
- package/stack-template/app/ui-kit/src/hooks/useMountEffect.ts +10 -0
- package/stack-template/app/ui-kit/src/hooks/useOnlineStatus.test.ts +36 -0
- package/stack-template/app/ui-kit/src/hooks/useOnlineStatus.ts +21 -0
- package/stack-template/app/ui-kit/src/hooks/usePrevious.test.ts +35 -0
- package/stack-template/app/ui-kit/src/hooks/usePrevious.ts +13 -0
- package/stack-template/app/ui-kit/src/hooks/useScrollProgress.test.ts +59 -0
- package/stack-template/app/ui-kit/src/hooks/useScrollProgress.ts +31 -0
- package/stack-template/app/ui-kit/src/hooks/useSessionStorage.test.ts +80 -0
- package/stack-template/app/ui-kit/src/hooks/useSessionStorage.ts +34 -0
- package/stack-template/app/ui-kit/src/hooks/useThrottle.test.ts +61 -0
- package/stack-template/app/ui-kit/src/hooks/useThrottle.ts +30 -0
- package/stack-template/app/ui-kit/src/hooks/useTimeout.test.ts +95 -0
- package/stack-template/app/ui-kit/src/hooks/useTimeout.ts +38 -0
- package/stack-template/app/ui-kit/src/hooks/useTitle.test.ts +34 -0
- package/stack-template/app/ui-kit/src/hooks/useTitle.ts +24 -0
- package/stack-template/app/ui-kit/src/hooks/useToggle.test.ts +46 -0
- package/stack-template/app/ui-kit/src/hooks/useToggle.ts +16 -0
- package/stack-template/app/ui-kit/src/hooks/useUpdateEffect.test.ts +25 -0
- package/stack-template/app/ui-kit/src/hooks/useUpdateEffect.ts +18 -0
- package/stack-template/app/ui-kit/src/hooks/useWindowSize.test.ts +33 -0
- package/stack-template/app/ui-kit/src/hooks/useWindowSize.ts +23 -0
- package/stack-template/app/ui-kit/src/index.ts +218 -0
- package/stack-template/app/ui-kit/src/intro-showcase.stories.tsx +272 -0
- package/stack-template/app/ui-kit/src/intro.docs.mdx +247 -0
- package/stack-template/app/ui-kit/src/motion/motion-showcase.stories.tsx +234 -0
- package/stack-template/app/ui-kit/src/motion/motion.md +38 -0
- package/stack-template/app/ui-kit/src/provider/index.tsx +77 -0
- package/stack-template/app/ui-kit/src/provider/provider.stories.tsx +87 -0
- package/stack-template/app/ui-kit/src/provider/provider.test.tsx +121 -0
- package/stack-template/app/ui-kit/src/styles/base.css +171 -0
- package/stack-template/app/ui-kit/src/styles/dark-theme.test.ts +21 -0
- package/stack-template/app/ui-kit/src/styles/tailwind.css +220 -0
- package/stack-template/app/ui-kit/src/styles/themes/dark.css +71 -0
- package/stack-template/app/ui-kit/src/styles/tokens.css +133 -0
- package/stack-template/app/ui-kit/src/styles/ui-kit.css +10 -0
- package/stack-template/app/ui-kit/src/templates/auth.stories.tsx +425 -0
- package/stack-template/app/ui-kit/src/templates/crud.stories.tsx +416 -0
- package/stack-template/app/ui-kit/src/templates/dashboard.stories.tsx +504 -0
- package/stack-template/app/ui-kit/src/templates/experience/chapters/ch1-deep-focus.tsx +96 -0
- package/stack-template/app/ui-kit/src/templates/experience/chapters/ch2-living-docs.tsx +134 -0
- package/stack-template/app/ui-kit/src/templates/experience/chapters/ch3-team-velocity.tsx +148 -0
- package/stack-template/app/ui-kit/src/templates/experience/chapters/ch4-ship-your-app.tsx +100 -0
- package/stack-template/app/ui-kit/src/templates/experience/chapters/ch5-future.tsx +67 -0
- package/stack-template/app/ui-kit/src/templates/experience/chapters/hero.tsx +434 -0
- package/stack-template/app/ui-kit/src/templates/experience/chapters/nav-footer.tsx +85 -0
- package/stack-template/app/ui-kit/src/templates/experience/hero.stories.tsx +27 -0
- package/stack-template/app/ui-kit/src/templates/experience/hero.test.tsx +108 -0
- package/stack-template/app/ui-kit/src/templates/experience/index.stories.tsx +51 -0
- package/stack-template/app/ui-kit/src/templates/experience/lib/ChapterShell.tsx +84 -0
- package/stack-template/app/ui-kit/src/templates/experience/lib/SideNav.tsx +173 -0
- package/stack-template/app/ui-kit/src/templates/experience/lib/chapter-shell.test.tsx +266 -0
- package/stack-template/app/ui-kit/src/templates/experience/lib/scroll-mood.tsx +143 -0
- package/stack-template/app/ui-kit/src/templates/experience/lib/starfield.test.tsx +31 -0
- package/stack-template/app/ui-kit/src/templates/experience/lib/starfield.tsx +190 -0
- package/stack-template/app/ui-kit/src/templates/experience/mood-engine.stories.tsx +114 -0
- package/stack-template/app/ui-kit/src/templates/experience/shell-nav.stories.tsx +113 -0
- package/stack-template/app/ui-kit/src/templates/kanban-project.stories.tsx +352 -0
- package/stack-template/app/ui-kit/src/templates/landing.stories.tsx +380 -0
- package/stack-template/app/ui-kit/src/templates/parallax-landing.stories.tsx +633 -0
- package/stack-template/app/ui-kit/src/templates/settings.stories.tsx +474 -0
- package/stack-template/app/ui-kit/src/ui/accordion/accordion.stories.tsx +91 -0
- package/stack-template/app/ui-kit/src/ui/accordion/accordion.test.tsx +99 -0
- package/stack-template/app/ui-kit/src/ui/accordion/index.tsx +107 -0
- package/stack-template/app/ui-kit/src/ui/affix/affix.stories.tsx +104 -0
- package/stack-template/app/ui-kit/src/ui/affix/affix.test.tsx +138 -0
- package/stack-template/app/ui-kit/src/ui/affix/index.tsx +89 -0
- package/stack-template/app/ui-kit/src/ui/alert/alert.stories.tsx +149 -0
- package/stack-template/app/ui-kit/src/ui/alert/alert.test.tsx +85 -0
- package/stack-template/app/ui-kit/src/ui/alert/index.tsx +118 -0
- package/stack-template/app/ui-kit/src/ui/anchor/anchor.stories.tsx +96 -0
- package/stack-template/app/ui-kit/src/ui/anchor/anchor.test.tsx +191 -0
- package/stack-template/app/ui-kit/src/ui/anchor/index.tsx +144 -0
- package/stack-template/app/ui-kit/src/ui/auto-complete/auto-complete.stories.tsx +67 -0
- package/stack-template/app/ui-kit/src/ui/auto-complete/auto-complete.test.tsx +94 -0
- package/stack-template/app/ui-kit/src/ui/auto-complete/index.tsx +54 -0
- package/stack-template/app/ui-kit/src/ui/avatar/avatar.stories.tsx +132 -0
- package/stack-template/app/ui-kit/src/ui/avatar/avatar.test.tsx +65 -0
- package/stack-template/app/ui-kit/src/ui/avatar/index.tsx +48 -0
- package/stack-template/app/ui-kit/src/ui/avatar-group/avatar-group.stories.tsx +113 -0
- package/stack-template/app/ui-kit/src/ui/avatar-group/avatar-group.test.tsx +71 -0
- package/stack-template/app/ui-kit/src/ui/avatar-group/index.tsx +66 -0
- package/stack-template/app/ui-kit/src/ui/backdrop/backdrop.stories.tsx +66 -0
- package/stack-template/app/ui-kit/src/ui/backdrop/backdrop.test.tsx +37 -0
- package/stack-template/app/ui-kit/src/ui/backdrop/index.tsx +29 -0
- package/stack-template/app/ui-kit/src/ui/badge/badge.stories.tsx +105 -0
- package/stack-template/app/ui-kit/src/ui/badge/badge.test.tsx +115 -0
- package/stack-template/app/ui-kit/src/ui/badge/index.tsx +154 -0
- package/stack-template/app/ui-kit/src/ui/blockui/blockui.stories.tsx +34 -0
- package/stack-template/app/ui-kit/src/ui/blockui/blockui.test.tsx +29 -0
- package/stack-template/app/ui-kit/src/ui/blockui/index.tsx +25 -0
- package/stack-template/app/ui-kit/src/ui/bottom-navigation/bottom-navigation.stories.tsx +70 -0
- package/stack-template/app/ui-kit/src/ui/bottom-navigation/bottom-navigation.test.tsx +68 -0
- package/stack-template/app/ui-kit/src/ui/bottom-navigation/index.tsx +82 -0
- package/stack-template/app/ui-kit/src/ui/branch-fill.test.tsx +245 -0
- package/stack-template/app/ui-kit/src/ui/breadcrumb/breadcrumb.stories.tsx +103 -0
- package/stack-template/app/ui-kit/src/ui/breadcrumb/breadcrumb.test.tsx +49 -0
- package/stack-template/app/ui-kit/src/ui/breadcrumb/index.tsx +37 -0
- package/stack-template/app/ui-kit/src/ui/busy-box/busy-box.stories.tsx +30 -0
- package/stack-template/app/ui-kit/src/ui/busy-box/busy-box.test.tsx +29 -0
- package/stack-template/app/ui-kit/src/ui/busy-box/index.tsx +25 -0
- package/stack-template/app/ui-kit/src/ui/button/button.stories.tsx +121 -0
- package/stack-template/app/ui-kit/src/ui/button/button.test.tsx +207 -0
- package/stack-template/app/ui-kit/src/ui/button/index.tsx +128 -0
- package/stack-template/app/ui-kit/src/ui/calendar/calendar.stories.tsx +100 -0
- package/stack-template/app/ui-kit/src/ui/calendar/calendar.test.tsx +92 -0
- package/stack-template/app/ui-kit/src/ui/calendar/index.tsx +163 -0
- package/stack-template/app/ui-kit/src/ui/card/card.stories.tsx +203 -0
- package/stack-template/app/ui-kit/src/ui/card/card.test.tsx +135 -0
- package/stack-template/app/ui-kit/src/ui/card/index.tsx +84 -0
- package/stack-template/app/ui-kit/src/ui/carousel/carousel.stories.tsx +533 -0
- package/stack-template/app/ui-kit/src/ui/carousel/carousel.test.tsx +148 -0
- package/stack-template/app/ui-kit/src/ui/carousel/index.tsx +195 -0
- package/stack-template/app/ui-kit/src/ui/cascade-select/cascade-select.stories.tsx +126 -0
- package/stack-template/app/ui-kit/src/ui/cascade-select/cascade-select.test.tsx +132 -0
- package/stack-template/app/ui-kit/src/ui/cascade-select/index.tsx +87 -0
- package/stack-template/app/ui-kit/src/ui/chart/chart-theme.test.tsx +79 -0
- package/stack-template/app/ui-kit/src/ui/chart/chart.stories.tsx +278 -0
- package/stack-template/app/ui-kit/src/ui/chart/chart.test.tsx +103 -0
- package/stack-template/app/ui-kit/src/ui/chart/index.tsx +172 -0
- package/stack-template/app/ui-kit/src/ui/checkbox/checkbox.stories.tsx +67 -0
- package/stack-template/app/ui-kit/src/ui/checkbox/checkbox.test.tsx +99 -0
- package/stack-template/app/ui-kit/src/ui/checkbox/index.tsx +52 -0
- package/stack-template/app/ui-kit/src/ui/chips/chips.stories.tsx +53 -0
- package/stack-template/app/ui-kit/src/ui/chips/chips.test.tsx +86 -0
- package/stack-template/app/ui-kit/src/ui/chips/index.tsx +44 -0
- package/stack-template/app/ui-kit/src/ui/collapse/collapse.stories.tsx +93 -0
- package/stack-template/app/ui-kit/src/ui/collapse/collapse.test.tsx +128 -0
- package/stack-template/app/ui-kit/src/ui/collapse/index.tsx +75 -0
- package/stack-template/app/ui-kit/src/ui/color-picker/color-picker.stories.tsx +48 -0
- package/stack-template/app/ui-kit/src/ui/color-picker/color-picker.test.tsx +68 -0
- package/stack-template/app/ui-kit/src/ui/color-picker/index.tsx +38 -0
- package/stack-template/app/ui-kit/src/ui/context-menu/context-menu.stories.tsx +73 -0
- package/stack-template/app/ui-kit/src/ui/context-menu/context-menu.test.tsx +93 -0
- package/stack-template/app/ui-kit/src/ui/context-menu/index.tsx +79 -0
- package/stack-template/app/ui-kit/src/ui/count-up/count-up.stories.tsx +80 -0
- package/stack-template/app/ui-kit/src/ui/count-up/count-up.test.tsx +121 -0
- package/stack-template/app/ui-kit/src/ui/count-up/index.tsx +70 -0
- package/stack-template/app/ui-kit/src/ui/date-picker/date-picker.stories.tsx +154 -0
- package/stack-template/app/ui-kit/src/ui/date-picker/date-picker.test.tsx +221 -0
- package/stack-template/app/ui-kit/src/ui/date-picker/index.tsx +287 -0
- package/stack-template/app/ui-kit/src/ui/date-picker/locale-constants.ts +90 -0
- package/stack-template/app/ui-kit/src/ui/date-picker/locale.tsx +15 -0
- package/stack-template/app/ui-kit/src/ui/deferred-content/deferred-content.stories.tsx +62 -0
- package/stack-template/app/ui-kit/src/ui/deferred-content/deferred-content.test.tsx +94 -0
- package/stack-template/app/ui-kit/src/ui/deferred-content/index.tsx +61 -0
- package/stack-template/app/ui-kit/src/ui/descriptions/descriptions.stories.tsx +114 -0
- package/stack-template/app/ui-kit/src/ui/descriptions/descriptions.test.tsx +75 -0
- package/stack-template/app/ui-kit/src/ui/descriptions/index.tsx +48 -0
- package/stack-template/app/ui-kit/src/ui/divider/divider.stories.tsx +66 -0
- package/stack-template/app/ui-kit/src/ui/divider/divider.test.tsx +83 -0
- package/stack-template/app/ui-kit/src/ui/divider/index.tsx +65 -0
- package/stack-template/app/ui-kit/src/ui/drag-drop/drag-drop.stories.tsx +145 -0
- package/stack-template/app/ui-kit/src/ui/drag-drop/drag-drop.test.tsx +352 -0
- package/stack-template/app/ui-kit/src/ui/drag-drop/index.tsx +456 -0
- package/stack-template/app/ui-kit/src/ui/drawer/drawer.stories.tsx +108 -0
- package/stack-template/app/ui-kit/src/ui/drawer/drawer.test.tsx +132 -0
- package/stack-template/app/ui-kit/src/ui/drawer/index.tsx +113 -0
- package/stack-template/app/ui-kit/src/ui/dropdown/dropdown.stories.tsx +61 -0
- package/stack-template/app/ui-kit/src/ui/dropdown/dropdown.test.tsx +101 -0
- package/stack-template/app/ui-kit/src/ui/dropdown/index.tsx +162 -0
- package/stack-template/app/ui-kit/src/ui/editor/EditorInner.tsx +93 -0
- package/stack-template/app/ui-kit/src/ui/editor/editor.stories.tsx +37 -0
- package/stack-template/app/ui-kit/src/ui/editor/editor.test.tsx +84 -0
- package/stack-template/app/ui-kit/src/ui/editor/index.tsx +58 -0
- package/stack-template/app/ui-kit/src/ui/empty-state/empty-state.stories.tsx +24 -0
- package/stack-template/app/ui-kit/src/ui/empty-state/empty-state.test.tsx +48 -0
- package/stack-template/app/ui-kit/src/ui/empty-state/index.tsx +22 -0
- package/stack-template/app/ui-kit/src/ui/experience3d/experience3d.stories.tsx +66 -0
- package/stack-template/app/ui-kit/src/ui/experience3d/experience3d.test.tsx +50 -0
- package/stack-template/app/ui-kit/src/ui/experience3d/index.tsx +457 -0
- package/stack-template/app/ui-kit/src/ui/field/field-array.stories.tsx +214 -0
- package/stack-template/app/ui-kit/src/ui/field/field.stories.tsx +158 -0
- package/stack-template/app/ui-kit/src/ui/field/field.test.tsx +68 -0
- package/stack-template/app/ui-kit/src/ui/field/index.tsx +48 -0
- package/stack-template/app/ui-kit/src/ui/fieldset/fieldset.stories.tsx +49 -0
- package/stack-template/app/ui-kit/src/ui/fieldset/fieldset.test.tsx +88 -0
- package/stack-template/app/ui-kit/src/ui/fieldset/index.tsx +62 -0
- package/stack-template/app/ui-kit/src/ui/flex/flex.stories.tsx +96 -0
- package/stack-template/app/ui-kit/src/ui/flex/flex.test.tsx +79 -0
- package/stack-template/app/ui-kit/src/ui/flex/index.tsx +45 -0
- package/stack-template/app/ui-kit/src/ui/float-button/float-button.stories.tsx +82 -0
- package/stack-template/app/ui-kit/src/ui/float-button/float-button.test.tsx +107 -0
- package/stack-template/app/ui-kit/src/ui/float-button/index.tsx +124 -0
- package/stack-template/app/ui-kit/src/ui/galleria/galleria.stories.tsx +78 -0
- package/stack-template/app/ui-kit/src/ui/galleria/galleria.test.tsx +67 -0
- package/stack-template/app/ui-kit/src/ui/galleria/index.tsx +47 -0
- package/stack-template/app/ui-kit/src/ui/grid/grid.stories.tsx +179 -0
- package/stack-template/app/ui-kit/src/ui/grid/grid.test.tsx +286 -0
- package/stack-template/app/ui-kit/src/ui/grid/index.tsx +104 -0
- package/stack-template/app/ui-kit/src/ui/icons/icons.stories.tsx +52 -0
- package/stack-template/app/ui-kit/src/ui/icons/icons.test.tsx +60 -0
- package/stack-template/app/ui-kit/src/ui/icons/index.tsx +294 -0
- package/stack-template/app/ui-kit/src/ui/image/image.stories.tsx +231 -0
- package/stack-template/app/ui-kit/src/ui/image/image.test.tsx +79 -0
- package/stack-template/app/ui-kit/src/ui/image/index.tsx +76 -0
- package/stack-template/app/ui-kit/src/ui/inplace/index.tsx +33 -0
- package/stack-template/app/ui-kit/src/ui/inplace/inplace.stories.tsx +75 -0
- package/stack-template/app/ui-kit/src/ui/inplace/inplace.test.tsx +58 -0
- package/stack-template/app/ui-kit/src/ui/input/index.tsx +133 -0
- package/stack-template/app/ui-kit/src/ui/input/input-search.stories.tsx +112 -0
- package/stack-template/app/ui-kit/src/ui/input/input-search.test.tsx +116 -0
- package/stack-template/app/ui-kit/src/ui/input/input-search.tsx +116 -0
- package/stack-template/app/ui-kit/src/ui/input/input.stories.tsx +176 -0
- package/stack-template/app/ui-kit/src/ui/input/input.test.tsx +106 -0
- package/stack-template/app/ui-kit/src/ui/input-mask/index.tsx +39 -0
- package/stack-template/app/ui-kit/src/ui/input-mask/input-mask.stories.tsx +46 -0
- package/stack-template/app/ui-kit/src/ui/input-mask/input-mask.test.tsx +57 -0
- package/stack-template/app/ui-kit/src/ui/input-number/index.tsx +125 -0
- package/stack-template/app/ui-kit/src/ui/input-number/input-number.stories.tsx +190 -0
- package/stack-template/app/ui-kit/src/ui/input-number/input-number.test.tsx +157 -0
- package/stack-template/app/ui-kit/src/ui/input-otp/index.tsx +57 -0
- package/stack-template/app/ui-kit/src/ui/input-otp/input-otp.stories.tsx +90 -0
- package/stack-template/app/ui-kit/src/ui/input-otp/input-otp.test.tsx +66 -0
- package/stack-template/app/ui-kit/src/ui/kanban/index.tsx +277 -0
- package/stack-template/app/ui-kit/src/ui/kanban/kanban.stories.tsx +219 -0
- package/stack-template/app/ui-kit/src/ui/kanban/kanban.test.tsx +234 -0
- package/stack-template/app/ui-kit/src/ui/knob/index.tsx +58 -0
- package/stack-template/app/ui-kit/src/ui/knob/knob.stories.tsx +49 -0
- package/stack-template/app/ui-kit/src/ui/knob/knob.test.tsx +42 -0
- package/stack-template/app/ui-kit/src/ui/layout/index.tsx +145 -0
- package/stack-template/app/ui-kit/src/ui/layout/layout.stories.tsx +158 -0
- package/stack-template/app/ui-kit/src/ui/layout/layout.test.tsx +154 -0
- package/stack-template/app/ui-kit/src/ui/link/index.tsx +61 -0
- package/stack-template/app/ui-kit/src/ui/link/link.stories.tsx +68 -0
- package/stack-template/app/ui-kit/src/ui/link/link.test.tsx +69 -0
- package/stack-template/app/ui-kit/src/ui/list/index.tsx +135 -0
- package/stack-template/app/ui-kit/src/ui/list/list.stories.tsx +194 -0
- package/stack-template/app/ui-kit/src/ui/list/list.test.tsx +164 -0
- package/stack-template/app/ui-kit/src/ui/listbox/index.tsx +27 -0
- package/stack-template/app/ui-kit/src/ui/listbox/listbox.stories.tsx +57 -0
- package/stack-template/app/ui-kit/src/ui/listbox/listbox.test.tsx +49 -0
- package/stack-template/app/ui-kit/src/ui/mega-menu/index.tsx +142 -0
- package/stack-template/app/ui-kit/src/ui/mega-menu/mega-menu.stories.tsx +137 -0
- package/stack-template/app/ui-kit/src/ui/mega-menu/mega-menu.test.tsx +130 -0
- package/stack-template/app/ui-kit/src/ui/mention/index.tsx +76 -0
- package/stack-template/app/ui-kit/src/ui/mention/mention.stories.tsx +44 -0
- package/stack-template/app/ui-kit/src/ui/mention/mention.test.tsx +87 -0
- package/stack-template/app/ui-kit/src/ui/menu/index.tsx +256 -0
- package/stack-template/app/ui-kit/src/ui/menu/menu.stories.tsx +124 -0
- package/stack-template/app/ui-kit/src/ui/menu/menu.test.tsx +251 -0
- package/stack-template/app/ui-kit/src/ui/menubar/index.tsx +42 -0
- package/stack-template/app/ui-kit/src/ui/menubar/menubar.stories.tsx +66 -0
- package/stack-template/app/ui-kit/src/ui/menubar/menubar.test.tsx +65 -0
- package/stack-template/app/ui-kit/src/ui/message/index.tsx +123 -0
- package/stack-template/app/ui-kit/src/ui/message/message.stories.tsx +104 -0
- package/stack-template/app/ui-kit/src/ui/message/message.test.tsx +109 -0
- package/stack-template/app/ui-kit/src/ui/modal/index.tsx +142 -0
- package/stack-template/app/ui-kit/src/ui/modal/modal.stories.tsx +128 -0
- package/stack-template/app/ui-kit/src/ui/modal/modal.test.tsx +166 -0
- package/stack-template/app/ui-kit/src/ui/notification/index.tsx +142 -0
- package/stack-template/app/ui-kit/src/ui/notification/notification.stories.tsx +155 -0
- package/stack-template/app/ui-kit/src/ui/notification/notification.test.tsx +83 -0
- package/stack-template/app/ui-kit/src/ui/order-list/index.tsx +38 -0
- package/stack-template/app/ui-kit/src/ui/order-list/order-list.stories.tsx +38 -0
- package/stack-template/app/ui-kit/src/ui/order-list/order-list.test.tsx +54 -0
- package/stack-template/app/ui-kit/src/ui/org-chart/index.tsx +138 -0
- package/stack-template/app/ui-kit/src/ui/org-chart/org-chart.stories.tsx +76 -0
- package/stack-template/app/ui-kit/src/ui/org-chart/org-chart.test.tsx +98 -0
- package/stack-template/app/ui-kit/src/ui/pagination/index.tsx +102 -0
- package/stack-template/app/ui-kit/src/ui/pagination/pagination.stories.tsx +103 -0
- package/stack-template/app/ui-kit/src/ui/pagination/pagination.test.tsx +112 -0
- package/stack-template/app/ui-kit/src/ui/panel-menu/index.tsx +59 -0
- package/stack-template/app/ui-kit/src/ui/panel-menu/panel-menu.stories.tsx +96 -0
- package/stack-template/app/ui-kit/src/ui/panel-menu/panel-menu.test.tsx +64 -0
- package/stack-template/app/ui-kit/src/ui/parallax/index.tsx +62 -0
- package/stack-template/app/ui-kit/src/ui/parallax/parallax.stories.tsx +115 -0
- package/stack-template/app/ui-kit/src/ui/parallax/parallax.test.tsx +148 -0
- package/stack-template/app/ui-kit/src/ui/password/index.tsx +67 -0
- package/stack-template/app/ui-kit/src/ui/password/password.stories.tsx +43 -0
- package/stack-template/app/ui-kit/src/ui/password/password.test.tsx +45 -0
- package/stack-template/app/ui-kit/src/ui/pick-list/index.tsx +103 -0
- package/stack-template/app/ui-kit/src/ui/pick-list/pick-list.stories.tsx +59 -0
- package/stack-template/app/ui-kit/src/ui/pick-list/pick-list.test.tsx +94 -0
- package/stack-template/app/ui-kit/src/ui/popconfirm/index.tsx +102 -0
- package/stack-template/app/ui-kit/src/ui/popconfirm/popconfirm.stories.tsx +73 -0
- package/stack-template/app/ui-kit/src/ui/popconfirm/popconfirm.test.tsx +127 -0
- package/stack-template/app/ui-kit/src/ui/popover/index.tsx +136 -0
- package/stack-template/app/ui-kit/src/ui/popover/popover.stories.tsx +114 -0
- package/stack-template/app/ui-kit/src/ui/popover/popover.test.tsx +172 -0
- package/stack-template/app/ui-kit/src/ui/progress/index.tsx +46 -0
- package/stack-template/app/ui-kit/src/ui/progress/progress.stories.tsx +57 -0
- package/stack-template/app/ui-kit/src/ui/progress/progress.test.tsx +90 -0
- package/stack-template/app/ui-kit/src/ui/qr-code/index.tsx +88 -0
- package/stack-template/app/ui-kit/src/ui/qr-code/qr-code.stories.tsx +109 -0
- package/stack-template/app/ui-kit/src/ui/qr-code/qr-code.test.tsx +155 -0
- package/stack-template/app/ui-kit/src/ui/qr-code/qrcode-core.ts +56 -0
- package/stack-template/app/ui-kit/src/ui/qr-code/qrcode-generator.vendor.ts +2300 -0
- package/stack-template/app/ui-kit/src/ui/radio/index.tsx +62 -0
- package/stack-template/app/ui-kit/src/ui/radio/radio.stories.tsx +94 -0
- package/stack-template/app/ui-kit/src/ui/radio/radio.test.tsx +83 -0
- package/stack-template/app/ui-kit/src/ui/rating/index.tsx +36 -0
- package/stack-template/app/ui-kit/src/ui/rating/rating.stories.tsx +42 -0
- package/stack-template/app/ui-kit/src/ui/rating/rating.test.tsx +45 -0
- package/stack-template/app/ui-kit/src/ui/result/index.tsx +72 -0
- package/stack-template/app/ui-kit/src/ui/result/result.stories.tsx +82 -0
- package/stack-template/app/ui-kit/src/ui/result/result.test.tsx +57 -0
- package/stack-template/app/ui-kit/src/ui/reveal/index.tsx +83 -0
- package/stack-template/app/ui-kit/src/ui/reveal/reveal.stories.tsx +91 -0
- package/stack-template/app/ui-kit/src/ui/reveal/reveal.test.tsx +148 -0
- package/stack-template/app/ui-kit/src/ui/schedule/index.tsx +104 -0
- package/stack-template/app/ui-kit/src/ui/schedule/schedule.fc.test.tsx +95 -0
- package/stack-template/app/ui-kit/src/ui/schedule/schedule.stories.tsx +61 -0
- package/stack-template/app/ui-kit/src/ui/schedule/schedule.test.tsx +41 -0
- package/stack-template/app/ui-kit/src/ui/scroll-page/index.tsx +46 -0
- package/stack-template/app/ui-kit/src/ui/scroll-page/scroll-page.stories.tsx +92 -0
- package/stack-template/app/ui-kit/src/ui/scroll-page/scroll-page.test.tsx +51 -0
- package/stack-template/app/ui-kit/src/ui/scroll-panel/index.tsx +16 -0
- package/stack-template/app/ui-kit/src/ui/scroll-panel/scroll-panel.stories.tsx +37 -0
- package/stack-template/app/ui-kit/src/ui/scroll-panel/scroll-panel.test.tsx +41 -0
- package/stack-template/app/ui-kit/src/ui/scrolltop/index.tsx +27 -0
- package/stack-template/app/ui-kit/src/ui/scrolltop/scrolltop.stories.tsx +41 -0
- package/stack-template/app/ui-kit/src/ui/scrolltop/scrolltop.test.tsx +37 -0
- package/stack-template/app/ui-kit/src/ui/segmented/index.tsx +47 -0
- package/stack-template/app/ui-kit/src/ui/segmented/segmented.stories.tsx +126 -0
- package/stack-template/app/ui-kit/src/ui/segmented/segmented.test.tsx +77 -0
- package/stack-template/app/ui-kit/src/ui/select/index.tsx +302 -0
- package/stack-template/app/ui-kit/src/ui/select/select.stories.tsx +268 -0
- package/stack-template/app/ui-kit/src/ui/select/select.test.tsx +226 -0
- package/stack-template/app/ui-kit/src/ui/sidebar/index.tsx +83 -0
- package/stack-template/app/ui-kit/src/ui/sidebar/sidebar.stories.tsx +71 -0
- package/stack-template/app/ui-kit/src/ui/sidebar/sidebar.test.tsx +101 -0
- package/stack-template/app/ui-kit/src/ui/skeleton/index.tsx +55 -0
- package/stack-template/app/ui-kit/src/ui/skeleton/skeleton.stories.tsx +110 -0
- package/stack-template/app/ui-kit/src/ui/skeleton/skeleton.test.tsx +74 -0
- package/stack-template/app/ui-kit/src/ui/slide-menu/index.tsx +103 -0
- package/stack-template/app/ui-kit/src/ui/slide-menu/slide-menu.stories.tsx +92 -0
- package/stack-template/app/ui-kit/src/ui/slide-menu/slide-menu.test.tsx +120 -0
- package/stack-template/app/ui-kit/src/ui/slider/index.tsx +90 -0
- package/stack-template/app/ui-kit/src/ui/slider/slider.stories.tsx +60 -0
- package/stack-template/app/ui-kit/src/ui/slider/slider.test.tsx +66 -0
- package/stack-template/app/ui-kit/src/ui/space/index.tsx +32 -0
- package/stack-template/app/ui-kit/src/ui/space/space.stories.tsx +66 -0
- package/stack-template/app/ui-kit/src/ui/space/space.test.tsx +56 -0
- package/stack-template/app/ui-kit/src/ui/speed-dial/index.tsx +32 -0
- package/stack-template/app/ui-kit/src/ui/speed-dial/speed-dial.stories.tsx +34 -0
- package/stack-template/app/ui-kit/src/ui/speed-dial/speed-dial.test.tsx +34 -0
- package/stack-template/app/ui-kit/src/ui/spinner/index.tsx +74 -0
- package/stack-template/app/ui-kit/src/ui/spinner/spinner.stories.tsx +64 -0
- package/stack-template/app/ui-kit/src/ui/spinner/spinner.test.tsx +66 -0
- package/stack-template/app/ui-kit/src/ui/split-button/index.tsx +155 -0
- package/stack-template/app/ui-kit/src/ui/split-button/split-button.stories.tsx +137 -0
- package/stack-template/app/ui-kit/src/ui/split-button/split-button.test.tsx +152 -0
- package/stack-template/app/ui-kit/src/ui/splitter/index.tsx +49 -0
- package/stack-template/app/ui-kit/src/ui/splitter/splitter.stories.tsx +24 -0
- package/stack-template/app/ui-kit/src/ui/splitter/splitter.test.tsx +21 -0
- package/stack-template/app/ui-kit/src/ui/statistic/index.tsx +28 -0
- package/stack-template/app/ui-kit/src/ui/statistic/statistic.stories.tsx +112 -0
- package/stack-template/app/ui-kit/src/ui/statistic/statistic.test.tsx +39 -0
- package/stack-template/app/ui-kit/src/ui/steps/index.tsx +50 -0
- package/stack-template/app/ui-kit/src/ui/steps/steps.stories.tsx +57 -0
- package/stack-template/app/ui-kit/src/ui/steps/steps.test.tsx +55 -0
- package/stack-template/app/ui-kit/src/ui/switch/index.tsx +87 -0
- package/stack-template/app/ui-kit/src/ui/switch/switch.stories.tsx +123 -0
- package/stack-template/app/ui-kit/src/ui/switch/switch.test.tsx +98 -0
- package/stack-template/app/ui-kit/src/ui/tab-menu/index.tsx +33 -0
- package/stack-template/app/ui-kit/src/ui/tab-menu/tab-menu.stories.tsx +49 -0
- package/stack-template/app/ui-kit/src/ui/tab-menu/tab-menu.test.tsx +50 -0
- package/stack-template/app/ui-kit/src/ui/table/index.tsx +690 -0
- package/stack-template/app/ui-kit/src/ui/table/table-advanced.stories.tsx +91 -0
- package/stack-template/app/ui-kit/src/ui/table/table-advanced.test.tsx +188 -0
- package/stack-template/app/ui-kit/src/ui/table/table-expandable.stories.tsx +91 -0
- package/stack-template/app/ui-kit/src/ui/table/table-expandable.test.tsx +143 -0
- package/stack-template/app/ui-kit/src/ui/table/table.stories.tsx +342 -0
- package/stack-template/app/ui-kit/src/ui/table/table.test.tsx +465 -0
- package/stack-template/app/ui-kit/src/ui/table/types.ts +173 -0
- package/stack-template/app/ui-kit/src/ui/tabs/index.tsx +118 -0
- package/stack-template/app/ui-kit/src/ui/tabs/tabs.stories.tsx +113 -0
- package/stack-template/app/ui-kit/src/ui/tabs/tabs.test.tsx +77 -0
- package/stack-template/app/ui-kit/src/ui/tag/index.tsx +68 -0
- package/stack-template/app/ui-kit/src/ui/tag/tag.stories.tsx +88 -0
- package/stack-template/app/ui-kit/src/ui/tag/tag.test.tsx +126 -0
- package/stack-template/app/ui-kit/src/ui/team/debt-board/debt-board.stories.tsx +52 -0
- package/stack-template/app/ui-kit/src/ui/team/debt-board/debt-board.test.tsx +72 -0
- package/stack-template/app/ui-kit/src/ui/team/debt-board/index.tsx +125 -0
- package/stack-template/app/ui-kit/src/ui/team/inbox-thread/inbox-thread.stories.tsx +70 -0
- package/stack-template/app/ui-kit/src/ui/team/inbox-thread/inbox-thread.test.tsx +56 -0
- package/stack-template/app/ui-kit/src/ui/team/inbox-thread/index.tsx +107 -0
- package/stack-template/app/ui-kit/src/ui/team/ping-feed/index.tsx +102 -0
- package/stack-template/app/ui-kit/src/ui/team/ping-feed/ping-feed.stories.tsx +57 -0
- package/stack-template/app/ui-kit/src/ui/team/ping-feed/ping-feed.test.tsx +60 -0
- package/stack-template/app/ui-kit/src/ui/team/stage-pipeline/index.tsx +60 -0
- package/stack-template/app/ui-kit/src/ui/team/stage-pipeline/stage-pipeline.stories.tsx +68 -0
- package/stack-template/app/ui-kit/src/ui/team/stage-pipeline/stage-pipeline.test.tsx +50 -0
- package/stack-template/app/ui-kit/src/ui/team/team-dashboard/index.tsx +103 -0
- package/stack-template/app/ui-kit/src/ui/team/team-dashboard/team-dashboard.stories.tsx +72 -0
- package/stack-template/app/ui-kit/src/ui/team/team-dashboard/team-dashboard.test.tsx +72 -0
- package/stack-template/app/ui-kit/src/ui/time-picker/index.tsx +143 -0
- package/stack-template/app/ui-kit/src/ui/time-picker/time-picker.stories.tsx +90 -0
- package/stack-template/app/ui-kit/src/ui/time-picker/time-picker.test.tsx +64 -0
- package/stack-template/app/ui-kit/src/ui/timeline/index.tsx +91 -0
- package/stack-template/app/ui-kit/src/ui/timeline/timeline.stories.tsx +209 -0
- package/stack-template/app/ui-kit/src/ui/timeline/timeline.test.tsx +116 -0
- package/stack-template/app/ui-kit/src/ui/timesheet/index.tsx +277 -0
- package/stack-template/app/ui-kit/src/ui/timesheet/timesheet.stories.tsx +97 -0
- package/stack-template/app/ui-kit/src/ui/timesheet/timesheet.test.tsx +103 -0
- package/stack-template/app/ui-kit/src/ui/toggle-button/index.tsx +28 -0
- package/stack-template/app/ui-kit/src/ui/toggle-button/toggle-button-group.stories.tsx +85 -0
- package/stack-template/app/ui-kit/src/ui/toggle-button/toggle-button-group.test.tsx +97 -0
- package/stack-template/app/ui-kit/src/ui/toggle-button/toggle-button-group.tsx +81 -0
- package/stack-template/app/ui-kit/src/ui/toggle-button/toggle-button.stories.tsx +46 -0
- package/stack-template/app/ui-kit/src/ui/toggle-button/toggle-button.test.tsx +38 -0
- package/stack-template/app/ui-kit/src/ui/toolbar/index.tsx +18 -0
- package/stack-template/app/ui-kit/src/ui/toolbar/toolbar.stories.tsx +35 -0
- package/stack-template/app/ui-kit/src/ui/toolbar/toolbar.test.tsx +11 -0
- package/stack-template/app/ui-kit/src/ui/tooltip/index.tsx +61 -0
- package/stack-template/app/ui-kit/src/ui/tooltip/tooltip.stories.tsx +81 -0
- package/stack-template/app/ui-kit/src/ui/tooltip/tooltip.test.tsx +120 -0
- package/stack-template/app/ui-kit/src/ui/tour/index.tsx +210 -0
- package/stack-template/app/ui-kit/src/ui/tour/tour.stories.tsx +153 -0
- package/stack-template/app/ui-kit/src/ui/tour/tour.test.tsx +131 -0
- package/stack-template/app/ui-kit/src/ui/transition/index.tsx +377 -0
- package/stack-template/app/ui-kit/src/ui/transition/transition.stories.tsx +254 -0
- package/stack-template/app/ui-kit/src/ui/transition/transition.test.tsx +285 -0
- package/stack-template/app/ui-kit/src/ui/tree/index.tsx +68 -0
- package/stack-template/app/ui-kit/src/ui/tree/tree.stories.tsx +139 -0
- package/stack-template/app/ui-kit/src/ui/tree/tree.test.tsx +77 -0
- package/stack-template/app/ui-kit/src/ui/tree-select/index.tsx +251 -0
- package/stack-template/app/ui-kit/src/ui/tree-select/tree-select.stories.tsx +105 -0
- package/stack-template/app/ui-kit/src/ui/tree-select/tree-select.test.tsx +174 -0
- package/stack-template/app/ui-kit/src/ui/tree-table/index.tsx +229 -0
- package/stack-template/app/ui-kit/src/ui/tree-table/tree-table.stories.tsx +111 -0
- package/stack-template/app/ui-kit/src/ui/tree-table/tree-table.test.tsx +137 -0
- package/stack-template/app/ui-kit/src/ui/typography/index.tsx +124 -0
- package/stack-template/app/ui-kit/src/ui/typography/typography.stories.tsx +65 -0
- package/stack-template/app/ui-kit/src/ui/typography/typography.test.tsx +117 -0
- package/stack-template/app/ui-kit/src/ui/upload/index.tsx +39 -0
- package/stack-template/app/ui-kit/src/ui/upload/upload-core.tsx +204 -0
- package/stack-template/app/ui-kit/src/ui/upload/upload-dropzone.tsx +79 -0
- package/stack-template/app/ui-kit/src/ui/upload/upload.stories.tsx +67 -0
- package/stack-template/app/ui-kit/src/ui/upload/upload.test.tsx +204 -0
- package/stack-template/app/ui-kit/src/ui/virtual-scroll/index.tsx +86 -0
- package/stack-template/app/ui-kit/src/ui/virtual-scroll/virtual-scroll.stories.tsx +111 -0
- package/stack-template/app/ui-kit/src/ui/virtual-scroll/virtual-scroll.test.tsx +125 -0
- package/stack-template/app/ui-kit/src/ui/watermark/index.tsx +182 -0
- package/stack-template/app/ui-kit/src/ui/watermark/watermark.stories.tsx +96 -0
- package/stack-template/app/ui-kit/src/ui/watermark/watermark.test.tsx +120 -0
- package/stack-template/app/ui-kit/src/utils/array.test.ts +88 -0
- package/stack-template/app/ui-kit/src/utils/array.ts +51 -0
- package/stack-template/app/ui-kit/src/utils/dom.test.tsx +69 -0
- package/stack-template/app/ui-kit/src/utils/dom.ts +38 -0
- package/stack-template/app/ui-kit/src/utils/format.test.ts +63 -0
- package/stack-template/app/ui-kit/src/utils/format.ts +81 -0
- package/stack-template/app/ui-kit/tests/setup.ts +15 -0
- package/stack-template/app/ui-kit/tsconfig.json +18 -0
- package/stack-template/app/ui-kit/tsup.config.ts +37 -0
- package/stack-template/app/ui-kit/vercel.json +6 -0
- package/stack-template/app/ui-kit/vitest.config.ts +22 -0
- package/stack-template/contracts/auth/token-contract.md +119 -0
- package/stack-template/contracts/auth/users.json +35 -0
- package/stack-template/contracts/db/tasks-schema.sql +62 -0
- package/stack-template/contracts/events/fixtures/task.assigned.json +11 -0
- package/stack-template/contracts/events/fixtures/task.assignment_failed.json +11 -0
- package/stack-template/contracts/events/fixtures/task.created.json +12 -0
- package/stack-template/contracts/events/fixtures/task.deleted.json +10 -0
- package/stack-template/contracts/events/fixtures/task.updated.json +12 -0
- package/stack-template/contracts/events/task-events.md +80 -0
- package/stack-template/contracts/openapi/activity.yaml +196 -0
- package/stack-template/contracts/openapi/auth.yaml +310 -0
- package/stack-template/contracts/openapi/tasks.yaml +316 -0
- package/stack-template/contracts/openapi/users.yaml +345 -0
- package/stack-template/docs/adr/0001-mixed-stack.md +14 -0
- package/stack-template/docs/adr/0002-mf-rspack.md +14 -0
- package/stack-template/docs/adr/0003-contract-first.md +14 -0
- package/stack-template/docs/adr/0004-readonly-schema-tradeoff.md +14 -0
- package/stack-template/docs/adr/0005-fail-closed.md +14 -0
- package/stack-template/docs/adr/0006-fire-and-forget-events.md +14 -0
- package/stack-template/docs/adr/0007-fork-not-upgrade.md +14 -0
- package/stack-template/docs/adr/0008-kafka-outbox-saga.md +24 -0
- package/stack-template/docs/adr/0009-ui-kit-split.md +39 -0
- package/stack-template/docs/adr/README.md +15 -0
- package/stack-template/docs/ai/recipes.md +956 -0
- package/stack-template/docs/ai/table-Theming.md +25 -0
- package/stack-template/docs/ai/table-datadisplay-mz.md +20 -0
- package/stack-template/docs/ai/table-feedback.md +20 -0
- package/stack-template/docs/ai/table-forms.md +26 -0
- package/stack-template/docs/git-flow.md +70 -0
- package/stack-template/docs/parity-matrix.md +102 -0
- package/stack-template/docs/superpowers/contexts/auth-real/gap-answer.md +195 -0
- package/stack-template/docs/superpowers/contexts/auth-real/sf-1.md +21 -0
- package/stack-template/docs/superpowers/contexts/auth-real/sf-2.md +21 -0
- package/stack-template/docs/superpowers/contexts/auth-real/sf-3.md +17 -0
- package/stack-template/docs/superpowers/contexts/auth-real/sf-4.md +20 -0
- package/stack-template/docs/superpowers/contexts/auth-real/sf-5.md +21 -0
- package/stack-template/docs/superpowers/contexts/experience-design.md +85 -0
- package/stack-template/docs/superpowers/contexts/sf-1.md +39 -0
- package/stack-template/docs/superpowers/contexts/sf-2.md +42 -0
- package/stack-template/docs/superpowers/contexts/sf-3.md +42 -0
- package/stack-template/docs/superpowers/contexts/sf-4.md +26 -0
- package/stack-template/docs/superpowers/contexts/sf-5.md +36 -0
- package/stack-template/docs/superpowers/contexts/sf-6.md +36 -0
- package/stack-template/docs/superpowers/contexts/sf-7.md +35 -0
- package/stack-template/docs/superpowers/contexts/sf-cin-overview.md +21 -0
- package/stack-template/docs/superpowers/contexts/ui-redesign/sf-1.md +46 -0
- package/stack-template/docs/superpowers/contexts/ui-redesign/sf-2.md +44 -0
- package/stack-template/docs/superpowers/contexts/ui-redesign/sf-3.md +47 -0
- package/stack-template/docs/superpowers/contexts/ui-redesign/sf-4.md +44 -0
- package/stack-template/docs/superpowers/contexts/ui-redesign/sf-5.md +36 -0
- package/stack-template/docs/superpowers/designs/direction-approved.md +11 -0
- package/stack-template/docs/superpowers/designs/ui-redesign/drafts/a-roulette-soundviz.html +353 -0
- package/stack-template/docs/superpowers/designs/ui-redesign/drafts/b-reference.html +347 -0
- package/stack-template/docs/superpowers/designs/ui-redesign/drafts/c-designer.html +375 -0
- package/stack-template/docs/superpowers/designs/ui-redesign/ds-demo.html +140 -0
- package/stack-template/docs/superpowers/designs/ui-redesign-direction.md +93 -0
- package/stack-template/docs/superpowers/improvements-log.md +158 -0
- package/stack-template/docs/superpowers/mindmaps/auth-real.wakii +115 -0
- package/stack-template/docs/superpowers/mindmaps/kafka-outbox-saga.wakii +110 -0
- package/stack-template/docs/superpowers/mindmaps/micro-boilerplate.wakii +171 -0
- package/stack-template/docs/superpowers/mindmaps/ui-redesign.wakii +116 -0
- package/stack-template/docs/superpowers/mindmaps/vu53-cinematic-experience.wakii +32 -0
- package/stack-template/docs/superpowers/plans/2026-10-12-sf-1-contracts-platform-plan.md +44 -0
- package/stack-template/docs/superpowers/plans/2026-10-12-sf-3-spring-svc-impact.md +69 -0
- package/stack-template/docs/superpowers/plans/2026-10-12-sf-3-spring-svc-plan.md +27 -0
- package/stack-template/docs/superpowers/plans/2026-10-12-sf-4-go-svc-plan.md +99 -0
- package/stack-template/docs/superpowers/plans/2026-10-12-sf-5-fe-shell-plan.md +64 -0
- package/stack-template/docs/superpowers/plans/2026-10-12-sf-6-fe-remotes-plan.md +83 -0
- package/stack-template/docs/superpowers/plans/2026-10-12-sf-7-convergence-plan.md +59 -0
- package/stack-template/docs/superpowers/plans/2026-10-12-sf2-node-svc-plan.md +19 -0
- package/stack-template/docs/superpowers/plans/2026-10-13-sf-1-kafka-foundation-plan.md +30 -0
- package/stack-template/docs/superpowers/plans/2026-10-13-sf-1-ui-redesign-plan.md +28 -0
- package/stack-template/docs/superpowers/plans/2026-10-13-sf-2-node-outbox-plan.md +46 -0
- package/stack-template/docs/superpowers/plans/2026-10-13-sf-3-go-consumer-plan.md +31 -0
- package/stack-template/docs/superpowers/plans/2026-10-13-sf-4-spring-tx-plan.md +96 -0
- package/stack-template/docs/superpowers/plans/2026-10-13-sf-5-convergence-plan.md +21 -0
- package/stack-template/docs/superpowers/plans/2026-10-14-sf-2-ui-redesign-plan.md +32 -0
- package/stack-template/docs/superpowers/plans/2026-10-14-sf-3-ui-redesign-plan.md +34 -0
- package/stack-template/docs/superpowers/plans/2026-10-14-sf-5-ui-redesign-plan.md +35 -0
- package/stack-template/docs/superpowers/plans/2026-10-17-auth-real-plan.md +112 -0
- package/stack-template/docs/superpowers/plans/2026-10-17-ui-kit-split-plan.md +18 -0
- package/stack-template/docs/superpowers/reviews/2026-10-18-data-display-coverage.md +52 -0
- package/stack-template/docs/superpowers/reviews/code-reviewer-sf-5-r1.md +65 -0
- package/stack-template/docs/superpowers/reviews/security-audit-sf-5-auth-real.md +39 -0
- package/stack-template/docs/superpowers/specs/2026-10-12-boilerplate-microservice-mfe.md +110 -0
- package/stack-template/docs/superpowers/specs/2026-10-12-sf-3-spring-svc-design.md +160 -0
- package/stack-template/docs/superpowers/specs/2026-10-12-sf-7-convergence-spec.md +114 -0
- package/stack-template/docs/superpowers/specs/2026-10-12-sf2-node-svc-spec.md +42 -0
- package/stack-template/docs/superpowers/specs/2026-10-13-kafka-outbox-saga.md +111 -0
- package/stack-template/docs/superpowers/specs/2026-10-13-ui-redesign.md +173 -0
- package/stack-template/docs/superpowers/specs/2026-10-14-sf-3-ui-redesign.md +46 -0
- package/stack-template/docs/superpowers/specs/2026-10-14-sf-5-ui-redesign.md +30 -0
- package/stack-template/docs/superpowers/specs/2026-10-17-antd-look-tokens.md +28 -0
- package/stack-template/docs/superpowers/specs/2026-10-17-auth-real-design.md +124 -0
- package/stack-template/docs/superpowers/specs/2026-10-17-tailwind-migration.md +32 -0
- package/stack-template/docs/superpowers/specs/2026-10-17-ui-kit-split.md +44 -0
- package/stack-template/docs/superpowers/specs/2026-10-18-0.3.0-release-notes.md +77 -0
- package/stack-template/docs/toolchain.md +28 -0
- package/stack-template/docs/wakii-playbook.md +172 -0
- package/stack-template/docs/walkthrough.md +204 -0
- package/stack-template/orca.yaml +146 -0
- package/stack-template/package.json +19 -0
- package/stack-template/platform/.env.example +72 -0
- package/stack-template/platform/conventions/01-dockerfile-pattern.md +78 -0
- package/stack-template/platform/conventions/02-healthcheck.md +26 -0
- package/stack-template/platform/conventions/03-logging.md +41 -0
- package/stack-template/platform/conventions/04-error-envelope.md +41 -0
- package/stack-template/platform/conventions/05-ports.md +38 -0
- package/stack-template/platform/conventions/06-configuration.md +25 -0
- package/stack-template/platform/conventions/07-cors.md +23 -0
- package/stack-template/platform/conventions/08-gateway-and-remotes.md +33 -0
- package/stack-template/platform/conventions/09-async-messaging.md +42 -0
- package/stack-template/platform/conventions/README.md +15 -0
- package/stack-template/platform/docker-compose.yml +255 -0
- package/stack-template/platform/gateway/nginx/nginx.conf +137 -0
- package/stack-template/platform/postgres/init/01-init.sh +55 -0
- package/stack-template/pnpm-lock.yaml +15992 -0
- package/stack-template/pnpm-workspace.yaml +24 -0
- package/stack-template/scripts/scaffold/scaffold.sh +110 -0
- package/stack-template/scripts/smoke/e2e.sh +305 -0
- package/stack-template/scripts/snapshot-stack-template.sh +84 -0
- package/stack-template/services/auth-svc/.dockerignore +5 -0
- package/stack-template/services/auth-svc/Dockerfile +32 -0
- package/stack-template/services/auth-svc/README.md +101 -0
- package/stack-template/services/auth-svc/drizzle/0000_init.sql +25 -0
- package/stack-template/services/auth-svc/drizzle/meta/0000_snapshot.json +190 -0
- package/stack-template/services/auth-svc/drizzle/meta/_journal.json +13 -0
- package/stack-template/services/auth-svc/drizzle.config.ts +10 -0
- package/stack-template/services/auth-svc/package.json +35 -0
- package/stack-template/services/auth-svc/pnpm-lock.yaml +2425 -0
- package/stack-template/services/auth-svc/src/app.test.ts +403 -0
- package/stack-template/services/auth-svc/src/app.ts +103 -0
- package/stack-template/services/auth-svc/src/auth-crypto.test.ts +32 -0
- package/stack-template/services/auth-svc/src/auth-crypto.ts +25 -0
- package/stack-template/services/auth-svc/src/db/client.ts +24 -0
- package/stack-template/services/auth-svc/src/db/migrate.ts +72 -0
- package/stack-template/services/auth-svc/src/db/schema.ts +39 -0
- package/stack-template/services/auth-svc/src/db/seed.ts +60 -0
- package/stack-template/services/auth-svc/src/env.test.ts +55 -0
- package/stack-template/services/auth-svc/src/env.ts +57 -0
- package/stack-template/services/auth-svc/src/logger.ts +31 -0
- package/stack-template/services/auth-svc/src/plugins/auth.ts +70 -0
- package/stack-template/services/auth-svc/src/repo.drizzle.integration.test.ts +182 -0
- package/stack-template/services/auth-svc/src/repo.drizzle.ts +144 -0
- package/stack-template/services/auth-svc/src/repo.test-support.ts +168 -0
- package/stack-template/services/auth-svc/src/repo.ts +60 -0
- package/stack-template/services/auth-svc/src/routes/auth.ts +193 -0
- package/stack-template/services/auth-svc/src/routes/health.ts +40 -0
- package/stack-template/services/auth-svc/src/server.ts +54 -0
- package/stack-template/services/auth-svc/tsconfig.json +20 -0
- package/stack-template/services/go-svc/.dockerignore +5 -0
- package/stack-template/services/go-svc/Dockerfile +19 -0
- package/stack-template/services/go-svc/README.md +93 -0
- package/stack-template/services/go-svc/cmd/server/main.go +105 -0
- package/stack-template/services/go-svc/go.mod +12 -0
- package/stack-template/services/go-svc/internal/api/auth.go +83 -0
- package/stack-template/services/go-svc/internal/api/auth_test.go +92 -0
- package/stack-template/services/go-svc/internal/api/envelope.go +61 -0
- package/stack-template/services/go-svc/internal/api/envelope_test.go +51 -0
- package/stack-template/services/go-svc/internal/api/fakes_test.go +105 -0
- package/stack-template/services/go-svc/internal/api/feed.go +98 -0
- package/stack-template/services/go-svc/internal/api/feed_test.go +118 -0
- package/stack-template/services/go-svc/internal/api/health.go +34 -0
- package/stack-template/services/go-svc/internal/api/health_test.go +46 -0
- package/stack-template/services/go-svc/internal/api/json.go +13 -0
- package/stack-template/services/go-svc/internal/api/middleware.go +82 -0
- package/stack-template/services/go-svc/internal/api/middleware_test.go +48 -0
- package/stack-template/services/go-svc/internal/api/openapi/activity.yaml +196 -0
- package/stack-template/services/go-svc/internal/api/openapi.go +29 -0
- package/stack-template/services/go-svc/internal/api/openapi_test.go +38 -0
- package/stack-template/services/go-svc/internal/api/router.go +86 -0
- package/stack-template/services/go-svc/internal/api/stats.go +63 -0
- package/stack-template/services/go-svc/internal/api/stats_test.go +83 -0
- package/stack-template/services/go-svc/internal/api/types.go +32 -0
- package/stack-template/services/go-svc/internal/apperr/apperr.go +9 -0
- package/stack-template/services/go-svc/internal/config/config.go +115 -0
- package/stack-template/services/go-svc/internal/config/config_test.go +92 -0
- package/stack-template/services/go-svc/internal/consumer/envelope.go +78 -0
- package/stack-template/services/go-svc/internal/consumer/envelope_test.go +154 -0
- package/stack-template/services/go-svc/internal/consumer/handler.go +91 -0
- package/stack-template/services/go-svc/internal/consumer/handler_test.go +136 -0
- package/stack-template/services/go-svc/internal/consumer/producer.go +117 -0
- package/stack-template/services/go-svc/internal/consumer/runner.go +194 -0
- package/stack-template/services/go-svc/internal/consumer/runner_test.go +351 -0
- package/stack-template/services/go-svc/internal/logging/logging.go +49 -0
- package/stack-template/services/go-svc/internal/model/model.go +37 -0
- package/stack-template/services/go-svc/internal/resolve/resolver.go +134 -0
- package/stack-template/services/go-svc/internal/resolve/resolver_test.go +82 -0
- package/stack-template/services/go-svc/internal/resolve/token.go +130 -0
- package/stack-template/services/go-svc/internal/resolve/token_test.go +151 -0
- package/stack-template/services/go-svc/internal/store/events.go +71 -0
- package/stack-template/services/go-svc/internal/store/migrate.go +90 -0
- package/stack-template/services/go-svc/internal/store/migrate_test.go +34 -0
- package/stack-template/services/go-svc/internal/store/migrations/0001_create_events.sql +20 -0
- package/stack-template/services/go-svc/internal/store/migrations/0002_widen_action_cascade.sql +14 -0
- package/stack-template/services/go-svc/internal/store/store.go +65 -0
- package/stack-template/services/go-svc/internal/store/tasks.go +109 -0
- package/stack-template/services/go-svc/internal/swagger/assets/LICENSE +202 -0
- package/stack-template/services/go-svc/internal/swagger/assets/NOTICE +2 -0
- package/stack-template/services/go-svc/internal/swagger/assets/favicon-16x16.png +0 -0
- package/stack-template/services/go-svc/internal/swagger/assets/favicon-32x32.png +0 -0
- package/stack-template/services/go-svc/internal/swagger/assets/swagger-ui-bundle.js +2 -0
- package/stack-template/services/go-svc/internal/swagger/assets/swagger-ui.css +3 -0
- package/stack-template/services/go-svc/internal/swagger/index.html +28 -0
- package/stack-template/services/go-svc/internal/swagger/swagger.go +38 -0
- package/stack-template/services/go-svc/test/integration/integration_test.go +523 -0
- package/stack-template/services/node-svc/.dockerignore +5 -0
- package/stack-template/services/node-svc/Dockerfile +27 -0
- package/stack-template/services/node-svc/README.md +155 -0
- package/stack-template/services/node-svc/drizzle/0000_init.sql +17 -0
- package/stack-template/services/node-svc/drizzle/0001_status-assignment-failed.sql +2 -0
- package/stack-template/services/node-svc/drizzle/0002_outbox-table.sql +7 -0
- package/stack-template/services/node-svc/drizzle/meta/0000_snapshot.json +136 -0
- package/stack-template/services/node-svc/drizzle/meta/0001_snapshot.json +136 -0
- package/stack-template/services/node-svc/drizzle/meta/0002_snapshot.json +180 -0
- package/stack-template/services/node-svc/drizzle/meta/_journal.json +27 -0
- package/stack-template/services/node-svc/drizzle.config.ts +10 -0
- package/stack-template/services/node-svc/package.json +39 -0
- package/stack-template/services/node-svc/pnpm-lock.yaml +2706 -0
- package/stack-template/services/node-svc/src/app.test.ts +611 -0
- package/stack-template/services/node-svc/src/app.ts +126 -0
- package/stack-template/services/node-svc/src/clients/spring.ts +53 -0
- package/stack-template/services/node-svc/src/compensation-consumer.test.ts +157 -0
- package/stack-template/services/node-svc/src/compensation-consumer.ts +170 -0
- package/stack-template/services/node-svc/src/db/client.ts +23 -0
- package/stack-template/services/node-svc/src/db/migrate.ts +63 -0
- package/stack-template/services/node-svc/src/db/schema-diff.test.ts +252 -0
- package/stack-template/services/node-svc/src/db/schema.ts +64 -0
- package/stack-template/services/node-svc/src/env.ts +52 -0
- package/stack-template/services/node-svc/src/logger.ts +18 -0
- package/stack-template/services/node-svc/src/outbox-relay.test.ts +141 -0
- package/stack-template/services/node-svc/src/outbox-relay.ts +182 -0
- package/stack-template/services/node-svc/src/plugins/auth.ts +76 -0
- package/stack-template/services/node-svc/src/repo.drizzle.test.ts +182 -0
- package/stack-template/services/node-svc/src/repo.drizzle.ts +158 -0
- package/stack-template/services/node-svc/src/repo.ts +73 -0
- package/stack-template/services/node-svc/src/routes/health.ts +42 -0
- package/stack-template/services/node-svc/src/routes/tasks.ts +287 -0
- package/stack-template/services/node-svc/src/server.ts +91 -0
- package/stack-template/services/node-svc/src/types/api.d.ts +391 -0
- package/stack-template/services/node-svc/src/types/log.ts +3 -0
- package/stack-template/services/node-svc/tsconfig.json +20 -0
- package/stack-template/services/spring-svc/.dockerignore +5 -0
- package/stack-template/services/spring-svc/.mvn/wrapper/maven-wrapper.properties +20 -0
- package/stack-template/services/spring-svc/Dockerfile +22 -0
- package/stack-template/services/spring-svc/README.md +121 -0
- package/stack-template/services/spring-svc/mvnw +332 -0
- package/stack-template/services/spring-svc/mvnw.cmd +206 -0
- package/stack-template/services/spring-svc/pom.xml +144 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/SpringSvcApplication.java +12 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/domain/Team.java +64 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/domain/TeamRepository.java +34 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/domain/User.java +72 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/domain/UserRepository.java +10 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/logging/LowercaseLevelJsonProvider.java +24 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/security/JwtAuthFilter.java +89 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/security/JwtVerifier.java +48 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/service/TeamService.java +84 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/ApiError.java +15 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/ApiException.java +37 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/DevCorsConfig.java +41 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/ErrorEnvelope.java +27 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/GlobalExceptionHandler.java +90 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/HealthController.java +46 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/ReadinessService.java +40 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/TeamController.java +79 -0
- package/stack-template/services/spring-svc/src/main/java/com/example/springsvc/web/UserController.java +187 -0
- package/stack-template/services/spring-svc/src/main/java/db/migration/V2__SeedUsers.java +66 -0
- package/stack-template/services/spring-svc/src/main/resources/application.yml +42 -0
- package/stack-template/services/spring-svc/src/main/resources/db/migration/V1__init.sql +24 -0
- package/stack-template/services/spring-svc/src/main/resources/logback-spring.xml +34 -0
- package/stack-template/services/spring-svc/src/main/resources/openapi/users.yaml +345 -0
- package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/logging/LogShapeTest.java +39 -0
- package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/security/JwtAuthFilterTest.java +106 -0
- package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/seed/SeedMatchIntegrationTest.java +68 -0
- package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/service/TeamServiceRollbackTest.java +122 -0
- package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/web/DevCorsTest.java +45 -0
- package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/web/HealthCheckTest.java +56 -0
- package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/web/TeamApiTest.java +139 -0
- package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/web/TestPingController.java +21 -0
- package/stack-template/services/spring-svc/src/test/java/com/example/springsvc/web/UserApiTest.java +182 -0
- package/stack-template/stack-manifest.json +285 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Decision: design language = antd look (light default) — supersede direction B làm theme phụ
|
|
2
|
+
|
|
3
|
+
Ngày: 2026-10-17 · Trạng thái: APPROVED (chat) · Supersede phần visual của direction B (VU-53)
|
|
4
|
+
|
|
5
|
+
## Quyết định
|
|
6
|
+
|
|
7
|
+
User chốt: "UI cần giống y như antd" + chọn phương án **Clone antd look trên components
|
|
8
|
+
tự viết + Tailwind** (không install antd, không giữ dark-only).
|
|
9
|
+
|
|
10
|
+
1. **tokens.css đổi GIÁ TRỊ sang visual language antd v5/v6 default (light)** — var names
|
|
11
|
+
GIỮ NGUYÊN (components/tests/tailwind @theme không đụng mã):
|
|
12
|
+
- accent `#1677ff` (antd colorPrimary), hover `#4096ff`
|
|
13
|
+
- canvas `#f5f5f5` (colorBgLayout), container `#ffffff`, hover-fill `#fafafa`
|
|
14
|
+
- ink `rgba(0,0,0,.88)` / `.65` / `.45`; line `#d9d9d9` / line2 `#f0f0f0`
|
|
15
|
+
- status: todo gray `#bfbfbf`, doing `#faad14`, done `#52c41a`, fail `#ff4d4f`
|
|
16
|
+
- font stack antd, base 14px; radius 4/6/8 giữ
|
|
17
|
+
2. **Direction B hiện tại (dark) trở thành THEME PHỤ** — `styles/themes/dark.css` scoped
|
|
18
|
+
`[data-bp-theme='dark']` (giá trị = tokens direction B cũ y nguyên). Switching =
|
|
19
|
+
Phase theming (UiKitProvider theme='light'|'dark').
|
|
20
|
+
3. Structural antd-ness (shadow popover/modal, hover lifts) đi kèm phase migrate
|
|
21
|
+
components/pages — token `--shadow-1` thêm khi phase đó cần.
|
|
22
|
+
4. Token docs page + storybook preview chuyển light default, giữ story dark demo.
|
|
23
|
+
|
|
24
|
+
## Hệ quả
|
|
25
|
+
|
|
26
|
+
- Pixel của VU-53 evidence (screenshots dark) không còn là current look — archive giữ
|
|
27
|
+
nguyên trong docs/superpowers/evidence (lịch sử).
|
|
28
|
+
- prefers-color-scheme / theme switching: Phase theming quyết (không auto-switch giờ).
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Spec: Epic Auth thật thay auth-mock
|
|
2
|
+
|
|
3
|
+
Ngày: 2026-10-17 · Trạng thái: **rev 2** — spec-critic + plan-critic FIX-P0 đã xử (PR #13) ·
|
|
4
|
+
Archetype: **CC — Cross-cutting contract** (wakii-playbook §2) · Story epic đầu tiên áp dụng playbook.
|
|
5
|
+
|
|
6
|
+
## Bối cảnh
|
|
7
|
+
|
|
8
|
+
auth-mock là JWT HS256 NOT-FOR-PROD: password dev chung, không refresh, không register,
|
|
9
|
+
không revoke. Là điểm yếu #1 khi scaffold boilerplate sang project thật (CLAUDE.md đánh giá
|
|
10
|
+
2026-10-17). Epic này thay bằng service auth thật, giữ nguyên surface `/api/auth/*` :8090
|
|
11
|
+
để gateway/port-table/FE-flow không đổi.
|
|
12
|
+
|
|
13
|
+
## Quyết định đã chốt (user, chat 2026-10-17)
|
|
14
|
+
|
|
15
|
+
| # | Quyết định | Chọn | Không chọn |
|
|
16
|
+
|---|---|---|---|
|
|
17
|
+
| 1 | Scope MVP | **Full MVP**: register + login + refresh (rotation) + RBAC demo + decommission auth-mock | login-only; không-refresh |
|
|
18
|
+
| 2 | Port + path | **auth-svc đón :8090 `/api/auth/*`** — gateway/env/README không đổi, port 4-chỗ không kích hoạt | port mới :8091 song song |
|
|
19
|
+
| 3 | Users schema | **auth-svc owns schema `auth` riêng** (users + refresh_tokens), seed từ users.json GIỮ UUID | spring owns; gộp vào spring |
|
|
20
|
+
| 4 | Refresh mechanism | **Opaque + rotation + revoke** — CAS atomic, reuse → revoke **toàn bộ token của user** (strict) | JWT pair; chain-only revoke |
|
|
21
|
+
| 5 | FE READ-LOCKED | **Wrapper `refresh-client.ts` file mới** — token-storage.ts API đã đủ | sửa token-storage.ts |
|
|
22
|
+
| 6 | Ngôn ngữ | **Node Fastify + TS + Drizzle** (mirror node-svc) | Go + chi |
|
|
23
|
+
| 7 | *(rev 2)* **`iss` claim** | **PIN `iss: "auth-mock"`** — 3 service + 2 CI workflows hardcode giá trị này; đổi tên = rework 3 vùng + rework CI. Follow-up nhỏ riêng (đổi 3 constant + workflows) khi có SF chạm cả 3 vùng | đổi thành "auth-svc"; env-ify ngay trong epic |
|
|
24
|
+
| 8 | *(rev 2)* **Response shape v2** | `{user, accessToken, refreshToken}` — **drop `tokenType`/`expiresIn`** (e2e chỉ cần accessToken); FE SF-4 cập nhật theo | giữ tokenType/expiresIn |
|
|
25
|
+
| 9 | *(rev 2)* **auth.yaml v1 paths** | **Giữ `GET /users`** (FE demo picker — auth-svc serve từ schema auth); **drop `/.well-known/openid-configuration`** (không ai consume; path OIDC ghi token-contract) | giữ cả 2 |
|
|
26
|
+
| 10 | *(rev 2)* **Password compat** | `AUTH_DEV_PASSWORD` default **`demo-password`** (`${AUTH_DEV_PASSWORD:-demo-password}`) — e2e + svc-activity + fixture seed cùng một nguồn | default `change-me-auth` |
|
|
27
|
+
|
|
28
|
+
Token claims `sub/email/roles` giữ nguyên shape; HS256 giữ nguyên. Access TTL **8h → 30m**;
|
|
29
|
+
token cũ cùng `iss` vẫn verify trong chuyển tiếp. Refresh TTL **7d** (tầng contract).
|
|
30
|
+
|
|
31
|
+
## Kiến trúc
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
auth-svc (mới, :8090 /api/auth/* — workspace member, standalone lockfile như node-svc)
|
|
35
|
+
schema auth (role auth_svc — schema-only, custom migrate runner như node-svc):
|
|
36
|
+
users (id UUID PK ← fixture UUID GIỮ NGUYÊN, email UNIQUE lowercase-normalized,
|
|
37
|
+
display_name, roles text[] NOT NULL DEFAULT '{"user"}',
|
|
38
|
+
password_hash argon2id, created_at)
|
|
39
|
+
refresh_tokens (id uuid PK, user_id FK, token_hash sha256, expires_at,
|
|
40
|
+
revoked_at NULL, replaced_by uuid NULL, created_at)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
- **Seed**: từ `contracts/auth/users.json` — giữ nguyên UUID + displayName + roles;
|
|
44
|
+
password = `AUTH_DEV_PASSWORD` (default demo-password); **users.json KHÔNG thêm password**;
|
|
45
|
+
idempotent `ON CONFLICT (id) DO NOTHING`.
|
|
46
|
+
- **Rotation atomic (CAS)**: `UPDATE auth.refresh_tokens SET revoked_at=now(), replaced_by=$new
|
|
47
|
+
WHERE id=$old AND revoked_at IS NULL RETURNING` — 0 rows = **reuse-detect** → revoke tất cả
|
|
48
|
+
refresh_tokens của user + 401. 2 tab refresh đồng thời: request thua CAS điReuse-detect
|
|
49
|
+
(chấp nhận strict — FE single-flight lock giảm xác suất; documented).
|
|
50
|
+
- **spring-svc giữ users table của nó** cho demo @Transactional — cùng UUID từ fixture,
|
|
51
|
+
không sync runtime (roles source-of-truth = token claims).
|
|
52
|
+
- **svc-activity** (go-svc) login đúng flow cũ, password = cùng `AUTH_DEV_PASSWORD`
|
|
53
|
+
(users.json $comment đã ghi pattern này).
|
|
54
|
+
- **Register**: roles gán `["user"]`; email normalize lowercase trước lưu/lookup;
|
|
55
|
+
password 8–72 ký tự (argon2 input limit).
|
|
56
|
+
|
|
57
|
+
## API (contracts/openapi/auth.yaml v2 — SF-1)
|
|
58
|
+
|
|
59
|
+
| Endpoint | Body | Response / Note |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| `POST /api/auth/register` | {email, password(8–72), displayName} | 201 `{user, accessToken, refreshToken}`; 409 email trùng |
|
|
62
|
+
| `POST /api/auth/login` | {email, password} | 200 same shape; 401 sai thông tin |
|
|
63
|
+
| `POST /api/auth/refresh` | {refreshToken} | 200 cặp mới (CAS rotation); reuse → 401 + revoke-all |
|
|
64
|
+
| `POST /api/auth/logout` | {refreshToken} | 204 — **idempotent** (token đã revoked vẫn 204) |
|
|
65
|
+
| `POST /api/auth/logout-all` | (Bearer) | 204 revoke tất cả của `sub` |
|
|
66
|
+
| `GET /api/auth/users` | — | **giữ v1** — danh sách user demo (auth-svc serve từ schema auth) |
|
|
67
|
+
| `GET /healthz` + `/readyz` | — | mirror naked + prefix (conventions/02 rule 6) |
|
|
68
|
+
| ~~`/.well-known/openid-configuration`~~ | — | **drop** (không ai consume; path OIDC ở token-contract.md) |
|
|
69
|
+
|
|
70
|
+
**RBAC demo:** node-svc `DELETE /api/tasks/:id` yêu cầu roles chứa `admin` — alice admin
|
|
71
|
+
(e2e hiện tại giữ pass), bob → 403 (assert thêm). Gateway vẫn chỉ presence-check.
|
|
72
|
+
|
|
73
|
+
**FE (SF-4):** `app/shared/src/refresh-client.ts` (file MỚI): login/register lưu cặp
|
|
74
|
+
(access → tokenStorage; refresh → `localStorage['bp.rt']` — key mới, rationale pin vào
|
|
75
|
+
token-contract.md v2 để security-pass không mở lại); 401 → refresh single-flight đúng
|
|
76
|
+
một lần → retry; logout gọi endpoint + clear 2 key. `token-storage.ts` READ-LOCKED không đổi.
|
|
77
|
+
|
|
78
|
+
## CI ownership (rev 2 — P0 spec-critic + plan-critic)
|
|
79
|
+
|
|
80
|
+
| File | SF sở hữu | Thay đổi |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| `.github/workflows/contracts.yml` | **SF-1** | schemathesis scope hẹp lại (chỉ paths auth-mock đã implement — mới thêm sẽ 404); **SF-5**: boot auth-svc thay auth-mock + bỏ assert `"iss"` nếu cần |
|
|
83
|
+
| `.github/workflows/services-auth-svc.yml` | **SF-2 (tạo mới)** | từ workflow-templates: build + test + docker build + boot-smoke |
|
|
84
|
+
| `.github/workflows/services-node-svc.yml` | — không đổi | test payload `iss: "auth-mock"` — vẫn đúng (iss pinned) |
|
|
85
|
+
| `.github/workflows/services-go-svc.yml` + `services-spring-svc.yml` | **SF-5** | boot auth-svc thay auth-mock (tên container) |
|
|
86
|
+
|
|
87
|
+
Chấp thuận gates: `iss` pinned → node workflow payload không đổi ✓.
|
|
88
|
+
|
|
89
|
+
## SF tier bracket (story mode — 5 SF)
|
|
90
|
+
|
|
91
|
+
| SF | Tier | Nội dung | Gate chính |
|
|
92
|
+
|---|---|---|---|
|
|
93
|
+
| SF-1 | 0 | auth.yaml v2 + token-contract.md v2 (iss pinned, TTLs, rotation/CAS/reuse, bp.rt rationale) + gap-answer ĐẦY ĐỦ (compose entry + depends_on key + nginx upstream + go-svc `AUTH_MOCK_URL` value + users.json mount + init role `auth_svc` + .env rename AUTH_MOCK_* + workspace line + **contracts.yml schemathesis scope**) | spectral + schemathesis scoped |
|
|
94
|
+
| SF-2 | 1 | auth-svc: schema + seed + 5 endpoints + CAS rotation + reuse-detect + **services-auth-svc.yml workflow** | workflow mới xanh + tests |
|
|
95
|
+
| SF-3 | 1 | node-svc RBAC DELETE admin-only + 403 tests | node suite |
|
|
96
|
+
| SF-4 | 1 | FE refresh-client + LoginPage register tab + auto-refresh + a11y | shell suite + coverage gate (90/90/80/90) + a11y |
|
|
97
|
+
| SF-5 | 2 | convergence: e2e mở rộng + decommission (thực thi gap-answer: compose/nginx/go-env/users-mount/init/.env renames) + **CI swap 3 workflows** + docs sync rộng (walkthrough, CLAUDE.md, orca.yaml, README, toolchain, gotcha `down -v`) + security pass | e2e + CI toàn main xanh + human walkthrough |
|
|
98
|
+
|
|
99
|
+
## Điều kiện chấp nhận (epic DONE)
|
|
100
|
+
|
|
101
|
+
1. `pnpm lint:contracts` xanh; schemathesis auth.yaml PASS (scoped SF-1, full SF-5).
|
|
102
|
+
2. auth-svc: register→login→refresh→reuse-old→401+revoke-all; logout idempotent 204;
|
|
103
|
+
logout-all hết hiệu lực — integration test chứng minh từng bước.
|
|
104
|
+
3. e2e 2 chiều hiện tại PASS không sửa (login đọc `accessToken` ✓; password default
|
|
105
|
+
demo-password ✓; iss pinned ✓).
|
|
106
|
+
4. DELETE task bằng bob → 403 envelope; alice → 200 (unit SF-3 + e2e SF-5).
|
|
107
|
+
5. FE: access hết hạn → auto-refresh đúng 1 lần không 401 UI; logout-all → **các tab khác
|
|
108
|
+
chết ở request kế tiếp (401 → refresh fail → về login)** — verify qua human walkthrough
|
|
109
|
+
2 tab (không claim cross-tab realtime).
|
|
110
|
+
6. compose boot auth-svc healthcheck xanh; **volume postgres cũ cần `down -v` 1 lần
|
|
111
|
+
(gotcha mới vào orca.yaml + walkthrough)**.
|
|
112
|
+
7. Security pass 0 P0/P1: argon2id, rotation CAS, reuse-detect, không log password/refresh,
|
|
113
|
+
**localStorage `bp.rt` = accepted-for-demo (rationale pin trong token-contract.md —
|
|
114
|
+
httpOnly-cookie là upgrade path ghi rõ)**.
|
|
115
|
+
8. Docs sync rộng: walkthrough + CLAUDE.md + orca.yaml + README + toolchain + `.env.example`
|
|
116
|
+
(rename AUTH_MOCK_*) + grep `auth-mock` = rỗng trên docs + `.env.example` + workflows
|
|
117
|
+
(token-contract/users.json giữ histórico tên trong $comment nếu cần).
|
|
118
|
+
9. *(rev 2)* **CI toàn main xanh sau SF-5 merge** (contracts/go/spring swap auth-svc boot).
|
|
119
|
+
|
|
120
|
+
## Non-goals
|
|
121
|
+
|
|
122
|
+
OAuth/OIDC (RS256/JWKS — path token-contract.md), password reset qua email, rate-limit
|
|
123
|
+
distributed, multi-tenant, đổi claims shape, **đổi `iss` string (follow-up riêng)**,
|
|
124
|
+
httpOnly-cookie storage (upgrade path ghi token-contract.md).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Spec: Tailwind v4 migration — toàn bộ app styling
|
|
2
|
+
|
|
3
|
+
Ngày: 2026-10-17 · Trạng thái: APPROVED (chat cùng ngày) · Bổ sung cho: ui-kit-split spec + 4-phase plan (vẫn đúng, styling cơ chế đổi)
|
|
4
|
+
|
|
5
|
+
## Quyết định (user đã chọn)
|
|
6
|
+
|
|
7
|
+
1. **Tailwind áp dụng TOÀN BỘ app** — primitives ui-kit + pages shell/remotes; xoá dần
|
|
8
|
+
scoped css `.tsk-*` / `.sh-*` / `.act-*` và section primitives `bp-*` của base.css.
|
|
9
|
+
2. **tokens.css giữ làm NGUỒN DUY NHẤT** — Tailwind v4 `@theme inline` map thẳng
|
|
10
|
+
`var(--accent)`, `var(--ink2)`… → utilities (`bg-accent`, `text-ink2`) tự theo tokens;
|
|
11
|
+
accent-override runtime (Phase theming) hoạt động không đổi config.
|
|
12
|
+
3. Tailwind **v4** (CSS-first, `@import "tailwindcss"`): PostCSS plugin cho 3 app Rspack
|
|
13
|
+
(`@tailwindcss/postcss` + postcss-loader), Vite plugin cho Storybook (`@tailwindcss/vite`).
|
|
14
|
+
4. **Preflight KHÔNG bật** giai đoạn đầu — giữ reset hiện có của base.css để tránh visual
|
|
15
|
+
shift hàng loạt; cân nhắc đổi sau khi mọi trang đã Tailwind (story riêng).
|
|
16
|
+
5. Phase 重排 (build Tailwind-first tránh double-styling):
|
|
17
|
+
- **P0 infra**: @theme + postcss/vite wiring + `@source` cho app/ui-kit sources + proof
|
|
18
|
+
1 primitive (Badge) end-to-end (test + storybook + app build)
|
|
19
|
+
- **P1**: 4 primitives còn lại + `BusyBox` + `className/classNames/style` props + a11y
|
|
20
|
+
addon gate; USAGE.md
|
|
21
|
+
- **P2**: `Tag.Checkable` thay chips Tasks; `Button`; `Input/Textarea` (born Tailwind)
|
|
22
|
+
- **P3**: refactor shell pages (styles.css → utilities, xoá sh-*)
|
|
23
|
+
- **P4**: refactor tasks + activity pages (xoá tsk-*/act-*), base.css chỉ còn reset/global
|
|
24
|
+
- **P5**: `UiKitProvider` accent-override + tokens docs page bản Tailwind
|
|
25
|
+
6. Mỗi phase = 1 PR riêng (git-flow), evidence đối chiếu storybook/screenshot giữ pixel
|
|
26
|
+
direction B. Tests đang select theo class `bp-*`/`tsk-*` đổi sang role/structure/API props.
|
|
27
|
+
|
|
28
|
+
## Non-goals
|
|
29
|
+
|
|
30
|
+
- Không đổi design direction B (màu/spacing/radius/typography giữ tokens)
|
|
31
|
+
- Không dùng tailwind.config.js (v4 CSS-first); không CSS-in-JS runtime
|
|
32
|
+
- Không preflight trong phase đầu
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Spec: tách UI kit thành package riêng + Storybook Phase 1
|
|
2
|
+
|
|
3
|
+
Ngày: 2026-10-17 · Trạng thái: APPROVED (design duyệt trong chat cùng ngày) · Nguồn: thảo luận "lib UI cần storybook?" + "base component cần tách thư viện riêng"
|
|
4
|
+
|
|
5
|
+
## Bối cảnh
|
|
6
|
+
|
|
7
|
+
Sau story VU-53, design system (tokens + base + 4 primitives) sống trong `app/shared`
|
|
8
|
+
cùng 4 file logic READ-LOCKED (api-client/token-storage/error-envelope/mf-bootstrap).
|
|
9
|
+
Boundary "design system ≠ logic" bị trộn — SF design-system sau này phải đụng package
|
|
10
|
+
có vùng cấm. Đồng thời primitives chỉ được review qua screenshot ad-hoc, không có
|
|
11
|
+
catalog sống.
|
|
12
|
+
|
|
13
|
+
## Quyết định (đã duyệt)
|
|
14
|
+
|
|
15
|
+
1. **Package mới `app/ui-kit` (`@wakii/ui-kit`)**: `src/ui/*` (Badge/EmptyState/Skeleton/
|
|
16
|
+
Spinner) + `src/styles/{tokens,base}.css`. `app/shared` giữ 4 file logic (READ-LOCKED
|
|
17
|
+
không đổi nội dung).
|
|
18
|
+
2. **Consumption QUA SOURCE** — giống fe-shared: main/types → src/, không build, không
|
|
19
|
+
runtime dep (react types do consumer cung cấp; devDeps react chỉ cho test).
|
|
20
|
+
3. **Consumers đổi thẳng import** — không re-export cầu: UI stuff từ `@wakii/ui-kit`,
|
|
21
|
+
logic từ `@wakii/fe-shared`. 3 consumers (shell, remote-tasks, remote-activity).
|
|
22
|
+
4. **Storybook 9 + Vite builder trong ui-kit** (kèm luôn, không phase sau): stories cho
|
|
23
|
+
4 primitives (đủ variants/states) + trang docs tokens. KHÔNG: stories cho MF views,
|
|
24
|
+
visual-regression trả phí. Spike rút gọn: storybook dev-only, không đụng MF runtime
|
|
25
|
+
pin-matrix — evidence = build-storybook PASS + dev screenshot, ghi trong commit.
|
|
26
|
+
5. Hạ tầng: Dockerfiles ×3 COPY ui-kit (lockfile importer cần package.json khi install
|
|
27
|
+
frozen trong container); convergence copy-dir typecheck standalone CẢ fe-shared LẪN
|
|
28
|
+
ui-kit (pattern @types/react + --jsx đã fix); CI workflow `ui-kit` mới (typecheck +
|
|
29
|
+
test + build-storybook gate); ADR-0009; descriptor sync (CLAUDE.md, orca.yaml,
|
|
30
|
+
agents/fe-dev, scaffold).
|
|
31
|
+
|
|
32
|
+
## Điều kiện chấp nhận
|
|
33
|
+
|
|
34
|
+
- `pnpm install --frozen-lockfile` PASS; 3 FE suites + typecheck + build xanh từ paths mới
|
|
35
|
+
- `bash scripts/smoke/e2e.sh` PASS trên compose rebuild (shell render primitives từ ui-kit)
|
|
36
|
+
- `pnpm --filter @wakii/ui-kit build-storybook` PASS trong CI; stories cover mọi variants
|
|
37
|
+
- fe-shared standalone typecheck (copy-dir) vẫn PASS — không còn TS6142 sau khi ui/*
|
|
38
|
+
rời đi; ui-kit standalone typecheck PASS với pattern @types/react
|
|
39
|
+
- Scaffold: project mới nhận ui-kit + storybook build được (CI scaffold-verify che build shell)
|
|
40
|
+
|
|
41
|
+
## Non-goals
|
|
42
|
+
|
|
43
|
+
- Build step/publish registry cho ui-kit; stories cho TasksPage/ActivityPage; Chromatic
|
|
44
|
+
hoặc visual-regression; đổi MF pin-matrix.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# @wakii/ui-kit 0.3.0 — Release notes (NHÁP)
|
|
2
|
+
|
|
3
|
+
> Draft 2026-10-18 — tổng hợp từ `CHANGELOG.md` `[Unreleased]` (story VU-53 UI redesign,
|
|
4
|
+
> 2026-10-17/18). **Đối chiếu chéo lần 2 với CHANGELOG (changelog = chân lý): counts/story
|
|
5
|
+
> liệu khớp từng bullet; hash ngoài changelog được verify bằng `git log` thật.**
|
|
6
|
+
> PR: [#55](https://github.com/__STACK_ORG__/architecture-overview/pull/55)
|
|
7
|
+
|
|
8
|
+
## Breaking changes
|
|
9
|
+
|
|
10
|
+
**None.** 0.2.x consumers upgrade không phải đổi gì: mọi API mới là additive; đổi tên
|
|
11
|
+
trong chu kỳ (`Collapse` transition → `CollapseTransition` barrel, precedent `UiImage`)
|
|
12
|
+
xảyra TRƯỚC release nên không consumer nào ngoài đang dùng tên cũ; legacy prop
|
|
13
|
+
`scrollHeight` của Table vẫn nhận (ưu tiên thấp hơn `scroll.y` mới).
|
|
14
|
+
|
|
15
|
+
## Số liệu (đếm thật 2026-10-18)
|
|
16
|
+
|
|
17
|
+
| Chỉ số | Giá trị | Nguồn |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| Titles Storybook | **129** | `index.json` unique titles (hôm nay) |
|
|
20
|
+
| Story exports | **623** | `index.json` ids non-docs (750 ids gồm docs pages) |
|
|
21
|
+
| Template stories | **18 entries / 4 templates live** | nhóm Templates (Dashboard · Kanban Project · CRUD Table · Auth) |
|
|
22
|
+
| Test files | **136** (`*.test.ts*`) | `find src -name "*.test.ts*"` — README badge 540+ behavior tests |
|
|
23
|
+
| Component mới chu kỳ 0.3.0 | **50+** | đếm từ CHANGELOG `[Unreleased]` + git log (liệt kê dưới) |
|
|
24
|
+
| Storybook test-runner | 215/215 stories render-verified | README § Quality |
|
|
25
|
+
|
|
26
|
+
## 1. Component mới (50+)
|
|
27
|
+
|
|
28
|
+
**Data / grid / tree:** `List` + `AvatarGroup` + `TreeSelect` — 28 tests (`530a4a1`) · `VirtualScroll` + Table `virtual` (`b8fd380`) · `Table` `expandable` — 28 tests + 19 stories (Gap P0, worker W6; commit `6545bf8`) · `Table` advanced: `scroll.y` fixed header + `summary` tfoot + sorting 3-state — 12 tests + 4 stories (worker W6) · `TreeTable` đệ quy + `Layout` frame (`b73d2e6`) · `Timesheet` — 9 tests + 7 stories (`dd740e5`) · `KanbanBoard` + DragDrop primitives — 25 tests + 10 stories (`1782a5d`, `a8e6fd1`) · `OrgChart` — 8 tests + 4 stories (`7e3d0ec`) · `Accordion` single/multiple — 9 tests + 6 stories (`03e8ad2`)
|
|
29
|
+
|
|
30
|
+
**Forms:** `useForm` + peer-dep zod ^4 — 9 tests (`375baae`) · `useFieldArray` (Form.List parity, `append/remove/move/swap/update/nameAt` + lỗi đi theo ROW) — 12 tests + 3 stories (`8c5f716`) · `Field` (`5615a9b`) · `DatePicker` range/showTime + `TimePicker` + locale vi/en — 25 tests (`f4d1883`) · `InputNumber` restyle stepper (`ab76cfe`) · `Checkbox` tri-state — 4 tests (bộ 7→11) (`4b85830`) · `Input.Search` (`6545bf8`)
|
|
31
|
+
|
|
32
|
+
**Navigation / menu:** `Menu` đa cấp + `Sidebar` collapsible — 24 tests + 7 stories (`11bb127`) · `MegaMenu` + `SlideMenu` — 14 tests (8+6) + 9 stories (`7e3d0ec`) · `Pagination` antd redesign 32px (`ab76cfe`) · `ContextMenu` keyboard nav + `Dropdown` đồng bộ + `Tree/Steps/TabMenu/Menubar/Timeline` a11y pass (`1a086a8`)
|
|
33
|
+
|
|
34
|
+
**Overlay / feedback:** `Popover` (`291ce0d`) · `Watermark` SVG data-URI (`291ce0d`) · `Alert` `filled` + tokenize `--alert-*-filled` (`ab76cfe` + `1a086a8`) · `FloatButton`(+/`Group`/BackTop) · `BottomNavigation` · `Fieldset` · `DeferredContent` — 26 tests + 16 stories (`70f1f36`)
|
|
35
|
+
|
|
36
|
+
**Drag & drop / qr / tour:** `DragDropProvider`/`Draggable`/`DropZone` — tính trong bộ 25 tests trên (`1782a5d`) · `QRCode` vendored — 11 tests + 5 stories (worker W6, `6545bf8`) · `Tour` spotlight (`b0eb469`)
|
|
37
|
+
|
|
38
|
+
**Motion (0 deps, transform/opacity only):** `Fade`/`Zoom`/`CollapseTransition`/`Backdrop` — 13 tests (10+3) + 7 stories (`157cfc2`) · `Parallax`/`Reveal`/`CountUp` — 23 tests (7+8+8) + 13 stories (`47e1f55`) — `prefers-reduced-motion` toàn bộ
|
|
39
|
+
|
|
40
|
+
**Layout / grid:** `Row`/`Col` 24-col responsive · `Flex` · `Anchor` scroll-spy — 35 tests + stories EN (`4fd4323`)
|
|
41
|
+
|
|
42
|
+
**Hạ tầng:** `Icon` 48 primeicons (`463cef4`) · hooks native ×16 — 60 behavior tests (`4baf52b`) · `Upload` + `UploadDropzone` — 14 tests + 5 stories (`55288b1`) · subpath exports nặng `carousel|chart|schedule|editor` (`5615a9b`, `463cef4`) · z-scale tokens `--z-*` (`5615a9b`) · tokens scrim/mask `--scrim-1..4` + `--mask` + `--fs-h3` (`1a086a8`)
|
|
43
|
+
|
|
44
|
+
## 2. Templates (mới — điểm bán trực quan)
|
|
45
|
+
|
|
46
|
+
4 trang ghép sống trong Storybook, controlled state thật — 18 story entries:
|
|
47
|
+
|
|
48
|
+
| Template | Path | Nguồn |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| Dashboard admin | `templates-dashboard--dashboard` | (`3a55922`) |
|
|
51
|
+
| Kanban Project (WIP + filter + Timesheet + toast) | `templates-kanban-project--project-board` | (`3a55922`) |
|
|
52
|
+
| CRUD Table (sort/filter/bulk-delete/Drawer form/useForm focus-first) | `templates-crud-table--full-demo` | worker W6 (`src/templates/crud.stories.tsx`) |
|
|
53
|
+
| Auth (Sign in / Sign up / split) | `templates-auth--sign-in` · `--sign-up` · `--split-layout` | (`417f089`) |
|
|
54
|
+
|
|
55
|
+
Roadmap: Settings + Landing (recipe 9/10 sẵn). Showcase: `Kitchen Sink` full tour (`2f038c2`).
|
|
56
|
+
|
|
57
|
+
## 3. A11y
|
|
58
|
+
|
|
59
|
+
- WAI-ARIA sweep interactive (2026-10-18): **Tabs** roving tabindex + ←/→/Home/End + `aria-controls/labelledby` · **Modal/Drawer/Popconfirm/Popover** `role=dialog` + `aria-modal` + `aria-labelledby` (đủ cả title ReactNode) · **Dropdown/Menu** trigger `aria-haspopup=menu` + `aria-expanded` · **RadioGroup** name chung (arrow-key native) + accessible name · **Select** clear × operable bằng Enter/Space · **TreeTable** `role=treegrid` + `aria-level/expanded/selected`
|
|
60
|
+
- Chuỗi `1a086a8`: Tooltip `aria-describedby` · Popconfirm `aria-haspopup=dialog` + `aria-expanded` · ContextMenu ArrowUp/Down/Home/End + `aria-disabled` · Tree `role=treeitem/group` · Steps `aria-current="step"` · TabMenu `aria-current="page"` · focus-ring sweep Pagination/Inplace/PanelMenu/Segmented/ToggleButton
|
|
61
|
+
- `Checkbox` tri-state `aria-checked="mixed"` (`4b85830`) · keyboard DnD full (Tab→Space→arrows→Enter/Esc + aria-live, `1782a5d`) · icon-only buttons labeled · focus-ring chuẩn `ring-accent/40` toàn thư viện (`28a4f11`)
|
|
62
|
+
|
|
63
|
+
## 4. Dark mode & visual
|
|
64
|
+
|
|
65
|
+
- **Custom scrollbar** mảnh 8px pill token-driven (`8013033`) · dark cascade audit (Listbox hex → `bg-accent/10`, DarkTheme stories MegaMenu/SlideMenu — `4b85830`) · MegaMenu/SlideMenu dark screenshot-verified (`7e3d0ec`) · Alert filled WCAG AA (`ab76cfe`) · Schedule skin FullCalendar qua CSS vars (`1a086a8`) · DatePicker contrast polish + Select check accent + CascadeSelect panel + Table zebra dịu (`1a086a8`) · Carousel nav hoạt động thật swiper v14 + Calendar đồng bộ ngôn ngữ (`292b1a3`)
|
|
66
|
+
|
|
67
|
+
## 5. Fixes
|
|
68
|
+
|
|
69
|
+
- Dark theme không ăn (`@import` đứng sau rule bị drop) (`ab76cfe`) · 17 story file 0-export indexer drop — **fix batch đưa index 51 → 79 titles, 190 stories** (`6f4c9a0`; đo hôm nay 129 titles sau các batch tiếp theo) · stories Pagination TS2322/TS2353 sau merge (`a55b2fe`) · useFocusTrap dialog không focusable (`1a086a8`) · InputNumber stepper flush container (`e94b3e4`) · Storybook CSF render-only gotcha (meta `component:` + required props → TS2322) — quy ước ghi vào AGENTS Anti-patterns
|
|
70
|
+
|
|
71
|
+
## 6. Storybook infra
|
|
72
|
+
|
|
73
|
+
Toolbar dark-mode toggle `addon-themes` (body preview — `:root` light đè dark cùng specificity, body tránh) · trang Introduction docs + `storySort` · manager brand theo token · canvas padding 24px · bỏ `backgrounds` param (`8d8dad1`) · sống tại `:6006` + static build CI
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
**Việc còn mở trước release:** promote notes vào `CHANGELOG.md` đổi `[Unreleased]` → `[0.3.0]` · decide 2 issue design đang chờ (tooltip dark surface; white text trên `--st-doing/--st-done`) · Settings/Landing templates (roadmap 0.3.1) · badge README cập nhật số sau release · merge qua **PR [#55](https://github.com/__STACK_ORG__/architecture-overview/pull/55)**.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Toolchain — cần gì ở đâu (boilerplate FI-62)
|
|
2
|
+
|
|
3
|
+
Bảng đối chiếu tool × môi trường. Nguyên tắc: **máy dev không có Docker vẫn làm việc được 100%** (native per-service); Docker chỉ cần cho compose mode + một số bước verify (có thể đưa qua CI).
|
|
4
|
+
|
|
5
|
+
| Tool | Version | Dev native | Dev compose | CI | Ai cần |
|
|
6
|
+
|------|---------|-----------|-------------|-----|--------|
|
|
7
|
+
| Node.js | 22 LTS (engines >=22) | ✓ | — | ✓ setup-node 22 | node-svc, auth-svc, toàn FE, scaffold output |
|
|
8
|
+
| pnpm | 9 (corepack) | ✓ | — | ✓ corepack | cùng Node ở trên |
|
|
9
|
+
| JDK | 21 (Temurin) | ✓ | — | ✓ setup-java 21 | spring-svc (mvnw tự tải deps — không cần Maven cài sẵn) |
|
|
10
|
+
| Go | 1.24.x | ✓ (hoặc skip — CI build) | — | ✓ setup-go 1.24 | go-svc (`go.sum` không commit — `go mod tidy` sinh) |
|
|
11
|
+
| Docker + Compose v2 | — | ✗ | ✓ | ✓ (ubuntu runner có sẵn) | chạy `platform/docker-compose.yml`; build image per service |
|
|
12
|
+
| Postgres | 16 | ✓ (cài riêng/portable) | ✓ (container) | ✓ (container compose) | mọi service BE + e2e smoke |
|
|
13
|
+
| bash + curl | — | ✓ (Git Bash trên Windows) | ✓ | ✓ | chạy `scripts/smoke/e2e.sh`, `scripts/scaffold/scaffold.sh` |
|
|
14
|
+
| jq | — | không cần (script dùng grep thuần) | — | có sẵn | — |
|
|
15
|
+
|
|
16
|
+
## Ma trận task × tool tối thiểu
|
|
17
|
+
|
|
18
|
+
| Task cần làm | Tool cần ở máy |
|
|
19
|
+
|--------------|----------------|
|
|
20
|
+
| Sửa node-svc / auth-svc / FE | Node 22 + pnpm + Postgres 16 (test) |
|
|
21
|
+
| Sửa spring-svc | JDK 21 (mvnw lo phần còn lại) |
|
|
22
|
+
| Sửa go-svc | Go 1.24 (hoặc để CI build — dev chỉ đọc code) |
|
|
23
|
+
| e2e smoke local | bash + curl + stack sống (compose HOẶC native — walkthrough.md) |
|
|
24
|
+
| Scaffold project mới | bash + pnpm (Node 22) |
|
|
25
|
+
| Build image / compose up | Docker (hoặc push → CI làm) |
|
|
26
|
+
|
|
27
|
+
## Lưu ý portable (máy khoá admin)
|
|
28
|
+
Mọi tool trên đều chạy được bản portable không cần admin (precedent: `~/Tools/sf6-e2e` — JDK 21 + Go 1.24 + Postgres 16 portable, xoá được). Extract là chạy, không installer.
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Wakii Playbook — tổ chức story cho boilerplate
|
|
2
|
+
|
|
3
|
+
Cách dùng story-workflow (Wakii) khi phát triển **chính repo này** và project scaffold từ nó
|
|
4
|
+
(`scripts/scaffold/scaffold.sh` copy `docs/` — trừ `docs/superpowers/` — nên playbook ở `docs/`
|
|
5
|
+
đi theo project mới).
|
|
6
|
+
|
|
7
|
+
**Đọc khi nào:** sắp có việc lớn hơn 1 task, cần quyết chia story hay làm lẻ — và khi chia
|
|
8
|
+
rồi, tra công thức slice theo loại epic. **Không lặp** nội dung skill (`story-workflow`,
|
|
9
|
+
`orca-superpowers-workflow`) — ở đây chỉ có phần *riêng của boilerplate*: archetype chia SF,
|
|
10
|
+
thứ tự đụng file theo conventions, gates nào đỏ vì gì. Quy tắc vàng ở [CLAUDE.md](../CLAUDE.md);
|
|
11
|
+
kiến trúc ở [walkthrough.md](walkthrough.md); "vì sao" ở `docs/adr/`.
|
|
12
|
+
|
|
13
|
+
> Bài học chung của 3 story đã qua (FI-62 micro-boilerplate · FI-76 kafka-outbox-saga ·
|
|
14
|
+
> VU-53 ui-redesign):
|
|
15
|
+
> chi phí lớn nhất không phải code — là **slice sai**: SF quá to (review không kịp), quá nhỏ
|
|
16
|
+
> (overhead gate > giá trị), hoặc phụ thuộc ngầm (2 SF đụng cùng file → worker chặn nhau ở Phase 4).
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 1. Khi nào dùng gì (decision tree)
|
|
21
|
+
|
|
22
|
+
| Việc | Dùng | Ví dụ thật trong repo |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| >3 sub-feature **hoặc** >10 tasks, nhiều người/agent làm song song | **Story mode** — epic Linear + mindmap `.wakii` + SF sub-issues, bracket theo tier | FI-62 (7 SF), FI-76 (5 SF), VU-53 (5 SF tier bracket) |
|
|
25
|
+
| 1 sub-feature hoàn chỉnh, 3–10 tasks | **Single workflow** — `orca-superpowers-workflow` trên 1 Linear issue, đủ Phase 0–5 | từng SF FI-64..FI-75 chạy đơn lẻ giai đoạn đầu FI-62 |
|
|
26
|
+
| Fix 1 điểm rõ gốc rễ, không đụng contract/port | Fix trực tiếp + test, không story | `fix(auth-mock): assert user count theo fixture` (ee0117c) |
|
|
27
|
+
| Đổi behavior có MainPage động | 1 story nhỏ 2–3 SF vẫn ổn — đừng ép story mode chỉ vì "to" | — |
|
|
28
|
+
|
|
29
|
+
Ngưỡng mờ: **2 SF mà có phụ thuộc tier (một cái Unblock hẳn cái kia) → story mode** — bracket
|
|
30
|
+
tier là giá trị thật, không phải ceremony.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 2. Bốn archetype epic — công thức chia SF
|
|
35
|
+
|
|
36
|
+
Trước khi CREATE story, trả lời 5 câu (ghi vào epic summary):
|
|
37
|
+
|
|
38
|
+
1. Đụng **contracts/** không? (OpenAPI / DDL / event / users.json) — đụng là SF-1 contracts, không ghép với impl.
|
|
39
|
+
2. Đụng **port hoặc route gateway** không? — kích hoạt quy tắc 4 chỗ (conventions/05 + .env.example + compose + README cùng commit).
|
|
40
|
+
3. Đụng **READ-LOCKED** không? (`app/shared/src/{api-client,token-storage,error-envelope,mf-bootstrap}.ts`, `package.json#mfToolkit`, catalog pins) — cần epic duyệt + re-spike qua `app/spike`.
|
|
41
|
+
4. Cần **secret/env mới** không? — liệt kê vào `.env.example` ở SF-1, không để SF cuối mới discover.
|
|
42
|
+
5. Chạy **song song được không?** — SF cùng tier KHÔNG được đụng cùng file; đụng → tách tier.
|
|
43
|
+
|
|
44
|
+
Rồi tra archetype:
|
|
45
|
+
|
|
46
|
+
### CC — Cross-cutting contract
|
|
47
|
+
*Đổi thứ mọi thứ phụ thuộc: auth thật, error envelope v2, thêm field event, đổi envelope shape.*
|
|
48
|
+
|
|
49
|
+
- **Slice theo tầng, không theo service:** SF-1 contracts + gateway route → tier 1 services thích ứng (song song) → tier 1 FE → tier 2 convergence + decommission cái cũ.
|
|
50
|
+
- **SF-1 là hiệp ước:** code sau phải theo spec rev đó; đổi spec giữa chừng = rollback SF-1, không vá lẻ.
|
|
51
|
+
- **Gates:** drift-guard CI (snapshot `activity.yaml` nhúng trong go-svc phải bit-identical `contracts/openapi/activity.yaml`), schemathesis contracts CI, human walkthrough ở convergence.
|
|
52
|
+
- **Rủi ro đặc trưng:** CI convergence đỏ liên hồi trong giai đoạn chuyển (2 nửa đổi không cùng lúc) → SF-1 phải giữ **tương thích ngược có kiểm soát** (token cũ còn verify, event cũ còn consume) hoặc đổi đồng loạt trong 1 SF duy nhất — chọn một, ghi rõ trong epic summary.
|
|
53
|
+
- Mẫu sống: chương 4 (epic auth thật).
|
|
54
|
+
|
|
55
|
+
### NS — Service mới
|
|
56
|
+
*Thêm service vào demo (vd notification-svc consume task-events).*
|
|
57
|
+
|
|
58
|
+
- **Câu hỏi làm rõ TRƯỚC khi tính slice** (mỗi câu đổi hình dạng SF-1):
|
|
59
|
+
| Câu hỏi | Hệ quả kỹ thuật |
|
|
60
|
+
|---|---|
|
|
61
|
+
| Sync hay async? | Có Kafka → conventions/09 + topic tạo tường minh trước consumer |
|
|
62
|
+
| Ngôn ngữ nào? | Node ngoài workspace → standalone lockfile (variant conventions/01); Go → drift-guard snapshot + distroless không healthcheck shell (conventions/02) |
|
|
63
|
+
| Có DB riêng? | DDL vào `contracts/db/` + role schema-only trong postgres init + migration pattern (drizzle/Flyway/auto) |
|
|
64
|
+
| Port mấy? | Quy tắc 4 chỗ cùng commit (conventions/05 + .env.example + compose + README) |
|
|
65
|
+
| FE có hiển thị? | Có → tách SF riêng cho remote/page, không gộp vào SF impl |
|
|
66
|
+
- **Công thức 4 SF:** SF-1 khung (contracts OpenAPI + DDL + entry compose + CI workflow — impl rỗng nhưng boot + healthcheck xanh) → SF-2 impl API → SF-3 consumer/producer + FE hiển thị → SF-4 convergence e2e mở rộng.
|
|
67
|
+
- **Đừng đóng SF-1 trước khi** `docker compose up` riêng service boot được với role DB schema-only (bài học drizzle `CREATE SCHEMA` permission — improvements-log 2026-10-12).
|
|
68
|
+
- **Gates:** boot-smoke CI + drift-guard snapshot; conventions mới (nếu có) phải thuộc SF-1, không nhét SF cuối.
|
|
69
|
+
- **Rủi ro:** topic auto-create race → tạo topic tường minh TRƯỚC consumer subscribe (conventions/09; bug thật SF-3 kafka story: consumer kẹt im lặng, 0 fetch 0 error).
|
|
70
|
+
|
|
71
|
+
### FE — FE/UX epic
|
|
72
|
+
*Đổi UI đáng kể (mẫu: VU-53).*
|
|
73
|
+
|
|
74
|
+
- **Design trước, code sau, tier tách bạch:** design gate front-load NGAY LÚC CREATE (mock-prototype 3 hướng, user chọn, hand-off `docs/superpowers/designs/`) → SF-1 tier 0 design-system nền móng (tokens + primitives, không phá hiện trạng) → tier 1 từng vùng UI song song → tier 2 convergence + human browser walkthrough.
|
|
75
|
+
- **Quy tắc sống còn của tier 1:** mỗi SF một vùng file (`shell/` | `remotes/tasks` | `remotes/activity`); fe-shared chỉ tier 0 đụng; css scoped, không sửa style chung sau tier 0.
|
|
76
|
+
- **Gates:** direction-approved record trước SF-1; a11y test; walkthrough 8-acceptance + responsive 375px ở convergence (VU-53 precedent).
|
|
77
|
+
- **Rủi ro:** react/rspack/MF upgrade đụng catalog pins → **phải re-spike** qua `app/spike` trước, không nâng trong epic UI.
|
|
78
|
+
|
|
79
|
+
### IN — Infra/platform
|
|
80
|
+
*Observability, upgrade toolchain, đổi CI, compose.*
|
|
81
|
+
|
|
82
|
+
- **Slice theo lớp infra, tách phần compose khỏi phần code:** entry compose + env là 1 SF (verify bằng boot-smoke), code service thích ứng là SF sau — đừng trộn.
|
|
83
|
+
- **Quyền sửa compose:** `platform/docker-compose.yml` có lịch sử sở hữu ghi ở đầu file — SF nào cũng KHÔNG tự sửa nếu không được brief ủy quyền; muốn đổi → flag coordinator kèm gap-answer ghi lại vào comment compose (precedent SF-5/SF-6 FI-62).
|
|
84
|
+
- **Gates:** convergence e2e trên compose 10 services là gate thật (dev machine không Docker → verify qua CI, `gh run watch`); down-scale heap kafka 512m giữ nguyên cho CI 7GB.
|
|
85
|
+
- **Rủi ro:** secrets — thêm env mới = `:?set in .env` ép lỗi sớm; KHÔNG commit `.env`; story-guard-secrets chặn inline secret (export qua script file nếu cần override).
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 3. Checklist lifecycle (một dòng một pha)
|
|
90
|
+
|
|
91
|
+
- [ ] **Phase 0** — impact analysis (phase0-impact-analyst): touch map + blast radius trước khi viết dòng spec nào.
|
|
92
|
+
- [ ] **Spec** — brainstorm → `docs/superpowers/specs/YYYY-MM-DD-<topic>.md` → spec-critic GO trước khi plan.
|
|
93
|
+
- [ ] **Plan + DAG** — writing-plans-linear (subtask lên Linear) → plan-critic nếu ≥5 tasks; SF cùng tier không đụng cùng file.
|
|
94
|
+
- [ ] **CREATE story** — mindmap `.wakii` (tier + depends-on + Linear id từng SF) + context pack `contexts/<story>/sf-N.md` cho từng SF; FE epic: design gate xong TRƯỚC khi dispatch SF-1.
|
|
95
|
+
- [ ] **Dispatch theo tier** — tier 0 xong mới tier 1; context pack trả lời HẾT câu epic-level ("Đã trả lời hết epic-level — KHÔNG hỏi lại"); SF hội tụ KHÔNG fix bug miền khác, REPORT coordinator.
|
|
96
|
+
- [ ] **Execute mỗi SF** — contracts TRƯỚC code; TDD chỗ được, ghi `tdd: skipped-tdd: CI-only <lý do>` chỗ không (dev thiếu JDK/Docker); review ĐỘC LẬP verdict APPROVED materialize ra file.
|
|
97
|
+
- [ ] **Evidence** — `docs/superpowers/evidence/<sf>/` + `test-run.txt` ghi HEAD **tại lúc code commit cuối** (docs commit sau làm B1 flip FAIL — loop nổi tiếng của SF-3).
|
|
98
|
+
- [ ] **Gate SF** — `story-verify` B1–B3 sạch; executor KHÔNG merge, KHÔNG set Linear Done — coordinator làm cả hai.
|
|
99
|
+
- [ ] **Convergence (tier 2)** — full suite xanh + e2e 2 chiều PASS + browser walkthrough human gate + docs sync (walkthrough/README/orca.yaml cùng commit).
|
|
100
|
+
- [ ] **Merge + đóng** — coordinator merge SF về dest (story model); **dest → main qua PR** theo [git-flow.md](git-flow.md) (CI xanh + `--no-ff`, từ 2026-10-17 — không push thẳng main); epic Linear Done; xoá state run/task lệch (như case SF-5 `ready` còn treo sau khi main đã merge).
|
|
101
|
+
- [ ] **Post-task-ritual** — improvements-log.md ghi bài học (flag, KHÔNG tự sửa skill); archetype mới → cập nhật playbook này **cùng commit merge**.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 4. Worked example — epic "Auth thật thay auth-mock" (archetype CC)
|
|
106
|
+
|
|
107
|
+
> ⚠️ Đây là **ví dụ minh hoạ công thức chia SF** — không phải spec auth. Khi epic được duyệt thật:
|
|
108
|
+
> brainstorm + spec riêng (câu 1–5 chương 2 + quyết định mở bên dưới), rồi mới CREATE story.
|
|
109
|
+
|
|
110
|
+
**Mục tiêu (draft):** thay auth-mock bằng service auth thật — register/login/refresh + enforcement
|
|
111
|
+
RBAC. `roles` (`user|admin`) đã có sẵn trong users.json + token contract (claims `sub/email/roles`,
|
|
112
|
+
Alice đã `admin`) — việc thật là **enforcement ở services + register/refresh**, không phải thêm
|
|
113
|
+
roles. Non-goals: OAuth/social, multi-tenant, rate-limit distributed.
|
|
114
|
+
|
|
115
|
+
**Decision points phải chốt ở Phase 0 (mỗi cái đổi hình dạng DAG):**
|
|
116
|
+
|
|
117
|
+
| Quyết định | Phương án | Hệ quả DAG |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| Port + path | auth-svc thật **đón luôn :8090 + giữ `/api/auth/*`** | gateway, conventions/05, .env, README **không đổi** — quy tắc 4 chỗ không kích hoạt (khuyến nghị) |
|
|
120
|
+
| Users schema | spring-svc đang owns users — auth-svc đọc qua API spring vs owns schema riêng | Nếu owns riêng: SF-2 thêm migration + role DB; nếu qua spring: SF-2/SF-3 ghép chặt → gộp 1 SF |
|
|
121
|
+
| Token contract | giữ claims `sub/email/roles` + thêm refresh/rotation (token-contract.md dòng 69 đã chốt: nâng OIDC thì claims giữ nguyên) vs đổi cấu trúc | Giữ: node/go sửa riêng từng SF khả thi; Đổi: buộc đồng loạt 1 SF |
|
|
122
|
+
| `token-storage.ts` READ-LOCKED | wrapper mới không đụng file locked vs epic duyệt sửa | Wrapper: SF FE gọn; Sửa: cần approval epic + re-spike |
|
|
123
|
+
|
|
124
|
+
**Slice SF đề xuất (bracket tier):**
|
|
125
|
+
|
|
126
|
+
- **SF-1 · tier 0 — Contracts + hiệp ước:** mở rộng `contracts/openapi/auth.yaml`
|
|
127
|
+
(register/refresh), `contracts/auth/token-contract.md` v2 (refresh/rotation — claims
|
|
128
|
+
`sub/email/roles` giữ nguyên), users.json **KHÔNG đổi** (UUID + roles đã chuẩn — saga fail-user
|
|
129
|
+
`svc-fail` và seed spring còn khớp), env mới vào `.env.example`. Gate: spectral + schemathesis
|
|
130
|
+
xanh; KHÔNG đụng code runtime.
|
|
131
|
+
- **SF-2 · tier 1 — auth-svc:** impl register/login/refresh (+ quyết định users-schema ở trên),
|
|
132
|
+
auth-mock chuyển chế độ legacy-flag tạm. Gate: unit + integration token thật; compose boot xanh.
|
|
133
|
+
- **SF-3 · tier 1 — Services thích ứng (song song SF-2 nếu token shape giữ):** node-svc + go-svc
|
|
134
|
+
middleware verify roles; go-svc service-token (`svc-activity`) đổi theo token contract; drift-guard
|
|
135
|
+
snapshot không đổi nếu API không đổi. Đụng file khác SF-2/SF-4 hoàn toàn.
|
|
136
|
+
- **SF-4 · tier 1 — FE:** login giữ behavior + messages contract (test shell hiện có là reguação),
|
|
137
|
+
thêm refresh flow; test shell hiện có (login behavior + error messages) là ràng buộc giữ nguyên;
|
|
138
|
+
**`e2e.sh` hardcode `alice@demo.local`** → nếu password/flow đổi, SF này phải đồng bộ smoke script
|
|
139
|
+
(hoặc SF-5 sẽ đỏ). READ-LOCKED theo decision ở trên.
|
|
140
|
+
- **SF-5 · tier 2 — Convergence + decommission:** e2e mở rộng login → refresh → RBAC 403 → saga
|
|
141
|
+
fail-user **vẫn xanh**; tắt auth-mock (hoặc giữ `AUTH_MOCK_MODE=legacy`); docs sync 4 chỗ; human
|
|
142
|
+
walkthrough cuối.
|
|
143
|
+
|
|
144
|
+
**Gates đắt tiền nhất của epic này:** (1) drift-guard + schemathesis ở SF-1; (2) CI convergence
|
|
145
|
+
đỏ trong window SF-2..4 nếu token shape đổi mà không giữ tương thích — đây là lý do decision
|
|
146
|
+
"token shape" phải chốt TRƯỚC khi CREATE; (3) human walkthrough SF-5.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 5. Anti-patterns — bài học đã trả giá (từ 3 story + improvements-log)
|
|
151
|
+
|
|
152
|
+
| Anti-pattern | Hậu quả thấy thật | Quy tắc |
|
|
153
|
+
|---|---|---|
|
|
154
|
+
| Consumer subscribe khi topic chưa tồn tại (auto-create race) | Consumer kẹt im lặng — stable group, 0 fetch, 0 error (SF-3 kafka) | Tạo topic tường minh TRƯỚC boot consumer; không `depends_on kafka` |
|
|
155
|
+
| Evidence `test-run.txt` ghi hash, sau đó commit docs mới | Gate B1 flip FAIL không do code (SF-3, lặp 2 lần) | Hash ghi tại code commit cuối; story-verify chấp nhận docs-only sau hash |
|
|
156
|
+
| Bắt `orca run-create` trả top-level `id` | Lấy nhầm request-id → 9 task orphan ngoài run (FI-62) | Id thật ở `.result.run.id` / `.result.gate.id`; task-create validate run tồn tại |
|
|
157
|
+
| Executor tự nghĩ mình merge được | `story-verify` B4 FAIL mãi ở handoff | B4 executor-view = PENDING-MERGE; merge là việc coordinator |
|
|
158
|
+
| `sed -i` / `realpath -m` GNU-only trong script | Scaffold fail trên macOS (fix 2026-10-17) | Script dùng chung repo: detect BSD/GNU 1 lần, python3 thay `realpath -m` |
|
|
159
|
+
| pnpm `catalog:` + standalone install `--ignore-workspace` | `ERR_PNPM_CATALOG_ENTRY_NOT_FOUND` (SF-7 copy-dir) | Mini workspace: sed catalog block từ root, install KHÔNG ignore-workspace |
|
|
160
|
+
| Đổi spec giữa chừng SF đang chạy | Rollback cả SF, mất 1 vòng review | Spec sai giữa chừng = STOP + REPORT coordinator, không vá lẻ trong SF impl |
|
|
161
|
+
| Test "ma" — tên có vẻ assert, thực chất không | Review APPROVED oan: phantom grep không assert gì (sf-5b phải rà lại) | Mỗi acceptance có 1 assert thật trỏ đúng behavior; reviewer đọc assert, không đọc tên test |
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 6. Cập nhật playbook
|
|
166
|
+
|
|
167
|
+
Epic mới không khớp archetype nào ở chương 2 → **đừng ép** vào archetype cũ. Merge mọi nhánh story về main qua PR (git-flow.md) — quy tắc này đè model merge-thẳng-dest của các story trước 2026-10-17. Thêm archetype mới
|
|
168
|
+
(định nghĩa + công thức slice + gates + rủi ro — cùng format) trong **cùng commit merge epic đó** —
|
|
169
|
+
cùng nguyên tắc với orca.yaml: descriptor đi cùng thay đổi nó mô tả, drift = lỗi onboarding.
|
|
170
|
+
|
|
171
|
+
Bài học một-lần-theo-epic cứ để improvements-log; bài học **lặp lại từ epic thứ hai** mới lên
|
|
172
|
+
playbook (tiêu chí lọc — không biến playbook thành nhật ký).
|