@rashidee/co2 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/dist/index.js +25449 -0
  2. package/drizzle/0000_remarkable_charles_xavier.sql +210 -0
  3. package/drizzle/0001_wise_wolf_cub.sql +13 -0
  4. package/drizzle/0002_secret_spyke.sql +16 -0
  5. package/drizzle/0003_workspace_config_singleton.sql +16 -0
  6. package/drizzle/0004_terminal_claim_v120.sql +11 -0
  7. package/drizzle/0005_brainstorm_v124.sql +10 -0
  8. package/drizzle/0006_project_v140.sql +6 -0
  9. package/drizzle/0007_prd_wizard_v124.sql +14 -0
  10. package/drizzle/0008_workflow_artifact_v126.sql +24 -0
  11. package/drizzle/0009_project_import_v150.sql +7 -0
  12. package/drizzle/0010_quality_v151.sql +3 -0
  13. package/drizzle/meta/0000_snapshot.json +1335 -0
  14. package/drizzle/meta/0001_snapshot.json +1416 -0
  15. package/drizzle/meta/0002_snapshot.json +1510 -0
  16. package/drizzle/meta/_journal.json +83 -0
  17. package/package.json +41 -0
  18. package/plugin/.claude-plugin/marketplace.json +36 -0
  19. package/plugin/.claude-plugin/plugin.json +22 -0
  20. package/plugin/README.md +625 -0
  21. package/plugin/SKILLS.md +350 -0
  22. package/plugin/co2.svg +5 -0
  23. package/plugin/commands/brainstorm-loop.md +129 -0
  24. package/plugin/skills/conductor-defect/SKILL.md +898 -0
  25. package/plugin/skills/conductor-feature-develop/SKILL.md +1383 -0
  26. package/plugin/skills/conductor-feature-develop/references/implementation-domain-template.md +131 -0
  27. package/plugin/skills/conductor-feature-develop/references/implementation-master-template.md +89 -0
  28. package/plugin/skills/conductor-feature-develop/references/playwright-setup.md +224 -0
  29. package/plugin/skills/conductor-feature-prepare/SKILL.md +604 -0
  30. package/plugin/skills/depgen-k8s/SKILL.md +468 -0
  31. package/plugin/skills/depgen-k8s/references/dockerfile-laravel.md +197 -0
  32. package/plugin/skills/depgen-k8s/references/dockerfile-nodejs.md +163 -0
  33. package/plugin/skills/depgen-k8s/references/dockerfile-spring-boot.md +174 -0
  34. package/plugin/skills/depgen-k8s/references/k8s-patterns.md +869 -0
  35. package/plugin/skills/mockgen-shadcn/SKILL.md +1067 -0
  36. package/plugin/skills/mockgen-shadcn/references/admin-layout-template.md +1467 -0
  37. package/plugin/skills/mockgen-shadcn/references/mockup-hub-template.md +498 -0
  38. package/plugin/skills/mockgen-shadcn/references/mockup-index-template.md +216 -0
  39. package/plugin/skills/mockgen-tailwind/SKILL.md +904 -0
  40. package/plugin/skills/mockgen-tailwind/references/admin-layout-template.md +720 -0
  41. package/plugin/skills/mockgen-tailwind/references/mockup-hub-template.md +498 -0
  42. package/plugin/skills/mockgen-tailwind/references/mockup-index-template.md +190 -0
  43. package/plugin/skills/modelgen-nosql/SKILL.md +617 -0
  44. package/plugin/skills/modelgen-nosql/references/model-extraction-methodology.md +497 -0
  45. package/plugin/skills/modelgen-nosql/references/nosql-design-guide.md +258 -0
  46. package/plugin/skills/modelgen-relational/SKILL.md +707 -0
  47. package/plugin/skills/modelgen-relational/references/model-extraction-methodology.md +499 -0
  48. package/plugin/skills/specgen-flutter-riverpod/SKILL.md +898 -0
  49. package/plugin/skills/specgen-flutter-riverpod/references/component-patterns.md +971 -0
  50. package/plugin/skills/specgen-flutter-riverpod/references/notification-patterns.md +457 -0
  51. package/plugin/skills/specgen-flutter-riverpod/references/routing-patterns.md +362 -0
  52. package/plugin/skills/specgen-flutter-riverpod/references/security-patterns.md +709 -0
  53. package/plugin/skills/specgen-flutter-riverpod/references/spec-template.md +1566 -0
  54. package/plugin/skills/specgen-flutter-riverpod/references/state-patterns.md +518 -0
  55. package/plugin/skills/specgen-flutter-riverpod/references/storage-patterns.md +370 -0
  56. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/SKILL.md +984 -0
  57. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/batch-patterns.md +359 -0
  58. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/messaging-patterns.md +468 -0
  59. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/modulith-patterns.md +461 -0
  60. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/reporting-patterns.md +803 -0
  61. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/security-patterns.md +501 -0
  62. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/spec-template.md +1268 -0
  63. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/web-patterns.md +301 -0
  64. package/plugin/skills/specgen-node-cli-web/SKILL.md +561 -0
  65. package/plugin/skills/specgen-node-cli-web/references/auth-patterns.md +293 -0
  66. package/plugin/skills/specgen-node-cli-web/references/cli-packaging-patterns.md +250 -0
  67. package/plugin/skills/specgen-node-cli-web/references/server-patterns.md +247 -0
  68. package/plugin/skills/specgen-node-cli-web/references/spec-template.md +401 -0
  69. package/plugin/skills/specgen-node-cli-web/references/testing-patterns.md +174 -0
  70. package/plugin/skills/specgen-react-mui/SKILL.md +789 -0
  71. package/plugin/skills/specgen-react-mui/references/component-patterns.md +1077 -0
  72. package/plugin/skills/specgen-react-mui/references/reporting-patterns.md +1998 -0
  73. package/plugin/skills/specgen-react-mui/references/routing-patterns.md +461 -0
  74. package/plugin/skills/specgen-react-mui/references/security-patterns.md +599 -0
  75. package/plugin/skills/specgen-react-mui/references/spec-template.md +1030 -0
  76. package/plugin/skills/specgen-react-mui/references/state-patterns.md +327 -0
  77. package/plugin/skills/specgen-react-tailwind/SKILL.md +859 -0
  78. package/plugin/skills/specgen-react-tailwind/references/component-patterns.md +1212 -0
  79. package/plugin/skills/specgen-react-tailwind/references/reporting-patterns.md +1529 -0
  80. package/plugin/skills/specgen-react-tailwind/references/routing-patterns.md +669 -0
  81. package/plugin/skills/specgen-react-tailwind/references/security-patterns.md +656 -0
  82. package/plugin/skills/specgen-react-tailwind/references/spec-template.md +1237 -0
  83. package/plugin/skills/specgen-react-tailwind/references/state-patterns.md +327 -0
  84. package/plugin/skills/specgen-sdk-java/SKILL.md +933 -0
  85. package/plugin/skills/specgen-sdk-java/references/api-extraction-patterns.md +247 -0
  86. package/plugin/skills/specgen-sdk-java/references/http-client-patterns.md +495 -0
  87. package/plugin/skills/specgen-sdk-java/references/packaging-patterns.md +366 -0
  88. package/plugin/skills/specgen-sdk-java/references/spec-template.md +956 -0
  89. package/plugin/skills/specgen-spring-jpa-jtehtmx/SKILL.md +1284 -0
  90. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/batch-patterns.md +1224 -0
  91. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/jasper-patterns.md +1638 -0
  92. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/messaging-patterns.md +512 -0
  93. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/modulith-patterns.md +354 -0
  94. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/security-patterns.md +551 -0
  95. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/spec-template.md +2502 -0
  96. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/web-patterns.md +503 -0
  97. package/plugin/skills/specgen-spring-jpa-restapi/SKILL.md +990 -0
  98. package/plugin/skills/specgen-spring-jpa-restapi/references/batch-patterns.md +1224 -0
  99. package/plugin/skills/specgen-spring-jpa-restapi/references/messaging-patterns.md +512 -0
  100. package/plugin/skills/specgen-spring-jpa-restapi/references/modulith-patterns.md +279 -0
  101. package/plugin/skills/specgen-spring-jpa-restapi/references/reporting-patterns.md +1536 -0
  102. package/plugin/skills/specgen-spring-jpa-restapi/references/restapi-patterns.md +722 -0
  103. package/plugin/skills/specgen-spring-jpa-restapi/references/security-patterns.md +351 -0
  104. package/plugin/skills/specgen-spring-jpa-restapi/references/spec-template.md +553 -0
  105. package/plugin/skills/specgen-ts-cli/SKILL.md +861 -0
  106. package/plugin/skills/specgen-ts-cli/references/async-patterns.md +1101 -0
  107. package/plugin/skills/specgen-ts-cli/references/command-patterns.md +383 -0
  108. package/plugin/skills/specgen-ts-cli/references/config-patterns.md +430 -0
  109. package/plugin/skills/specgen-ts-cli/references/database-patterns.md +750 -0
  110. package/plugin/skills/specgen-ts-cli/references/packaging-patterns.md +426 -0
  111. package/plugin/skills/specgen-ts-cli/references/spec-template.md +1391 -0
  112. package/plugin/skills/specgen-ts-cli/references/testing-patterns.md +909 -0
  113. package/plugin/skills/testgen-functional/SKILL.md +1381 -0
  114. package/plugin/skills/tracegen-matrix/SKILL.md +243 -0
  115. package/plugin/skills/util-preparek8senv/SKILL.md +422 -0
  116. package/plugin/skills/util-projectinit/SKILL.md +307 -0
  117. package/plugin/skills/util-projectinit/reference/brainstorm-loop.md +129 -0
  118. package/plugin/skills/util-projectinit/reference/brainstorm-protocol.md +144 -0
  119. package/plugin/skills/util-projectinit/reference/brainstorm-setup-guide.md +153 -0
  120. package/plugin/skills/util-projectinit/reference/brainstorm-template-appdev.md +87 -0
  121. package/plugin/skills/util-projectinit/reference/co2-context-generation-guide.md +761 -0
  122. package/plugin/skills/util-projectsync/SKILL.md +501 -0
  123. package/plugin/skills/util-updprd/SKILL.md +324 -0
  124. package/plugin/skills/util-usanalyzer/SKILL.md +307 -0
  125. package/plugin/skills/util-ustagger/SKILL.md +154 -0
  126. package/static/assets/abnfDiagram-VRR7QNED-DvPuwyCV.js +1 -0
  127. package/static/assets/arc-DRKw7sjs.js +1 -0
  128. package/static/assets/architectureDiagram-ZJ3FMSHR-CaNcxUbC.js +36 -0
  129. package/static/assets/blockDiagram-677ZJIJ3-Demd4AOK.js +132 -0
  130. package/static/assets/c4Diagram-LMCZKHZV-PVKUfc2x.js +10 -0
  131. package/static/assets/channel-C2nVbuwv.js +1 -0
  132. package/static/assets/chunk-2Q5K7J3B-CExf8ww_.js +1 -0
  133. package/static/assets/chunk-32BRIVSS-CFPaoONF.js +1 -0
  134. package/static/assets/chunk-5VM5RSS4-DE2esM67.js +15 -0
  135. package/static/assets/chunk-EX3LRPZG-SON_YdDG.js +231 -0
  136. package/static/assets/chunk-JWPE2WC7-Qxah8LNr.js +1 -0
  137. package/static/assets/chunk-MOJQB5TN-BcWGQV3j.js +88 -0
  138. package/static/assets/chunk-RYQCIY6F-DkDj-OR5.js +1 -0
  139. package/static/assets/chunk-V7JOEXUC-BlI1Mrah.js +206 -0
  140. package/static/assets/chunk-VR4S4FIN-Agf__duj.js +1 -0
  141. package/static/assets/chunk-XXDRQBXY-B5CfAh85.js +1 -0
  142. package/static/assets/classDiagram-OUVF2IWQ-DXJIljsR.js +1 -0
  143. package/static/assets/classDiagram-v2-EOCWNBFH-DXJIljsR.js +1 -0
  144. package/static/assets/cose-bilkent-JH36ORCC-DO0cQkcy.js +1 -0
  145. package/static/assets/cynefin-VYW2F7L2-CfOnsnXc.js +178 -0
  146. package/static/assets/cynefinDiagram-TSTJHNR4-BJ8tULAv.js +62 -0
  147. package/static/assets/cytoscape.esm-DTSO7Bv0.js +331 -0
  148. package/static/assets/dagre-VKFMJZFB-DfjwzHqP.js +4 -0
  149. package/static/assets/defaultLocale-DX6XiGOO.js +1 -0
  150. package/static/assets/diagram-FQU43EPY-CndSOIIM.js +3 -0
  151. package/static/assets/diagram-G47NLZAW-Czf5hN0Z.js +24 -0
  152. package/static/assets/diagram-NH7WQ7WH-COAyojGh.js +24 -0
  153. package/static/assets/diagram-OA4YK3LP-H8PoiN2m.js +30 -0
  154. package/static/assets/diagram-WEI45ONY-DzcaVzjp.js +41 -0
  155. package/static/assets/ebnfDiagram-CCIWWBDH-DPazGYLJ.js +1 -0
  156. package/static/assets/erDiagram-Q63AITRT-Bo-fubgF.js +85 -0
  157. package/static/assets/flowDiagram-23GEKE2U-CSvxUDwh.js +156 -0
  158. package/static/assets/ganttDiagram-NO4QXBWP-DnBveWX6.js +292 -0
  159. package/static/assets/gitGraphDiagram-IHSO6WYX-B3rVL8c-.js +106 -0
  160. package/static/assets/graph-C9eacEi8.js +1 -0
  161. package/static/assets/index-LZSQkLE2.css +41 -0
  162. package/static/assets/index-y7XDSgMG.js +495 -0
  163. package/static/assets/infoDiagram-FWYZ7A6U-CvWV9yy2.js +2 -0
  164. package/static/assets/init-Gi6I4Gst.js +1 -0
  165. package/static/assets/ishikawaDiagram-FXEZZL3T-DF28a1N6.js +70 -0
  166. package/static/assets/journeyDiagram-5HDEW3XC-CB6CugYk.js +139 -0
  167. package/static/assets/kanban-definition-HUTT4EX6-ResSLF6d.js +89 -0
  168. package/static/assets/katex-C5jXJg4s.js +257 -0
  169. package/static/assets/layout-DEXfKzaS.js +1 -0
  170. package/static/assets/linear-CLO--ryk.js +1 -0
  171. package/static/assets/map-Czzmt4hB.js +1 -0
  172. package/static/assets/mindmap-definition-LN4V7U3C-BvW3EbxX.js +96 -0
  173. package/static/assets/ordinal-Cboi1Yqb.js +1 -0
  174. package/static/assets/pegDiagram-2B236MQR-BHCgqrrM.js +1 -0
  175. package/static/assets/pieDiagram-ENE6RG2P-DVmCQ5FA.js +39 -0
  176. package/static/assets/quadrantDiagram-ABIIQ3AL-B3e5KR52.js +7 -0
  177. package/static/assets/railroadDiagram-RFXS5EU6-Csv5ysLc.js +1 -0
  178. package/static/assets/requirementDiagram-TGXJPOKE-DOMVzvnB.js +84 -0
  179. package/static/assets/sankeyDiagram-HTMAVEWB-B1dcTOvy.js +40 -0
  180. package/static/assets/sequenceDiagram-DBY2YBRQ-BY414yeO.js +162 -0
  181. package/static/assets/sizeCapture-X5ZJPWSS-CuJfrfBN.js +1 -0
  182. package/static/assets/stateDiagram-2N3HPSRC-FX4rJkzV.js +1 -0
  183. package/static/assets/stateDiagram-v2-6OUMAXLB-BVufbO_H.js +1 -0
  184. package/static/assets/swimlanes-5IMT3BWC-Sfy58mmv.js +2 -0
  185. package/static/assets/swimlanesDiagram-G3AALYLV-wDCDw08H.js +8 -0
  186. package/static/assets/timeline-definition-FHXFAJF6-CmV7by8p.js +120 -0
  187. package/static/assets/vennDiagram-L72KCM5P-FqIyFZFt.js +34 -0
  188. package/static/assets/wardleyDiagram-EHGQE667-BZ06O45i.js +78 -0
  189. package/static/assets/xychartDiagram-FW5EYKEG-BOkffR06.js +7 -0
  190. package/static/index.html +24 -0
@@ -0,0 +1,327 @@
1
+ # State Management Patterns — Zustand Feature Stores & TanStack Query
2
+
3
+ This reference describes when and how to use feature-level Zustand stores alongside
4
+ TanStack Query. Include this content in Section 9 of the generated specification and
5
+ in any module SPEC.md that requires client-side state beyond server cache.
6
+
7
+ ---
8
+
9
+ ## State Separation Principle
10
+
11
+ The golden rule for React SPA state management:
12
+
13
+ | State Type | Tool | Examples |
14
+ |---|---|---|
15
+ | **Server state** (data from API) | TanStack Query | Hero section list, user profile, blog posts |
16
+ | **UI state** (ephemeral, per-session) | Zustand | Selected rows, filter panel open/closed, active tab |
17
+ | **Global UI state** | Zustand (persisted) | Theme mode, sidebar open, user preferences |
18
+ | **Auth state** | Zustand (memory-only, no persist) | JWT token, logged-in user info |
19
+ | **Form state** | React Hook Form | All form field values and validation errors |
20
+
21
+ **Do NOT use Zustand to cache API responses.** If data comes from the server, TanStack
22
+ Query owns it. Zustand holds only the filters/pagination params that TanStack Query uses
23
+ as its query key.
24
+
25
+ ---
26
+
27
+ ## Feature Store Pattern
28
+
29
+ Create a feature store only when the module has complex UI state that needs to be shared
30
+ between sibling components (e.g., a list page and a detail panel rendered side-by-side).
31
+
32
+ ### When to create a feature store
33
+
34
+ | Scenario | Use feature store? |
35
+ |---|---|
36
+ | List page with filter bar → filter values | **Yes** — filter state drives TanStack Query params |
37
+ | Multi-step form with shared wizard state | **Yes** — wizard step and accumulated values |
38
+ | List page + slide-over detail panel (side-by-side) | **Yes** — selected item ID |
39
+ | Simple list page with local filter `useState` | **No** — keep state local |
40
+ | Simple create/edit form | **No** — React Hook Form handles form state |
41
+
42
+ ### Feature Store Template
43
+
44
+ ```typescript
45
+ // Example: src/features/heroSection/store/heroSection.store.ts
46
+ import { create } from 'zustand';
47
+ import type { HeroSectionListParams, HeroSectionStatus } from '../heroSection.types';
48
+
49
+ interface HeroSectionState {
50
+ // Filter and pagination params — these drive the TanStack Query key
51
+ filters: HeroSectionListParams;
52
+
53
+ // UI state
54
+ selectedIds: Set<string>;
55
+ isDetailPanelOpen: boolean;
56
+ selectedId: string | null;
57
+
58
+ // Actions
59
+ setFilter: (key: keyof HeroSectionListParams, value: unknown) => void;
60
+ resetFilters: () => void;
61
+ setPage: (page: number) => void;
62
+ toggleSelectId: (id: string) => void;
63
+ clearSelection: () => void;
64
+ openDetail: (id: string) => void;
65
+ closeDetail: () => void;
66
+ }
67
+
68
+ const DEFAULT_FILTERS: HeroSectionListParams = {
69
+ page: 0,
70
+ size: 10,
71
+ status: '',
72
+ };
73
+
74
+ export const useHeroSectionStore = create<HeroSectionState>((set) => ({
75
+ filters: { ...DEFAULT_FILTERS },
76
+ selectedIds: new Set(),
77
+ isDetailPanelOpen: false,
78
+ selectedId: null,
79
+
80
+ setFilter: (key, value) =>
81
+ set((state) => ({
82
+ filters: { ...state.filters, [key]: value, page: 0 },
83
+ })),
84
+
85
+ resetFilters: () => set({ filters: { ...DEFAULT_FILTERS } }),
86
+
87
+ setPage: (page) =>
88
+ set((state) => ({ filters: { ...state.filters, page } })),
89
+
90
+ toggleSelectId: (id) =>
91
+ set((state) => {
92
+ const next = new Set(state.selectedIds);
93
+ next.has(id) ? next.delete(id) : next.add(id);
94
+ return { selectedIds: next };
95
+ }),
96
+
97
+ clearSelection: () => set({ selectedIds: new Set() }),
98
+
99
+ openDetail: (id) => set({ selectedId: id, isDetailPanelOpen: true }),
100
+
101
+ closeDetail: () => set({ isDetailPanelOpen: false, selectedId: null }),
102
+ }));
103
+ ```
104
+
105
+ ### Integration with TanStack Query
106
+
107
+ ```tsx
108
+ // src/features/heroSection/pages/HeroSectionListPage.tsx
109
+ import { useHeroSectionStore } from '../store/heroSection.store';
110
+ import { useHeroSections } from '../hooks/useHeroSections';
111
+
112
+ export function HeroSectionListPage() {
113
+ // Filter state lives in Zustand — changes trigger React re-render
114
+ const { filters, setFilter, setPage } = useHeroSectionStore();
115
+
116
+ // TanStack Query uses filters as the query key — auto-refetches when filters change
117
+ const { data, isLoading } = useHeroSections(filters);
118
+
119
+ return (
120
+ <>
121
+ <FilterBar
122
+ status={filters.status}
123
+ onStatusChange={(value) => setFilter('status', value)}
124
+ />
125
+ <DataTable
126
+ rows={data?.content ?? []}
127
+ loading={isLoading}
128
+ />
129
+ <TablePagination
130
+ count={data?.totalElements ?? 0}
131
+ page={filters.page ?? 0}
132
+ onPageChange={(_, page) => setPage(page)}
133
+ />
134
+ </>
135
+ );
136
+ }
137
+ ```
138
+
139
+ ---
140
+
141
+ ## Optimistic Updates Pattern
142
+
143
+ For fast UI feedback on mutations (useful for toggle operations like status changes):
144
+
145
+ ```typescript
146
+ // src/features/heroSection/hooks/useHeroSectionMutations.ts
147
+ import { useMutation, useQueryClient } from '@tanstack/react-query';
148
+ import { heroSectionApi } from '../api/heroSectionApi';
149
+ import { heroSectionKeys } from './useHeroSections';
150
+ import type { HeroSection } from '../heroSection.types';
151
+
152
+ export function useToggleHeroSectionStatus() {
153
+ const queryClient = useQueryClient();
154
+
155
+ return useMutation({
156
+ mutationFn: ({ id, status }: { id: string; status: HeroSection['status'] }) =>
157
+ heroSectionApi.update(id, { status }),
158
+
159
+ // Optimistic update — immediately update the cache before the API responds
160
+ onMutate: async ({ id, status }) => {
161
+ // Cancel any in-flight refetches to avoid overwriting optimistic update
162
+ await queryClient.cancelQueries({ queryKey: heroSectionKeys.all });
163
+
164
+ // Snapshot previous data for rollback
165
+ const previousData = queryClient.getQueryData<HeroSection>(
166
+ heroSectionKeys.detail(id),
167
+ );
168
+
169
+ // Optimistically update the cache
170
+ queryClient.setQueryData<HeroSection>(heroSectionKeys.detail(id), (old) =>
171
+ old ? { ...old, status } : old,
172
+ );
173
+
174
+ return { previousData };
175
+ },
176
+
177
+ // On error, roll back to the previous value
178
+ onError: (_error, { id }, context) => {
179
+ if (context?.previousData) {
180
+ queryClient.setQueryData(heroSectionKeys.detail(id), context.previousData);
181
+ }
182
+ },
183
+
184
+ // Always refetch after error or success to sync with server
185
+ onSettled: (_, __, { id }) => {
186
+ queryClient.invalidateQueries({ queryKey: heroSectionKeys.detail(id) });
187
+ queryClient.invalidateQueries({ queryKey: heroSectionKeys.lists() });
188
+ },
189
+ });
190
+ }
191
+ ```
192
+
193
+ ---
194
+
195
+ ## Multi-Step Form Pattern (Wizard)
196
+
197
+ For complex forms spanning multiple steps (e.g., blog post creation with metadata, content, and preview steps):
198
+
199
+ ```typescript
200
+ // src/features/blog/store/blogCreate.store.ts
201
+ import { create } from 'zustand';
202
+ import type { BlogCreateStep1Values, BlogCreateStep2Values } from '../blog.schema';
203
+
204
+ type WizardStep = 'metadata' | 'content' | 'preview';
205
+
206
+ interface BlogCreateState {
207
+ currentStep: WizardStep;
208
+ step1Data: BlogCreateStep1Values | null;
209
+ step2Data: BlogCreateStep2Values | null;
210
+
211
+ goToStep: (step: WizardStep) => void;
212
+ saveStep1: (data: BlogCreateStep1Values) => void;
213
+ saveStep2: (data: BlogCreateStep2Values) => void;
214
+ reset: () => void;
215
+ }
216
+
217
+ export const useBlogCreateStore = create<BlogCreateState>((set) => ({
218
+ currentStep: 'metadata',
219
+ step1Data: null,
220
+ step2Data: null,
221
+
222
+ goToStep: (step) => set({ currentStep: step }),
223
+ saveStep1: (data) => set({ step1Data: data, currentStep: 'content' }),
224
+ saveStep2: (data) => set({ step2Data: data, currentStep: 'preview' }),
225
+ reset: () => set({ currentStep: 'metadata', step1Data: null, step2Data: null }),
226
+ }));
227
+ ```
228
+
229
+ ---
230
+
231
+ ## Cache Invalidation Strategy
232
+
233
+ Follow this decision tree when invalidating TanStack Query cache after mutations:
234
+
235
+ | Mutation | Invalidation Target |
236
+ |---|---|
237
+ | Create item | `queryKey: entityKeys.lists()` — all list queries |
238
+ | Update item | `queryKey: entityKeys.detail(id)` + `entityKeys.lists()` |
239
+ | Delete item | `queryKey: entityKeys.lists()` |
240
+ | Bulk action (delete multiple) | `queryKey: entityKeys.all` |
241
+ | Status toggle | `queryKey: entityKeys.detail(id)` + `entityKeys.lists()` |
242
+
243
+ Always use `invalidateQueries` (not `removeQueries`) so the UI shows stale data with
244
+ a loading indicator rather than an empty flash.
245
+
246
+ ---
247
+
248
+ ## Prefetching for Navigation
249
+
250
+ Prefetch list data when hovering a navigation link to make page transitions feel instant:
251
+
252
+ ```typescript
253
+ // In AppSidebar or NavigationLink component
254
+ import { useQueryClient } from '@tanstack/react-query';
255
+ import { heroSectionKeys } from '../../features/heroSection/hooks/useHeroSections';
256
+ import { heroSectionApi } from '../../features/heroSection/api/heroSectionApi';
257
+
258
+ function NavItemWithPrefetch({ item }: { item: NavItem }) {
259
+ const queryClient = useQueryClient();
260
+
261
+ const handleMouseEnter = () => {
262
+ // Prefetch the default page when the user hovers the nav item
263
+ queryClient.prefetchQuery({
264
+ queryKey: heroSectionKeys.list({ page: 0, size: 10 }),
265
+ queryFn: () => heroSectionApi.list({ page: 0, size: 10 }),
266
+ staleTime: 30_000,
267
+ });
268
+ };
269
+
270
+ return (
271
+ <ListItemButton onMouseEnter={handleMouseEnter} onClick={() => navigate(item.path)}>
272
+ ...
273
+ </ListItemButton>
274
+ );
275
+ }
276
+ ```
277
+
278
+ ---
279
+
280
+ ## Error State Handling in Pages
281
+
282
+ ```tsx
283
+ // Pattern for handling query errors in page components
284
+ import { Alert, Button, Box } from '@mui/material';
285
+
286
+ export function HeroSectionListPage() {
287
+ const { data, isLoading, isError, error, refetch } = useHeroSections(filters);
288
+
289
+ if (isError) {
290
+ return (
291
+ <Box sx={{ mt: 4 }}>
292
+ <Alert
293
+ severity="error"
294
+ action={
295
+ <Button color="inherit" size="small" onClick={() => refetch()}>
296
+ Retry
297
+ </Button>
298
+ }
299
+ >
300
+ {error instanceof Error ? error.message : 'Failed to load data. Please try again.'}
301
+ </Alert>
302
+ </Box>
303
+ );
304
+ }
305
+
306
+ // Normal render...
307
+ }
308
+ ```
309
+
310
+ ---
311
+
312
+ ## Scroll Position Restoration
313
+
314
+ React Router v7 handles scroll restoration automatically when navigating between routes.
315
+ For pages with virtual scroll or infinite pagination, use TanStack Query's `keepPreviousData`
316
+ equivalent:
317
+
318
+ ```typescript
319
+ export function useHeroSections(params: HeroSectionListParams) {
320
+ return useQuery({
321
+ queryKey: heroSectionKeys.list(params),
322
+ queryFn: () => heroSectionApi.list(params),
323
+ // Keep showing previous data while new data loads (avoids empty flash on page change)
324
+ placeholderData: (previousData) => previousData,
325
+ });
326
+ }
327
+ ```