maestro-bundle 1.3.0 → 1.4.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 +125 -37
- package/package.json +1 -1
- package/src/cli.mjs +7 -4
- package/templates/bundle-ai-agents/skills/agent-orchestration/SKILL.md +107 -41
- package/templates/bundle-ai-agents/skills/agent-orchestration/references/graph-patterns.md +50 -0
- package/templates/bundle-ai-agents/skills/agent-orchestration/references/routing-strategies.md +47 -0
- package/templates/bundle-ai-agents/skills/api-design/SKILL.md +125 -16
- package/templates/bundle-ai-agents/skills/api-design/references/pydantic-patterns.md +72 -0
- package/templates/bundle-ai-agents/skills/api-design/references/rest-conventions.md +51 -0
- package/templates/bundle-ai-agents/skills/clean-architecture/SKILL.md +113 -21
- package/templates/bundle-ai-agents/skills/clean-architecture/references/dependency-injection.md +60 -0
- package/templates/bundle-ai-agents/skills/clean-architecture/references/layer-rules.md +56 -0
- package/templates/bundle-ai-agents/skills/context-engineering/SKILL.md +104 -36
- package/templates/bundle-ai-agents/skills/context-engineering/references/compression-techniques.md +76 -0
- package/templates/bundle-ai-agents/skills/context-engineering/references/context-budget-calculator.md +45 -0
- package/templates/bundle-ai-agents/skills/database-modeling/SKILL.md +146 -19
- package/templates/bundle-ai-agents/skills/database-modeling/references/index-strategies.md +48 -0
- package/templates/bundle-ai-agents/skills/database-modeling/references/naming-conventions.md +27 -0
- package/templates/bundle-ai-agents/skills/docker-containerization/SKILL.md +124 -15
- package/templates/bundle-ai-agents/skills/docker-containerization/references/compose-patterns.md +97 -0
- package/templates/bundle-ai-agents/skills/docker-containerization/references/dockerfile-checklist.md +37 -0
- package/templates/bundle-ai-agents/skills/eval-testing/SKILL.md +113 -25
- package/templates/bundle-ai-agents/skills/eval-testing/references/eval-types.md +52 -0
- package/templates/bundle-ai-agents/skills/eval-testing/references/golden-dataset-template.md +59 -0
- package/templates/bundle-ai-agents/skills/memory-management/SKILL.md +112 -28
- package/templates/bundle-ai-agents/skills/memory-management/references/memory-tiers.md +41 -0
- package/templates/bundle-ai-agents/skills/memory-management/references/namespace-conventions.md +41 -0
- package/templates/bundle-ai-agents/skills/prompt-engineering/SKILL.md +139 -47
- package/templates/bundle-ai-agents/skills/prompt-engineering/references/anti-patterns.md +59 -0
- package/templates/bundle-ai-agents/skills/prompt-engineering/references/prompt-templates.md +75 -0
- package/templates/bundle-ai-agents/skills/rag-pipeline/SKILL.md +104 -27
- package/templates/bundle-ai-agents/skills/rag-pipeline/references/chunking-strategies.md +27 -0
- package/templates/bundle-ai-agents/skills/rag-pipeline/references/embedding-models.md +31 -0
- package/templates/bundle-ai-agents/skills/rag-pipeline/references/rag-evaluation.md +39 -0
- package/templates/bundle-ai-agents/skills/testing-strategy/SKILL.md +127 -18
- package/templates/bundle-ai-agents/skills/testing-strategy/references/fixture-patterns.md +81 -0
- package/templates/bundle-ai-agents/skills/testing-strategy/references/naming-conventions.md +69 -0
- package/templates/bundle-base/skills/branch-strategy/SKILL.md +134 -21
- package/templates/bundle-base/skills/branch-strategy/references/branch-rules.md +40 -0
- package/templates/bundle-base/skills/code-review/SKILL.md +123 -38
- package/templates/bundle-base/skills/code-review/references/review-checklist.md +45 -0
- package/templates/bundle-base/skills/commit-pattern/SKILL.md +98 -39
- package/templates/bundle-base/skills/commit-pattern/references/conventional-commits.md +40 -0
- package/templates/bundle-data-pipeline/skills/data-preprocessing/SKILL.md +110 -19
- package/templates/bundle-data-pipeline/skills/data-preprocessing/references/pandas-cheatsheet.md +63 -0
- package/templates/bundle-data-pipeline/skills/data-preprocessing/references/pandera-schemas.md +44 -0
- package/templates/bundle-data-pipeline/skills/docker-containerization/SKILL.md +132 -16
- package/templates/bundle-data-pipeline/skills/docker-containerization/references/compose-patterns.md +82 -0
- package/templates/bundle-data-pipeline/skills/docker-containerization/references/dockerfile-best-practices.md +57 -0
- package/templates/bundle-data-pipeline/skills/feature-engineering/SKILL.md +143 -45
- package/templates/bundle-data-pipeline/skills/feature-engineering/references/encoding-guide.md +41 -0
- package/templates/bundle-data-pipeline/skills/feature-engineering/references/scaling-guide.md +38 -0
- package/templates/bundle-data-pipeline/skills/mlops-pipeline/SKILL.md +156 -37
- package/templates/bundle-data-pipeline/skills/mlops-pipeline/references/mlflow-commands.md +69 -0
- package/templates/bundle-data-pipeline/skills/model-training/SKILL.md +152 -33
- package/templates/bundle-data-pipeline/skills/model-training/references/evaluation-metrics.md +52 -0
- package/templates/bundle-data-pipeline/skills/model-training/references/model-selection-guide.md +41 -0
- package/templates/bundle-data-pipeline/skills/rag-pipeline/SKILL.md +127 -39
- package/templates/bundle-data-pipeline/skills/rag-pipeline/references/chunking-strategies.md +51 -0
- package/templates/bundle-data-pipeline/skills/rag-pipeline/references/embedding-models.md +49 -0
- package/templates/bundle-frontend-spa/skills/authentication/SKILL.md +196 -13
- package/templates/bundle-frontend-spa/skills/authentication/references/jwt-security.md +41 -0
- package/templates/bundle-frontend-spa/skills/component-design/SKILL.md +191 -41
- package/templates/bundle-frontend-spa/skills/component-design/references/accessibility-checklist.md +41 -0
- package/templates/bundle-frontend-spa/skills/component-design/references/tailwind-patterns.md +65 -0
- package/templates/bundle-frontend-spa/skills/e2e-testing/SKILL.md +241 -79
- package/templates/bundle-frontend-spa/skills/e2e-testing/references/playwright-selectors.md +66 -0
- package/templates/bundle-frontend-spa/skills/e2e-testing/references/test-patterns.md +82 -0
- package/templates/bundle-frontend-spa/skills/integration-api/SKILL.md +221 -31
- package/templates/bundle-frontend-spa/skills/integration-api/references/api-patterns.md +81 -0
- package/templates/bundle-frontend-spa/skills/react-patterns/SKILL.md +195 -70
- package/templates/bundle-frontend-spa/skills/react-patterns/references/component-checklist.md +22 -0
- package/templates/bundle-frontend-spa/skills/react-patterns/references/hook-patterns.md +63 -0
- package/templates/bundle-frontend-spa/skills/responsive-layout/SKILL.md +162 -22
- package/templates/bundle-frontend-spa/skills/responsive-layout/references/breakpoint-guide.md +63 -0
- package/templates/bundle-frontend-spa/skills/state-management/SKILL.md +158 -30
- package/templates/bundle-frontend-spa/skills/state-management/references/react-query-config.md +64 -0
- package/templates/bundle-frontend-spa/skills/state-management/references/state-patterns.md +78 -0
- package/templates/bundle-jhipster-microservices/skills/ci-cd-pipeline/SKILL.md +135 -45
- package/templates/bundle-jhipster-microservices/skills/ci-cd-pipeline/references/gitlab-ci-templates.md +93 -0
- package/templates/bundle-jhipster-microservices/skills/clean-architecture/SKILL.md +87 -21
- package/templates/bundle-jhipster-microservices/skills/clean-architecture/references/layer-rules.md +78 -0
- package/templates/bundle-jhipster-microservices/skills/ddd-tactical/SKILL.md +94 -25
- package/templates/bundle-jhipster-microservices/skills/ddd-tactical/references/ddd-patterns.md +48 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-angular/SKILL.md +63 -21
- package/templates/bundle-jhipster-microservices/skills/jhipster-angular/references/angular-microservices.md +40 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-angular/references/angular-structure.md +59 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-docker-k8s/SKILL.md +125 -91
- package/templates/bundle-jhipster-microservices/skills/jhipster-docker-k8s/references/docker-k8s-commands.md +68 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-entities/SKILL.md +72 -20
- package/templates/bundle-jhipster-microservices/skills/jhipster-entities/references/cross-service-entities.md +36 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-entities/references/jdl-types.md +56 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-gateway/SKILL.md +80 -8
- package/templates/bundle-jhipster-microservices/skills/jhipster-gateway/references/gateway-config.md +43 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-kafka/SKILL.md +115 -22
- package/templates/bundle-jhipster-microservices/skills/jhipster-kafka/references/kafka-events.md +39 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-registry/SKILL.md +92 -23
- package/templates/bundle-jhipster-microservices/skills/jhipster-registry/references/consul-config.md +61 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-service/SKILL.md +81 -18
- package/templates/bundle-jhipster-microservices/skills/jhipster-service/references/service-patterns.md +40 -0
- package/templates/bundle-jhipster-microservices/skills/testing-strategy/SKILL.md +101 -20
- package/templates/bundle-jhipster-microservices/skills/testing-strategy/references/test-naming.md +55 -0
- package/templates/bundle-jhipster-monorepo/skills/clean-architecture/SKILL.md +87 -21
- package/templates/bundle-jhipster-monorepo/skills/clean-architecture/references/layer-rules.md +78 -0
- package/templates/bundle-jhipster-monorepo/skills/ddd-tactical/SKILL.md +94 -25
- package/templates/bundle-jhipster-monorepo/skills/ddd-tactical/references/ddd-patterns.md +48 -0
- package/templates/bundle-jhipster-monorepo/skills/jhipster-angular/SKILL.md +99 -52
- package/templates/bundle-jhipster-monorepo/skills/jhipster-angular/references/angular-structure.md +59 -0
- package/templates/bundle-jhipster-monorepo/skills/jhipster-entities/SKILL.md +89 -36
- package/templates/bundle-jhipster-monorepo/skills/jhipster-entities/references/jdl-types.md +56 -0
- package/templates/bundle-jhipster-monorepo/skills/jhipster-liquibase/SKILL.md +123 -23
- package/templates/bundle-jhipster-monorepo/skills/jhipster-liquibase/references/liquibase-operations.md +95 -0
- package/templates/bundle-jhipster-monorepo/skills/jhipster-security/SKILL.md +106 -19
- package/templates/bundle-jhipster-monorepo/skills/jhipster-security/references/security-checklist.md +47 -0
- package/templates/bundle-jhipster-monorepo/skills/jhipster-spring/SKILL.md +84 -16
- package/templates/bundle-jhipster-monorepo/skills/jhipster-spring/references/spring-layers.md +41 -0
- package/templates/bundle-jhipster-monorepo/skills/testing-strategy/SKILL.md +101 -20
- package/templates/bundle-jhipster-monorepo/skills/testing-strategy/references/test-naming.md +55 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Tailwind Breakpoint Guide
|
|
2
|
+
|
|
3
|
+
## Breakpoints
|
|
4
|
+
| Prefix | Min-width | Device Target |
|
|
5
|
+
|---|---|---|
|
|
6
|
+
| (none) | 0px | Mobile phones (portrait) |
|
|
7
|
+
| `sm:` | 640px | Mobile phones (landscape) |
|
|
8
|
+
| `md:` | 768px | Tablets |
|
|
9
|
+
| `lg:` | 1024px | Laptops / small desktops |
|
|
10
|
+
| `xl:` | 1280px | Desktops |
|
|
11
|
+
| `2xl:` | 1536px | Large monitors |
|
|
12
|
+
|
|
13
|
+
## Mobile-First Pattern
|
|
14
|
+
```html
|
|
15
|
+
<!-- Start with mobile, add overrides -->
|
|
16
|
+
<div class="
|
|
17
|
+
grid grid-cols-1 /* mobile: 1 column */
|
|
18
|
+
sm:grid-cols-2 /* 640px+: 2 columns */
|
|
19
|
+
lg:grid-cols-4 /* 1024px+: 4 columns */
|
|
20
|
+
gap-4
|
|
21
|
+
">
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Common Responsive Patterns
|
|
25
|
+
|
|
26
|
+
### Sidebar Layout
|
|
27
|
+
```html
|
|
28
|
+
<!-- Hidden on mobile, visible on desktop -->
|
|
29
|
+
<aside class="hidden lg:block w-64">
|
|
30
|
+
|
|
31
|
+
<!-- Full-width on mobile, fixed width on desktop -->
|
|
32
|
+
<aside class="fixed lg:static w-64 -translate-x-full lg:translate-x-0">
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Content Padding
|
|
36
|
+
```html
|
|
37
|
+
<main class="p-4 md:p-6 lg:p-8">
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Text Sizing
|
|
41
|
+
```html
|
|
42
|
+
<h1 class="text-xl md:text-2xl lg:text-3xl">
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Show/Hide Elements
|
|
46
|
+
```html
|
|
47
|
+
<!-- Mobile only -->
|
|
48
|
+
<button class="lg:hidden">Menu</button>
|
|
49
|
+
|
|
50
|
+
<!-- Desktop only -->
|
|
51
|
+
<nav class="hidden lg:flex">
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Container
|
|
55
|
+
```html
|
|
56
|
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Testing Responsive Design
|
|
60
|
+
1. Browser DevTools device toolbar (Ctrl+Shift+M)
|
|
61
|
+
2. Drag browser edge to resize manually
|
|
62
|
+
3. Test at exact breakpoints: 639px, 640px, 767px, 768px, 1023px, 1024px
|
|
63
|
+
4. Test with actual mobile devices if possible
|
|
@@ -1,66 +1,144 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: state-management
|
|
3
|
-
description:
|
|
3
|
+
description: Manage application state with Zustand for global UI state and React Query for server state. Use when you need to manage global state, cache API data, sync real-time WebSocket data, or decide which state solution to use.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
author: Maestro
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# State Management
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
Choose and implement the right state management solution for each type of state using Zustand, React Query, and React Hook Form.
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
## When to Use
|
|
13
|
+
- User needs to decide between Zustand, React Query, or useState
|
|
14
|
+
- User wants to create a global UI store (sidebar, theme, selections)
|
|
15
|
+
- User needs to set up server state caching with React Query
|
|
16
|
+
- User wants to add real-time WebSocket state
|
|
17
|
+
- User needs to manage complex form state
|
|
18
|
+
|
|
19
|
+
## Available Operations
|
|
20
|
+
1. Set up React Query provider and hooks for server state
|
|
21
|
+
2. Create Zustand stores for global UI state
|
|
22
|
+
3. Build WebSocket-connected stores for real-time data
|
|
23
|
+
4. Configure React Hook Form for form state
|
|
24
|
+
5. Diagnose and fix state management anti-patterns
|
|
25
|
+
|
|
26
|
+
## Multi-Step Workflow
|
|
27
|
+
|
|
28
|
+
### Step 1: Install Dependencies
|
|
29
|
+
```bash
|
|
30
|
+
npm install @tanstack/react-query zustand react-hook-form @hookform/resolvers zod socket.io-client
|
|
31
|
+
npm install -D @tanstack/react-query-devtools
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Step 2: Understand the State Decision Matrix
|
|
35
|
+
|
|
36
|
+
| State Type | Solution | Example |
|
|
11
37
|
|---|---|---|
|
|
12
|
-
| Server
|
|
13
|
-
| UI state
|
|
14
|
-
| UI state
|
|
15
|
-
| Form state | React Hook Form |
|
|
16
|
-
| Real-time
|
|
38
|
+
| Server data (API) | React Query | List of items, user profiles, search results |
|
|
39
|
+
| Global UI state | Zustand | Sidebar open/closed, theme, selected item ID |
|
|
40
|
+
| Local UI state | useState | Modal visibility, input value, toggle |
|
|
41
|
+
| Form state | React Hook Form | Form inputs, validation, submission |
|
|
42
|
+
| Real-time data | Zustand + WebSocket | Live agent status, event feed |
|
|
17
43
|
|
|
18
|
-
|
|
44
|
+
### Step 3: Set Up React Query Provider
|
|
45
|
+
```tsx
|
|
46
|
+
// src/main.tsx
|
|
47
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
48
|
+
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
|
19
49
|
|
|
50
|
+
const queryClient = new QueryClient({
|
|
51
|
+
defaultOptions: {
|
|
52
|
+
queries: {
|
|
53
|
+
staleTime: 30_000, // 30 seconds
|
|
54
|
+
retry: 2,
|
|
55
|
+
refetchOnWindowFocus: false,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
function App() {
|
|
61
|
+
return (
|
|
62
|
+
<QueryClientProvider client={queryClient}>
|
|
63
|
+
<Router />
|
|
64
|
+
<ReactQueryDevtools initialIsOpen={false} />
|
|
65
|
+
</QueryClientProvider>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Step 4: Create API Service and Query Hooks
|
|
20
71
|
```tsx
|
|
21
|
-
// services/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
72
|
+
// src/services/itemApi.ts
|
|
73
|
+
import { api } from '@/lib/api';
|
|
74
|
+
|
|
75
|
+
export const itemApi = {
|
|
76
|
+
list: (filters?: ItemFilters) =>
|
|
77
|
+
api.get<PaginatedResponse<Item>>('/api/v1/items', { params: filters }),
|
|
25
78
|
get: (id: string) =>
|
|
26
|
-
api.get<
|
|
27
|
-
create: (data:
|
|
28
|
-
api.post<
|
|
79
|
+
api.get<Item>(`/api/v1/items/${id}`),
|
|
80
|
+
create: (data: CreateItemDto) =>
|
|
81
|
+
api.post<Item>('/api/v1/items', data),
|
|
29
82
|
};
|
|
30
83
|
|
|
31
|
-
// hooks/
|
|
32
|
-
|
|
84
|
+
// src/hooks/useItems.ts
|
|
85
|
+
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
86
|
+
|
|
87
|
+
export function useItems(filters?: ItemFilters) {
|
|
33
88
|
return useQuery({
|
|
34
|
-
queryKey: ['
|
|
35
|
-
queryFn: () =>
|
|
89
|
+
queryKey: ['items', filters],
|
|
90
|
+
queryFn: () => itemApi.list(filters),
|
|
36
91
|
});
|
|
37
92
|
}
|
|
38
|
-
```
|
|
39
93
|
|
|
40
|
-
|
|
94
|
+
export function useCreateItem() {
|
|
95
|
+
const qc = useQueryClient();
|
|
96
|
+
return useMutation({
|
|
97
|
+
mutationFn: itemApi.create,
|
|
98
|
+
onSuccess: () => qc.invalidateQueries({ queryKey: ['items'] }),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
```
|
|
41
102
|
|
|
103
|
+
### Step 5: Create Zustand Store for UI State
|
|
42
104
|
```tsx
|
|
105
|
+
// src/stores/useAppStore.ts
|
|
106
|
+
import { create } from 'zustand';
|
|
107
|
+
|
|
43
108
|
interface AppStore {
|
|
44
109
|
sidebarOpen: boolean;
|
|
45
110
|
toggleSidebar: () => void;
|
|
46
|
-
|
|
47
|
-
|
|
111
|
+
selectedItemId: string | null;
|
|
112
|
+
selectItem: (id: string | null) => void;
|
|
113
|
+
theme: 'light' | 'dark';
|
|
114
|
+
setTheme: (theme: 'light' | 'dark') => void;
|
|
48
115
|
}
|
|
49
116
|
|
|
50
117
|
export const useAppStore = create<AppStore>((set) => ({
|
|
51
118
|
sidebarOpen: true,
|
|
52
119
|
toggleSidebar: () => set((s) => ({ sidebarOpen: !s.sidebarOpen })),
|
|
53
|
-
|
|
54
|
-
|
|
120
|
+
selectedItemId: null,
|
|
121
|
+
selectItem: (id) => set({ selectedItemId: id }),
|
|
122
|
+
theme: 'light',
|
|
123
|
+
setTheme: (theme) => set({ theme }),
|
|
55
124
|
}));
|
|
56
|
-
```
|
|
57
125
|
|
|
58
|
-
|
|
126
|
+
// Usage in components:
|
|
127
|
+
// const { sidebarOpen, toggleSidebar } = useAppStore();
|
|
128
|
+
// Or with selector for performance:
|
|
129
|
+
// const sidebarOpen = useAppStore((s) => s.sidebarOpen);
|
|
130
|
+
```
|
|
59
131
|
|
|
132
|
+
### Step 6: Add Real-Time WebSocket Store
|
|
60
133
|
```tsx
|
|
134
|
+
// src/stores/useRealtimeStore.ts
|
|
135
|
+
import { create } from 'zustand';
|
|
136
|
+
import { io, type Socket } from 'socket.io-client';
|
|
137
|
+
|
|
61
138
|
interface RealtimeStore {
|
|
62
139
|
agentStatuses: Record<string, AgentStatus>;
|
|
63
140
|
events: TrackingEvent[];
|
|
141
|
+
connected: boolean;
|
|
64
142
|
connect: () => void;
|
|
65
143
|
disconnect: () => void;
|
|
66
144
|
}
|
|
@@ -71,8 +149,12 @@ export const useRealtimeStore = create<RealtimeStore>((set) => {
|
|
|
71
149
|
return {
|
|
72
150
|
agentStatuses: {},
|
|
73
151
|
events: [],
|
|
152
|
+
connected: false,
|
|
153
|
+
|
|
74
154
|
connect: () => {
|
|
75
|
-
socket = io(
|
|
155
|
+
socket = io(import.meta.env.VITE_WS_URL || 'http://localhost:8000');
|
|
156
|
+
socket.on('connect', () => set({ connected: true }));
|
|
157
|
+
socket.on('disconnect', () => set({ connected: false }));
|
|
76
158
|
socket.on('agent:status', (data) =>
|
|
77
159
|
set((s) => ({ agentStatuses: { ...s.agentStatuses, [data.agentId]: data.status } }))
|
|
78
160
|
);
|
|
@@ -80,7 +162,53 @@ export const useRealtimeStore = create<RealtimeStore>((set) => {
|
|
|
80
162
|
set((s) => ({ events: [event, ...s.events].slice(0, 100) }))
|
|
81
163
|
);
|
|
82
164
|
},
|
|
83
|
-
|
|
165
|
+
|
|
166
|
+
disconnect: () => {
|
|
167
|
+
socket?.disconnect();
|
|
168
|
+
socket = null;
|
|
169
|
+
set({ connected: false });
|
|
170
|
+
},
|
|
84
171
|
};
|
|
85
172
|
});
|
|
86
173
|
```
|
|
174
|
+
|
|
175
|
+
### Step 7: Verify State Management
|
|
176
|
+
```bash
|
|
177
|
+
npm run dev
|
|
178
|
+
# Open http://localhost:5173
|
|
179
|
+
# Open React Query DevTools (floating button in bottom-right)
|
|
180
|
+
# Verify: queries are cached, mutations invalidate correctly
|
|
181
|
+
|
|
182
|
+
npx tsc --noEmit
|
|
183
|
+
# Check for TypeScript errors in stores and hooks
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Resources
|
|
187
|
+
- `references/state-patterns.md` - Common state patterns and anti-patterns
|
|
188
|
+
- `references/react-query-config.md` - React Query configuration reference
|
|
189
|
+
|
|
190
|
+
## Examples
|
|
191
|
+
### Example 1: Add a Global Store
|
|
192
|
+
User asks: "Create a store for managing the notification panel state"
|
|
193
|
+
Response approach:
|
|
194
|
+
1. Create `useNotificationStore` with Zustand
|
|
195
|
+
2. Add state: `isOpen`, `unreadCount`, `notifications[]`
|
|
196
|
+
3. Add actions: `toggle()`, `markRead(id)`, `addNotification()`
|
|
197
|
+
4. Show usage in the NotificationPanel component
|
|
198
|
+
5. Use selector pattern for performance
|
|
199
|
+
|
|
200
|
+
### Example 2: Fix State Duplication
|
|
201
|
+
User asks: "We have user data in both Zustand and React Query, which should we keep?"
|
|
202
|
+
Response approach:
|
|
203
|
+
1. Identify that server data belongs in React Query, not Zustand
|
|
204
|
+
2. Remove user data from Zustand store
|
|
205
|
+
3. Create `useCurrentUser()` hook with React Query
|
|
206
|
+
4. Keep only the auth token in Zustand (UI state)
|
|
207
|
+
5. Update components to use the new hook
|
|
208
|
+
|
|
209
|
+
## Notes
|
|
210
|
+
- Never duplicate API data in Zustand -- React Query is the source of truth for server state
|
|
211
|
+
- Use selectors with Zustand to prevent unnecessary re-renders: `useAppStore(s => s.sidebarOpen)`
|
|
212
|
+
- React Query DevTools are essential for debugging cache behavior
|
|
213
|
+
- Keep Zustand stores small and focused -- one store per domain, not one mega-store
|
|
214
|
+
- For WebSocket stores, always handle disconnect cleanup
|
package/templates/bundle-frontend-spa/skills/state-management/references/react-query-config.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# React Query Configuration Reference
|
|
2
|
+
|
|
3
|
+
## QueryClient Defaults
|
|
4
|
+
```tsx
|
|
5
|
+
const queryClient = new QueryClient({
|
|
6
|
+
defaultOptions: {
|
|
7
|
+
queries: {
|
|
8
|
+
staleTime: 30_000, // how long data is "fresh" (ms)
|
|
9
|
+
gcTime: 5 * 60_000, // garbage collection time (was cacheTime)
|
|
10
|
+
retry: 2, // retry failed requests
|
|
11
|
+
refetchOnWindowFocus: false, // disable refetch on tab focus
|
|
12
|
+
refetchOnReconnect: true, // refetch on network reconnect
|
|
13
|
+
},
|
|
14
|
+
mutations: {
|
|
15
|
+
retry: 0, // don't retry mutations
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Common Query Patterns
|
|
22
|
+
```tsx
|
|
23
|
+
// Basic query
|
|
24
|
+
useQuery({ queryKey: ['items'], queryFn: api.list })
|
|
25
|
+
|
|
26
|
+
// Query with parameters
|
|
27
|
+
useQuery({ queryKey: ['items', filters], queryFn: () => api.list(filters) })
|
|
28
|
+
|
|
29
|
+
// Conditional query
|
|
30
|
+
useQuery({ queryKey: ['item', id], queryFn: () => api.get(id), enabled: !!id })
|
|
31
|
+
|
|
32
|
+
// Polling
|
|
33
|
+
useQuery({ queryKey: ['status'], queryFn: api.getStatus, refetchInterval: 5000 })
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Query Key Conventions
|
|
37
|
+
```tsx
|
|
38
|
+
// Entity list
|
|
39
|
+
['items']
|
|
40
|
+
['items', { status: 'active', page: 1 }]
|
|
41
|
+
|
|
42
|
+
// Single entity
|
|
43
|
+
['items', itemId]
|
|
44
|
+
|
|
45
|
+
// Nested resource
|
|
46
|
+
['items', itemId, 'comments']
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Cache Invalidation
|
|
50
|
+
```tsx
|
|
51
|
+
const qc = useQueryClient();
|
|
52
|
+
|
|
53
|
+
// Invalidate all items queries
|
|
54
|
+
qc.invalidateQueries({ queryKey: ['items'] });
|
|
55
|
+
|
|
56
|
+
// Invalidate specific item
|
|
57
|
+
qc.invalidateQueries({ queryKey: ['items', itemId] });
|
|
58
|
+
|
|
59
|
+
// Set data directly (optimistic update)
|
|
60
|
+
qc.setQueryData(['items', itemId], updatedItem);
|
|
61
|
+
|
|
62
|
+
// Remove from cache
|
|
63
|
+
qc.removeQueries({ queryKey: ['items', itemId] });
|
|
64
|
+
```
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# State Patterns and Anti-Patterns
|
|
2
|
+
|
|
3
|
+
## Pattern: Selector-Based Zustand Access
|
|
4
|
+
```tsx
|
|
5
|
+
// GOOD: only re-renders when sidebarOpen changes
|
|
6
|
+
const sidebarOpen = useAppStore((s) => s.sidebarOpen);
|
|
7
|
+
|
|
8
|
+
// BAD: re-renders on ANY store change
|
|
9
|
+
const { sidebarOpen } = useAppStore();
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Pattern: Optimistic Updates
|
|
13
|
+
```tsx
|
|
14
|
+
const mutation = useMutation({
|
|
15
|
+
mutationFn: api.update,
|
|
16
|
+
onMutate: async (newData) => {
|
|
17
|
+
await qc.cancelQueries({ queryKey: ['items'] });
|
|
18
|
+
const previous = qc.getQueryData(['items']);
|
|
19
|
+
qc.setQueryData(['items'], (old) => ({ ...old, ...newData }));
|
|
20
|
+
return { previous };
|
|
21
|
+
},
|
|
22
|
+
onError: (_, __, context) => {
|
|
23
|
+
qc.setQueryData(['items'], context?.previous);
|
|
24
|
+
},
|
|
25
|
+
onSettled: () => {
|
|
26
|
+
qc.invalidateQueries({ queryKey: ['items'] });
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Anti-Pattern: Duplicating Server State
|
|
32
|
+
```tsx
|
|
33
|
+
// BAD: duplicating API data in Zustand
|
|
34
|
+
const useStore = create((set) => ({
|
|
35
|
+
users: [],
|
|
36
|
+
fetchUsers: async () => {
|
|
37
|
+
const users = await api.getUsers();
|
|
38
|
+
set({ users });
|
|
39
|
+
},
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
// GOOD: use React Query for server state
|
|
43
|
+
function useUsers() {
|
|
44
|
+
return useQuery({ queryKey: ['users'], queryFn: api.getUsers });
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Anti-Pattern: Mega Store
|
|
49
|
+
```tsx
|
|
50
|
+
// BAD: one store for everything
|
|
51
|
+
const useMegaStore = create((set) => ({
|
|
52
|
+
sidebar: true,
|
|
53
|
+
theme: 'light',
|
|
54
|
+
users: [],
|
|
55
|
+
notifications: [],
|
|
56
|
+
// ...50 more fields
|
|
57
|
+
}));
|
|
58
|
+
|
|
59
|
+
// GOOD: separate stores by domain
|
|
60
|
+
const useUIStore = create(/* UI state */);
|
|
61
|
+
const useNotificationStore = create(/* notification state */);
|
|
62
|
+
// Server state in React Query hooks
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Pattern: Persisted Zustand Store
|
|
66
|
+
```tsx
|
|
67
|
+
import { persist } from 'zustand/middleware';
|
|
68
|
+
|
|
69
|
+
const useSettingsStore = create(
|
|
70
|
+
persist(
|
|
71
|
+
(set) => ({
|
|
72
|
+
theme: 'light',
|
|
73
|
+
setTheme: (theme) => set({ theme }),
|
|
74
|
+
}),
|
|
75
|
+
{ name: 'settings-storage' }
|
|
76
|
+
)
|
|
77
|
+
);
|
|
78
|
+
```
|
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ci-cd-pipeline
|
|
3
|
-
description:
|
|
3
|
+
description: Create CI/CD pipelines with GitLab CI for JHipster microservices including lint, test, build, compliance check, and deploy. Use when setting up CI/CD, creating pipelines, automating deployments, or adding quality gates.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
author: Maestro
|
|
4
6
|
---
|
|
5
7
|
|
|
6
|
-
# CI/CD Pipeline
|
|
8
|
+
# CI/CD Pipeline
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
Create and configure GitLab CI pipelines for JHipster microservices with stages for lint, test, security, compliance, build, and deploy.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
- When setting up CI/CD for a new microservice
|
|
14
|
+
- When adding quality gates (lint, test, security scan)
|
|
15
|
+
- When automating Docker builds and pushes
|
|
16
|
+
- When configuring deployment to K3s/Kubernetes
|
|
17
|
+
- When adding compliance checks
|
|
18
|
+
|
|
19
|
+
## Available Operations
|
|
20
|
+
1. Create `.gitlab-ci.yml` with all stages
|
|
21
|
+
2. Configure lint and test stages
|
|
22
|
+
3. Set up Docker image build with Jib
|
|
23
|
+
4. Configure deployment to Kubernetes
|
|
24
|
+
5. Add security scanning
|
|
25
|
+
|
|
26
|
+
## Multi-Step Workflow
|
|
27
|
+
|
|
28
|
+
### Step 1: Create Pipeline File
|
|
9
29
|
|
|
10
30
|
```yaml
|
|
11
31
|
# .gitlab-ci.yml
|
|
@@ -13,7 +33,6 @@ stages:
|
|
|
13
33
|
- lint
|
|
14
34
|
- test
|
|
15
35
|
- security
|
|
16
|
-
- compliance
|
|
17
36
|
- build
|
|
18
37
|
- deploy-staging
|
|
19
38
|
- deploy-prod
|
|
@@ -21,15 +40,23 @@ stages:
|
|
|
21
40
|
variables:
|
|
22
41
|
DOCKER_IMAGE: $CI_REGISTRY_IMAGE
|
|
23
42
|
K3S_NAMESPACE: maestro
|
|
43
|
+
MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"
|
|
24
44
|
|
|
25
|
-
|
|
26
|
-
|
|
45
|
+
cache:
|
|
46
|
+
paths:
|
|
47
|
+
- .m2/repository/
|
|
48
|
+
- node_modules/
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Step 2: Add Lint and Test Stages
|
|
52
|
+
|
|
53
|
+
```yaml
|
|
54
|
+
lint:backend:
|
|
27
55
|
stage: lint
|
|
28
|
-
image:
|
|
56
|
+
image: maven:3.9-eclipse-temurin-21
|
|
29
57
|
script:
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
- mypy src/ --ignore-missing-imports
|
|
58
|
+
- ./mvnw checkstyle:check -DskipTests
|
|
59
|
+
- ./mvnw pmd:check -DskipTests
|
|
33
60
|
|
|
34
61
|
lint:frontend:
|
|
35
62
|
stage: lint
|
|
@@ -37,76 +64,139 @@ lint:frontend:
|
|
|
37
64
|
script:
|
|
38
65
|
- npm ci
|
|
39
66
|
- npm run lint
|
|
40
|
-
- npm run type-check
|
|
41
67
|
|
|
42
|
-
# ===== TEST =====
|
|
43
68
|
test:backend:
|
|
44
69
|
stage: test
|
|
45
|
-
image:
|
|
70
|
+
image: maven:3.9-eclipse-temurin-21
|
|
46
71
|
services:
|
|
47
72
|
- postgres:16
|
|
48
|
-
- redis:7
|
|
49
73
|
variables:
|
|
50
|
-
|
|
51
|
-
|
|
74
|
+
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/testdb
|
|
75
|
+
SPRING_DATASOURCE_USERNAME: test
|
|
76
|
+
SPRING_DATASOURCE_PASSWORD: test
|
|
52
77
|
script:
|
|
53
|
-
-
|
|
54
|
-
-
|
|
78
|
+
- ./mvnw verify -Pprod -DskipTests=false
|
|
79
|
+
- ./mvnw test -Dtest="*IT" -DfailIfNoTests=false
|
|
55
80
|
artifacts:
|
|
56
81
|
reports:
|
|
57
|
-
|
|
58
|
-
coverage_format: cobertura
|
|
59
|
-
path: coverage.xml
|
|
82
|
+
junit: target/surefire-reports/*.xml
|
|
60
83
|
|
|
61
84
|
test:frontend:
|
|
62
85
|
stage: test
|
|
63
86
|
image: node:20-slim
|
|
64
87
|
script:
|
|
65
88
|
- npm ci
|
|
66
|
-
- npm
|
|
89
|
+
- npm test -- --coverage
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Step 3: Add Security Scanning
|
|
67
93
|
|
|
68
|
-
|
|
69
|
-
security:
|
|
94
|
+
```yaml
|
|
95
|
+
security:dependencies:
|
|
70
96
|
stage: security
|
|
71
|
-
image:
|
|
97
|
+
image: maven:3.9-eclipse-temurin-21
|
|
72
98
|
script:
|
|
73
|
-
-
|
|
74
|
-
|
|
75
|
-
|
|
99
|
+
- ./mvnw org.owasp:dependency-check-maven:check
|
|
100
|
+
allow_failure: true
|
|
101
|
+
artifacts:
|
|
102
|
+
paths:
|
|
103
|
+
- target/dependency-check-report.html
|
|
104
|
+
```
|
|
76
105
|
|
|
77
|
-
|
|
78
|
-
compliance:bundle:
|
|
79
|
-
stage: compliance
|
|
80
|
-
script:
|
|
81
|
-
- python scripts/check_bundle_compliance.py --bundle $BUNDLE_NAME
|
|
82
|
-
- python scripts/check_structure.py
|
|
83
|
-
allow_failure: false
|
|
106
|
+
### Step 4: Add Docker Build
|
|
84
107
|
|
|
85
|
-
|
|
86
|
-
build:
|
|
108
|
+
```yaml
|
|
109
|
+
build:image:
|
|
87
110
|
stage: build
|
|
88
111
|
script:
|
|
89
|
-
|
|
90
|
-
-
|
|
112
|
+
# Build with Jib (no Docker daemon needed)
|
|
113
|
+
- ./mvnw -ntp verify -DskipTests jib:build
|
|
114
|
+
-Djib.to.image=$DOCKER_IMAGE:$CI_COMMIT_SHA
|
|
115
|
+
-Djib.to.auth.username=$CI_REGISTRY_USER
|
|
116
|
+
-Djib.to.auth.password=$CI_REGISTRY_PASSWORD
|
|
91
117
|
only:
|
|
92
118
|
- main
|
|
93
119
|
- develop
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Step 5: Add Deployment Stages
|
|
94
123
|
|
|
95
|
-
|
|
124
|
+
```yaml
|
|
96
125
|
deploy:staging:
|
|
97
126
|
stage: deploy-staging
|
|
127
|
+
image: bitnami/kubectl:latest
|
|
98
128
|
script:
|
|
99
|
-
- kubectl -n $K3S_NAMESPACE-staging set image
|
|
100
|
-
|
|
129
|
+
- kubectl -n $K3S_NAMESPACE-staging set image
|
|
130
|
+
deployment/$CI_PROJECT_NAME
|
|
131
|
+
app=$DOCKER_IMAGE:$CI_COMMIT_SHA
|
|
132
|
+
- kubectl -n $K3S_NAMESPACE-staging rollout status
|
|
133
|
+
deployment/$CI_PROJECT_NAME --timeout=120s
|
|
101
134
|
only:
|
|
102
135
|
- develop
|
|
103
136
|
|
|
104
137
|
deploy:prod:
|
|
105
138
|
stage: deploy-prod
|
|
139
|
+
image: bitnami/kubectl:latest
|
|
106
140
|
script:
|
|
107
|
-
- kubectl -n $K3S_NAMESPACE set image
|
|
108
|
-
|
|
141
|
+
- kubectl -n $K3S_NAMESPACE set image
|
|
142
|
+
deployment/$CI_PROJECT_NAME
|
|
143
|
+
app=$DOCKER_IMAGE:$CI_COMMIT_SHA
|
|
144
|
+
- kubectl -n $K3S_NAMESPACE rollout status
|
|
145
|
+
deployment/$CI_PROJECT_NAME --timeout=120s
|
|
109
146
|
only:
|
|
110
147
|
- main
|
|
111
|
-
when: manual
|
|
148
|
+
when: manual # Requires manual approval
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Step 6: Verify Pipeline
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# Validate gitlab-ci.yml syntax
|
|
155
|
+
gitlab-ci-lint .gitlab-ci.yml
|
|
156
|
+
|
|
157
|
+
# Or validate via GitLab API
|
|
158
|
+
curl --header "PRIVATE-TOKEN: $TOKEN" \
|
|
159
|
+
"https://gitlab.local/api/v4/ci/lint" \
|
|
160
|
+
--form "content=@.gitlab-ci.yml"
|
|
161
|
+
|
|
162
|
+
# Check pipeline status
|
|
163
|
+
git push && echo "Check pipeline at: https://gitlab.local/$PROJECT/pipelines"
|
|
112
164
|
```
|
|
165
|
+
|
|
166
|
+
## Resources
|
|
167
|
+
- `references/gitlab-ci-templates.md` - Reusable GitLab CI templates and patterns
|
|
168
|
+
|
|
169
|
+
## Examples
|
|
170
|
+
|
|
171
|
+
### Example 1: Setup CI for New Service
|
|
172
|
+
User asks: "Set up CI/CD for the new notification-service"
|
|
173
|
+
Response approach:
|
|
174
|
+
1. Create `.gitlab-ci.yml` in service root
|
|
175
|
+
2. Add lint, test, build stages
|
|
176
|
+
3. Configure PostgreSQL service for tests
|
|
177
|
+
4. Add Jib build step
|
|
178
|
+
5. Push and verify pipeline runs
|
|
179
|
+
|
|
180
|
+
### Example 2: Add Deployment Stage
|
|
181
|
+
User asks: "Add automatic deploy to staging on develop branch"
|
|
182
|
+
Response approach:
|
|
183
|
+
1. Add `deploy:staging` stage with kubectl
|
|
184
|
+
2. Configure K8s credentials as CI variables
|
|
185
|
+
3. Set `only: develop` trigger
|
|
186
|
+
4. Test with a push to develop
|
|
187
|
+
|
|
188
|
+
### Example 3: Pipeline is Failing
|
|
189
|
+
User asks: "Tests are failing in CI but pass locally"
|
|
190
|
+
Response approach:
|
|
191
|
+
1. Check CI logs for the specific failure
|
|
192
|
+
2. Compare CI environment (Java version, PostgreSQL version)
|
|
193
|
+
3. Verify environment variables are set in CI
|
|
194
|
+
4. Check if test depends on local-only resources
|
|
195
|
+
5. Fix and push to re-trigger pipeline
|
|
196
|
+
|
|
197
|
+
## Notes
|
|
198
|
+
- Use `cache` for Maven/npm dependencies to speed up builds
|
|
199
|
+
- `when: manual` for production deploys (requires human approval)
|
|
200
|
+
- Store secrets in GitLab CI variables, never in `.gitlab-ci.yml`
|
|
201
|
+
- Use Jib for Docker builds (no Docker daemon required)
|
|
202
|
+
- Each microservice has its own pipeline
|