ai-flow-dev 2.7.0 โ†’ 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +573 -570
  3. package/package.json +74 -74
  4. package/prompts/backend/flow-build-phase-0.md +535 -535
  5. package/prompts/backend/flow-build-phase-1.md +626 -626
  6. package/prompts/backend/flow-build-phase-10.md +340 -340
  7. package/prompts/backend/flow-build-phase-2.md +573 -573
  8. package/prompts/backend/flow-build-phase-3.md +834 -834
  9. package/prompts/backend/flow-build-phase-4.md +554 -554
  10. package/prompts/backend/flow-build-phase-5.md +703 -703
  11. package/prompts/backend/flow-build-phase-6.md +524 -524
  12. package/prompts/backend/flow-build-phase-7.md +1001 -1001
  13. package/prompts/backend/flow-build-phase-8.md +1407 -1407
  14. package/prompts/backend/flow-build-phase-9.md +477 -477
  15. package/prompts/backend/flow-build.md +137 -137
  16. package/prompts/backend/flow-check-review.md +656 -20
  17. package/prompts/backend/flow-check-test.md +526 -14
  18. package/prompts/backend/flow-check.md +725 -67
  19. package/prompts/backend/flow-commit.md +88 -119
  20. package/prompts/backend/flow-docs-sync.md +354 -354
  21. package/prompts/backend/flow-finish.md +919 -0
  22. package/prompts/backend/flow-release.md +949 -0
  23. package/prompts/backend/flow-work-feature.md +61 -61
  24. package/prompts/backend/flow-work-fix.md +46 -46
  25. package/prompts/backend/flow-work-refactor.md +48 -48
  26. package/prompts/backend/flow-work-resume.md +34 -34
  27. package/prompts/backend/flow-work.md +1098 -1286
  28. package/prompts/desktop/flow-build-phase-0.md +359 -359
  29. package/prompts/desktop/flow-build-phase-1.md +295 -295
  30. package/prompts/desktop/flow-build-phase-10.md +357 -357
  31. package/prompts/desktop/flow-build-phase-2.md +282 -282
  32. package/prompts/desktop/flow-build-phase-3.md +291 -291
  33. package/prompts/desktop/flow-build-phase-4.md +308 -308
  34. package/prompts/desktop/flow-build-phase-5.md +269 -269
  35. package/prompts/desktop/flow-build-phase-6.md +350 -350
  36. package/prompts/desktop/flow-build-phase-7.md +297 -297
  37. package/prompts/desktop/flow-build-phase-8.md +541 -541
  38. package/prompts/desktop/flow-build-phase-9.md +439 -439
  39. package/prompts/desktop/flow-build.md +156 -156
  40. package/prompts/desktop/flow-check-review.md +656 -20
  41. package/prompts/desktop/flow-check-test.md +526 -14
  42. package/prompts/desktop/flow-check.md +725 -67
  43. package/prompts/desktop/flow-commit.md +88 -119
  44. package/prompts/desktop/flow-docs-sync.md +354 -354
  45. package/prompts/desktop/flow-finish.md +910 -0
  46. package/prompts/desktop/flow-release.md +662 -0
  47. package/prompts/desktop/flow-work-feature.md +61 -61
  48. package/prompts/desktop/flow-work-fix.md +46 -46
  49. package/prompts/desktop/flow-work-refactor.md +48 -48
  50. package/prompts/desktop/flow-work-resume.md +34 -34
  51. package/prompts/desktop/flow-work.md +1202 -1390
  52. package/prompts/frontend/flow-build-phase-0.md +425 -425
  53. package/prompts/frontend/flow-build-phase-1.md +626 -626
  54. package/prompts/frontend/flow-build-phase-10.md +33 -33
  55. package/prompts/frontend/flow-build-phase-2.md +573 -573
  56. package/prompts/frontend/flow-build-phase-3.md +782 -782
  57. package/prompts/frontend/flow-build-phase-4.md +554 -554
  58. package/prompts/frontend/flow-build-phase-5.md +703 -703
  59. package/prompts/frontend/flow-build-phase-6.md +524 -524
  60. package/prompts/frontend/flow-build-phase-7.md +1001 -1001
  61. package/prompts/frontend/flow-build-phase-8.md +872 -872
  62. package/prompts/frontend/flow-build-phase-9.md +94 -94
  63. package/prompts/frontend/flow-build.md +137 -137
  64. package/prompts/frontend/flow-check-review.md +656 -20
  65. package/prompts/frontend/flow-check-test.md +526 -14
  66. package/prompts/frontend/flow-check.md +725 -67
  67. package/prompts/frontend/flow-commit.md +88 -119
  68. package/prompts/frontend/flow-docs-sync.md +550 -550
  69. package/prompts/frontend/flow-finish.md +910 -0
  70. package/prompts/frontend/flow-release.md +519 -0
  71. package/prompts/frontend/flow-work-api.md +1540 -0
  72. package/prompts/frontend/flow-work-feature.md +61 -61
  73. package/prompts/frontend/flow-work-fix.md +38 -38
  74. package/prompts/frontend/flow-work-refactor.md +48 -48
  75. package/prompts/frontend/flow-work-resume.md +34 -34
  76. package/prompts/frontend/flow-work.md +1583 -1320
  77. package/prompts/mobile/flow-build-phase-0.md +425 -425
  78. package/prompts/mobile/flow-build-phase-1.md +626 -626
  79. package/prompts/mobile/flow-build-phase-10.md +32 -32
  80. package/prompts/mobile/flow-build-phase-2.md +573 -573
  81. package/prompts/mobile/flow-build-phase-3.md +782 -782
  82. package/prompts/mobile/flow-build-phase-4.md +554 -554
  83. package/prompts/mobile/flow-build-phase-5.md +703 -703
  84. package/prompts/mobile/flow-build-phase-6.md +524 -524
  85. package/prompts/mobile/flow-build-phase-7.md +1001 -1001
  86. package/prompts/mobile/flow-build-phase-8.md +888 -888
  87. package/prompts/mobile/flow-build-phase-9.md +90 -90
  88. package/prompts/mobile/flow-build.md +135 -135
  89. package/prompts/mobile/flow-check-review.md +656 -20
  90. package/prompts/mobile/flow-check-test.md +526 -14
  91. package/prompts/mobile/flow-check.md +725 -67
  92. package/prompts/mobile/flow-commit.md +88 -119
  93. package/prompts/mobile/flow-docs-sync.md +620 -620
  94. package/prompts/mobile/flow-finish.md +910 -0
  95. package/prompts/mobile/flow-release.md +751 -0
  96. package/prompts/mobile/flow-work-api.md +1493 -0
  97. package/prompts/mobile/flow-work-feature.md +61 -61
  98. package/prompts/mobile/flow-work-fix.md +46 -46
  99. package/prompts/mobile/flow-work-refactor.md +48 -48
  100. package/prompts/mobile/flow-work-resume.md +34 -34
  101. package/prompts/mobile/flow-work.md +1593 -1329
  102. package/prompts/shared/mermaid-guidelines.md +102 -102
  103. package/prompts/shared/scope-levels.md +114 -114
  104. package/prompts/shared/smart-skip-preflight.md +214 -214
  105. package/prompts/shared/story-points.md +55 -55
  106. package/prompts/shared/task-format.md +74 -74
  107. package/prompts/shared/task-summary-template.md +277 -277
  108. package/templates/AGENT.template.md +443 -443
  109. package/templates/backend/.clauderules.template +112 -112
  110. package/templates/backend/.cursorrules.template +102 -102
  111. package/templates/backend/README.template.md +2 -2
  112. package/templates/backend/ai-instructions.template.md +2 -2
  113. package/templates/backend/copilot-instructions.template.md +2 -2
  114. package/templates/backend/docs/api.template.md +320 -320
  115. package/templates/backend/docs/business-flows.template.md +97 -97
  116. package/templates/backend/docs/code-standards.template.md +2 -2
  117. package/templates/backend/docs/contributing.template.md +3 -3
  118. package/templates/backend/docs/data-model.template.md +520 -520
  119. package/templates/backend/docs/testing.template.md +2 -2
  120. package/templates/backend/project-brief.template.md +2 -2
  121. package/templates/backend/specs/configuration.template.md +2 -2
  122. package/templates/backend/specs/security.template.md +2 -2
  123. package/templates/desktop/.clauderules.template +112 -112
  124. package/templates/desktop/.cursorrules.template +102 -102
  125. package/templates/desktop/README.template.md +170 -170
  126. package/templates/desktop/ai-instructions.template.md +366 -366
  127. package/templates/desktop/copilot-instructions.template.md +140 -140
  128. package/templates/desktop/docs/docs/api.template.md +320 -320
  129. package/templates/desktop/docs/docs/architecture.template.md +724 -724
  130. package/templates/desktop/docs/docs/business-flows.template.md +102 -102
  131. package/templates/desktop/docs/docs/code-standards.template.md +792 -792
  132. package/templates/desktop/docs/docs/contributing.template.md +149 -149
  133. package/templates/desktop/docs/docs/data-model.template.md +520 -520
  134. package/templates/desktop/docs/docs/operations.template.md +720 -720
  135. package/templates/desktop/docs/docs/testing.template.md +722 -722
  136. package/templates/desktop/project-brief.template.md +150 -150
  137. package/templates/desktop/specs/specs/configuration.template.md +121 -121
  138. package/templates/desktop/specs/specs/security.template.md +392 -392
  139. package/templates/frontend/README.template.md +2 -2
  140. package/templates/frontend/ai-instructions.template.md +2 -2
  141. package/templates/frontend/docs/api-integration.template.md +362 -362
  142. package/templates/frontend/docs/components.template.md +2 -2
  143. package/templates/frontend/docs/error-handling.template.md +360 -360
  144. package/templates/frontend/docs/operations.template.md +107 -107
  145. package/templates/frontend/docs/performance.template.md +124 -124
  146. package/templates/frontend/docs/pwa.template.md +119 -119
  147. package/templates/frontend/docs/state-management.template.md +2 -2
  148. package/templates/frontend/docs/styling.template.md +2 -2
  149. package/templates/frontend/docs/testing.template.md +2 -2
  150. package/templates/frontend/project-brief.template.md +2 -2
  151. package/templates/frontend/specs/accessibility.template.md +95 -95
  152. package/templates/frontend/specs/configuration.template.md +2 -2
  153. package/templates/frontend/specs/security.template.md +175 -175
  154. package/templates/fullstack/README.template.md +252 -252
  155. package/templates/fullstack/ai-instructions.template.md +444 -444
  156. package/templates/fullstack/project-brief.template.md +157 -157
  157. package/templates/fullstack/specs/configuration.template.md +340 -340
  158. package/templates/mobile/README.template.md +167 -167
  159. package/templates/mobile/ai-instructions.template.md +196 -196
  160. package/templates/mobile/docs/app-store.template.md +135 -135
  161. package/templates/mobile/docs/architecture.template.md +63 -63
  162. package/templates/mobile/docs/native-features.template.md +94 -94
  163. package/templates/mobile/docs/navigation.template.md +59 -59
  164. package/templates/mobile/docs/offline-strategy.template.md +65 -65
  165. package/templates/mobile/docs/permissions.template.md +56 -56
  166. package/templates/mobile/docs/state-management.template.md +85 -85
  167. package/templates/mobile/docs/testing.template.md +109 -109
  168. package/templates/mobile/project-brief.template.md +69 -69
  169. package/templates/mobile/specs/build-configuration.template.md +91 -91
  170. package/templates/mobile/specs/deployment.template.md +92 -92
  171. package/templates/work.template.md +47 -47
@@ -1,372 +1,372 @@
1
- # API Integration
2
-
3
- > API communication patterns and best practices for {{PROJECT_NAME}}
1
+ # API Integration
2
+
3
+ > API communication patterns and best practices for {{PROJECT_NAME}}
4
4
  ---
5
- ## ๐ŸŽฏ API Integration Strategy
6
-
7
- **Pattern:** {{API_INTEGRATION_PATTERN}}
8
- **Client:** {{API_CLIENT}}
9
- **Base URL:** {{API_BASE_URL}}
5
+ ## ๐ŸŽฏ API Integration Strategy
6
+
7
+ **Pattern:** {{API_INTEGRATION_PATTERN}}
8
+ **Client:** {{API_CLIENT}}
9
+ **Base URL:** {{API_BASE_URL}}
10
10
  ---
11
- ## ๐Ÿ“ก API Client Setup
12
-
13
- ### Base Configuration
14
-
15
- ```typescript
16
- // services/api.ts
17
- import axios from 'axios';
18
- // or: import { createClient } from '@urql/core';
19
-
20
- const apiClient = axios.create({
21
- baseURL: import.meta.env.VITE_API_BASE_URL,
22
- timeout: 30000,
23
- headers: {
24
- 'Content-Type': 'application/json',
25
- },
26
- });
27
-
28
- // Request interceptor
29
- apiClient.interceptors.request.use(
30
- (config) => {
31
- // Add auth token
32
- const token = getAuthToken();
33
- if (token) {
34
- config.headers.Authorization = `Bearer ${token}`;
35
- }
36
- return config;
37
- },
38
- (error) => Promise.reject(error)
39
- );
40
-
41
- // Response interceptor
42
- apiClient.interceptors.response.use(
43
- (response) => response,
44
- async (error) => {
45
- // Handle 401 - Unauthorized
46
- if (error.response?.status === 401) {
47
- await handleUnauthorized();
48
- }
49
- return Promise.reject(error);
50
- }
51
- );
52
-
53
- export default apiClient;
54
- ```
11
+ ## ๐Ÿ“ก API Client Setup
12
+
13
+ ### Base Configuration
14
+
15
+ ```typescript
16
+ // services/api.ts
17
+ import axios from 'axios';
18
+ // or: import { createClient } from '@urql/core';
19
+
20
+ const apiClient = axios.create({
21
+ baseURL: import.meta.env.VITE_API_BASE_URL,
22
+ timeout: 30000,
23
+ headers: {
24
+ 'Content-Type': 'application/json',
25
+ },
26
+ });
27
+
28
+ // Request interceptor
29
+ apiClient.interceptors.request.use(
30
+ (config) => {
31
+ // Add auth token
32
+ const token = getAuthToken();
33
+ if (token) {
34
+ config.headers.Authorization = `Bearer ${token}`;
35
+ }
36
+ return config;
37
+ },
38
+ (error) => Promise.reject(error)
39
+ );
40
+
41
+ // Response interceptor
42
+ apiClient.interceptors.response.use(
43
+ (response) => response,
44
+ async (error) => {
45
+ // Handle 401 - Unauthorized
46
+ if (error.response?.status === 401) {
47
+ await handleUnauthorized();
48
+ }
49
+ return Promise.reject(error);
50
+ }
51
+ );
52
+
53
+ export default apiClient;
54
+ ```
55
55
  ---
56
- ## ๐Ÿ—๏ธ API Layer Pattern
57
-
58
- ### Service Layer (Recommended)
59
-
60
- **Structure:**
61
- ```
62
- services/
63
- โ”œโ”€โ”€ api.ts # Base client configuration
64
- โ”œโ”€โ”€ users.ts # User endpoints
65
- โ”œโ”€โ”€ products.ts # Product endpoints
66
- โ””โ”€โ”€ orders.ts # Order endpoints
67
- ```
68
-
69
- **Example:**
70
- ```typescript
71
- // services/users.ts
72
- import apiClient from './api';
73
-
74
- export const usersService = {
75
- async getById(id: string): Promise<User> {
76
- const { data } = await apiClient.get(`/users/${id}`);
77
- return data;
78
- },
79
-
80
- async create(userData: CreateUserDto): Promise<User> {
81
- const { data } = await apiClient.post('/users', userData);
82
- return data;
83
- },
84
-
85
- async update(id: string, userData: UpdateUserDto): Promise<User> {
86
- const { data } = await apiClient.put(`/users/${id}`, userData);
87
- return data;
88
- },
89
-
90
- async delete(id: string): Promise<void> {
91
- await apiClient.delete(`/users/${id}`);
92
- },
93
- };
94
- ```
95
-
96
- ### Hooks/Composables Layer
97
-
98
- **React Example:**
99
- ```typescript
100
- // hooks/useUsers.ts
101
- import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
102
- import { usersService } from '@/services/users';
103
-
104
- export const useUsers = () => {
105
- const queryClient = useQueryClient();
106
-
107
- const getById = (id: string) => {
108
- return useQuery({
109
- queryKey: ['users', id],
110
- queryFn: () => usersService.getById(id),
111
- });
112
- };
113
-
114
- const create = useMutation({
115
- mutationFn: usersService.create,
116
- onSuccess: () => {
117
- queryClient.invalidateQueries({ queryKey: ['users'] });
118
- },
119
- });
120
-
121
- return { getById, create };
122
- };
123
- ```
124
-
125
- **Vue Example:**
126
- ```typescript
127
- // composables/useUsers.ts
128
- import { useQuery, useMutation } from '@tanstack/vue-query';
129
- import { usersService } from '@/services/users';
130
-
131
- export const useUsers = () => {
132
- const getById = (id: string) => {
133
- return useQuery({
134
- queryKey: ['users', id],
135
- queryFn: () => usersService.getById(id),
136
- });
137
- };
138
-
139
- const create = useMutation({
140
- mutationFn: usersService.create,
141
- });
142
-
143
- return { getById, create };
144
- };
145
- ```
56
+ ## ๐Ÿ—๏ธ API Layer Pattern
57
+
58
+ ### Service Layer (Recommended)
59
+
60
+ **Structure:**
61
+ ```
62
+ services/
63
+ โ”œโ”€โ”€ api.ts # Base client configuration
64
+ โ”œโ”€โ”€ users.ts # User endpoints
65
+ โ”œโ”€โ”€ products.ts # Product endpoints
66
+ โ””โ”€โ”€ orders.ts # Order endpoints
67
+ ```
68
+
69
+ **Example:**
70
+ ```typescript
71
+ // services/users.ts
72
+ import apiClient from './api';
73
+
74
+ export const usersService = {
75
+ async getById(id: string): Promise<User> {
76
+ const { data } = await apiClient.get(`/users/${id}`);
77
+ return data;
78
+ },
79
+
80
+ async create(userData: CreateUserDto): Promise<User> {
81
+ const { data } = await apiClient.post('/users', userData);
82
+ return data;
83
+ },
84
+
85
+ async update(id: string, userData: UpdateUserDto): Promise<User> {
86
+ const { data } = await apiClient.put(`/users/${id}`, userData);
87
+ return data;
88
+ },
89
+
90
+ async delete(id: string): Promise<void> {
91
+ await apiClient.delete(`/users/${id}`);
92
+ },
93
+ };
94
+ ```
95
+
96
+ ### Hooks/Composables Layer
97
+
98
+ **React Example:**
99
+ ```typescript
100
+ // hooks/useUsers.ts
101
+ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
102
+ import { usersService } from '@/services/users';
103
+
104
+ export const useUsers = () => {
105
+ const queryClient = useQueryClient();
106
+
107
+ const getById = (id: string) => {
108
+ return useQuery({
109
+ queryKey: ['users', id],
110
+ queryFn: () => usersService.getById(id),
111
+ });
112
+ };
113
+
114
+ const create = useMutation({
115
+ mutationFn: usersService.create,
116
+ onSuccess: () => {
117
+ queryClient.invalidateQueries({ queryKey: ['users'] });
118
+ },
119
+ });
120
+
121
+ return { getById, create };
122
+ };
123
+ ```
124
+
125
+ **Vue Example:**
126
+ ```typescript
127
+ // composables/useUsers.ts
128
+ import { useQuery, useMutation } from '@tanstack/vue-query';
129
+ import { usersService } from '@/services/users';
130
+
131
+ export const useUsers = () => {
132
+ const getById = (id: string) => {
133
+ return useQuery({
134
+ queryKey: ['users', id],
135
+ queryFn: () => usersService.getById(id),
136
+ });
137
+ };
138
+
139
+ const create = useMutation({
140
+ mutationFn: usersService.create,
141
+ });
142
+
143
+ return { getById, create };
144
+ };
145
+ ```
146
146
  ---
147
- ## ๐Ÿ”„ Error Handling
148
-
149
- ### Error Types
150
-
151
- ```typescript
152
- // types/api.ts
153
- export class ApiError extends Error {
154
- constructor(
155
- public status: number,
156
- public message: string,
157
- public code?: string
158
- ) {
159
- super(message);
160
- this.name = 'ApiError';
161
- }
162
- }
163
-
164
- export class NetworkError extends Error {
165
- constructor(message: string) {
166
- super(message);
167
- this.name = 'NetworkError';
168
- }
169
- }
170
-
171
- export class TimeoutError extends Error {
172
- constructor(message: string) {
173
- super(message);
174
- this.name = 'TimeoutError';
175
- }
176
- }
177
- ```
178
-
179
- ### Error Handling Strategy
180
-
181
- ```typescript
182
- // utils/errorHandler.ts
183
- import { ApiError, NetworkError, TimeoutError } from '@/types/api';
184
-
185
- export function handleApiError(error: unknown): string {
186
- if (error instanceof ApiError) {
187
- switch (error.status) {
188
- case 400:
189
- return 'Invalid request. Please check your input.';
190
- case 401:
191
- return 'Unauthorized. Please log in again.';
192
- case 403:
193
- return 'Access denied. You don\'t have permission.';
194
- case 404:
195
- return 'Resource not found.';
196
- case 500:
197
- return 'Server error. Please try again later.';
198
- default:
199
- return 'An error occurred. Please try again.';
200
- }
201
- }
202
-
203
- if (error instanceof NetworkError) {
204
- return 'Network error. Please check your connection.';
205
- }
206
-
207
- if (error instanceof TimeoutError) {
208
- return 'Request timed out. Please try again.';
209
- }
210
-
211
- return 'An unexpected error occurred.';
212
- }
213
- ```
147
+ ## ๐Ÿ”„ Error Handling
148
+
149
+ ### Error Types
150
+
151
+ ```typescript
152
+ // types/api.ts
153
+ export class ApiError extends Error {
154
+ constructor(
155
+ public status: number,
156
+ public message: string,
157
+ public code?: string
158
+ ) {
159
+ super(message);
160
+ this.name = 'ApiError';
161
+ }
162
+ }
163
+
164
+ export class NetworkError extends Error {
165
+ constructor(message: string) {
166
+ super(message);
167
+ this.name = 'NetworkError';
168
+ }
169
+ }
170
+
171
+ export class TimeoutError extends Error {
172
+ constructor(message: string) {
173
+ super(message);
174
+ this.name = 'TimeoutError';
175
+ }
176
+ }
177
+ ```
178
+
179
+ ### Error Handling Strategy
180
+
181
+ ```typescript
182
+ // utils/errorHandler.ts
183
+ import { ApiError, NetworkError, TimeoutError } from '@/types/api';
184
+
185
+ export function handleApiError(error: unknown): string {
186
+ if (error instanceof ApiError) {
187
+ switch (error.status) {
188
+ case 400:
189
+ return 'Invalid request. Please check your input.';
190
+ case 401:
191
+ return 'Unauthorized. Please log in again.';
192
+ case 403:
193
+ return 'Access denied. You don\'t have permission.';
194
+ case 404:
195
+ return 'Resource not found.';
196
+ case 500:
197
+ return 'Server error. Please try again later.';
198
+ default:
199
+ return 'An error occurred. Please try again.';
200
+ }
201
+ }
202
+
203
+ if (error instanceof NetworkError) {
204
+ return 'Network error. Please check your connection.';
205
+ }
206
+
207
+ if (error instanceof TimeoutError) {
208
+ return 'Request timed out. Please try again.';
209
+ }
210
+
211
+ return 'An unexpected error occurred.';
212
+ }
213
+ ```
214
214
  ---
215
- ## ๐Ÿ” Retry Strategy
216
-
217
- ### Automatic Retry
218
-
219
- ```typescript
220
- // utils/retry.ts
221
- export async function retryRequest<T>(
222
- fn: () => Promise<T>,
223
- maxRetries = 3,
224
- delay = 1000
225
- ): Promise<T> {
226
- for (let i = 0; i < maxRetries; i++) {
227
- try {
228
- return await fn();
229
- } catch (error) {
230
- if (i === maxRetries - 1) throw error;
231
-
232
- // Exponential backoff
233
- await new Promise(resolve => setTimeout(resolve, delay * Math.pow(2, i)));
234
- }
235
- }
236
- throw new Error('Max retries exceeded');
237
- }
238
- ```
239
-
240
- ### Usage with TanStack Query
241
-
242
- ```typescript
243
- import { useQuery } from '@tanstack/react-query';
244
-
245
- const { data } = useQuery({
246
- queryKey: ['users', id],
247
- queryFn: () => usersService.getById(id),
248
- retry: 3,
249
- retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
250
- });
251
- ```
215
+ ## ๐Ÿ” Retry Strategy
216
+
217
+ ### Automatic Retry
218
+
219
+ ```typescript
220
+ // utils/retry.ts
221
+ export async function retryRequest<T>(
222
+ fn: () => Promise<T>,
223
+ maxRetries = 3,
224
+ delay = 1000
225
+ ): Promise<T> {
226
+ for (let i = 0; i < maxRetries; i++) {
227
+ try {
228
+ return await fn();
229
+ } catch (error) {
230
+ if (i === maxRetries - 1) throw error;
231
+
232
+ // Exponential backoff
233
+ await new Promise(resolve => setTimeout(resolve, delay * Math.pow(2, i)));
234
+ }
235
+ }
236
+ throw new Error('Max retries exceeded');
237
+ }
238
+ ```
239
+
240
+ ### Usage with TanStack Query
241
+
242
+ ```typescript
243
+ import { useQuery } from '@tanstack/react-query';
244
+
245
+ const { data } = useQuery({
246
+ queryKey: ['users', id],
247
+ queryFn: () => usersService.getById(id),
248
+ retry: 3,
249
+ retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
250
+ });
251
+ ```
252
252
  ---
253
- ## ๐Ÿ” Authentication
254
-
255
- ### Token Management
256
-
257
- ```typescript
258
- // utils/auth.ts
259
- const TOKEN_KEY = 'auth_token';
260
-
261
- export function getAuthToken(): string | null {
262
- // Option 1: httpOnly cookie (most secure)
263
- // Token sent automatically with requests
264
-
265
- // Option 2: localStorage (less secure)
266
- return localStorage.getItem(TOKEN_KEY);
267
-
268
- // Option 3: Memory storage (most secure, lost on refresh)
269
- // Store in closure variable
270
- }
271
-
272
- export function setAuthToken(token: string): void {
273
- localStorage.setItem(TOKEN_KEY, token);
274
- }
275
-
276
- export function removeAuthToken(): void {
277
- localStorage.removeItem(TOKEN_KEY);
278
- }
279
- ```
280
-
281
- ### Token Refresh
282
-
283
- ```typescript
284
- // services/auth.ts
285
- let refreshTokenPromise: Promise<string> | null = null;
286
-
287
- export async function refreshAuthToken(): Promise<string> {
288
- if (refreshTokenPromise) {
289
- return refreshTokenPromise;
290
- }
291
-
292
- refreshTokenPromise = (async () => {
293
- try {
294
- const { data } = await apiClient.post('/auth/refresh');
295
- setAuthToken(data.accessToken);
296
- return data.accessToken;
297
- } finally {
298
- refreshTokenPromise = null;
299
- }
300
- })();
301
-
302
- return refreshTokenPromise;
303
- }
304
- ```
253
+ ## ๐Ÿ” Authentication
254
+
255
+ ### Token Management
256
+
257
+ ```typescript
258
+ // utils/auth.ts
259
+ const TOKEN_KEY = 'auth_token';
260
+
261
+ export function getAuthToken(): string | null {
262
+ // Option 1: httpOnly cookie (most secure)
263
+ // Token sent automatically with requests
264
+
265
+ // Option 2: localStorage (less secure)
266
+ return localStorage.getItem(TOKEN_KEY);
267
+
268
+ // Option 3: Memory storage (most secure, lost on refresh)
269
+ // Store in closure variable
270
+ }
271
+
272
+ export function setAuthToken(token: string): void {
273
+ localStorage.setItem(TOKEN_KEY, token);
274
+ }
275
+
276
+ export function removeAuthToken(): void {
277
+ localStorage.removeItem(TOKEN_KEY);
278
+ }
279
+ ```
280
+
281
+ ### Token Refresh
282
+
283
+ ```typescript
284
+ // services/auth.ts
285
+ let refreshTokenPromise: Promise<string> | null = null;
286
+
287
+ export async function refreshAuthToken(): Promise<string> {
288
+ if (refreshTokenPromise) {
289
+ return refreshTokenPromise;
290
+ }
291
+
292
+ refreshTokenPromise = (async () => {
293
+ try {
294
+ const { data } = await apiClient.post('/auth/refresh');
295
+ setAuthToken(data.accessToken);
296
+ return data.accessToken;
297
+ } finally {
298
+ refreshTokenPromise = null;
299
+ }
300
+ })();
301
+
302
+ return refreshTokenPromise;
303
+ }
304
+ ```
305
305
  ---
306
- ## ๐Ÿ“Š Request/Response Transformation
307
-
308
- ### Request Transformation
309
-
310
- ```typescript
311
- // Transform data before sending
312
- apiClient.interceptors.request.use((config) => {
313
- if (config.data) {
314
- // Convert dates to ISO strings
315
- config.data = transformDates(config.data);
316
- }
317
- return config;
318
- });
319
- ```
320
-
321
- ### Response Transformation
322
-
323
- ```typescript
324
- // Transform data after receiving
325
- apiClient.interceptors.response.use((response) => {
326
- if (response.data) {
327
- // Convert ISO strings to Date objects
328
- response.data = parseDates(response.data);
329
- }
330
- return response;
331
- });
332
- ```
306
+ ## ๐Ÿ“Š Request/Response Transformation
307
+
308
+ ### Request Transformation
309
+
310
+ ```typescript
311
+ // Transform data before sending
312
+ apiClient.interceptors.request.use((config) => {
313
+ if (config.data) {
314
+ // Convert dates to ISO strings
315
+ config.data = transformDates(config.data);
316
+ }
317
+ return config;
318
+ });
319
+ ```
320
+
321
+ ### Response Transformation
322
+
323
+ ```typescript
324
+ // Transform data after receiving
325
+ apiClient.interceptors.response.use((response) => {
326
+ if (response.data) {
327
+ // Convert ISO strings to Date objects
328
+ response.data = parseDates(response.data);
329
+ }
330
+ return response;
331
+ });
332
+ ```
333
333
  ---
334
- ## ๐Ÿงช Testing API Integration
335
-
336
- ### Mocking API Calls
337
-
338
- ```typescript
339
- // Using MSW (Mock Service Worker)
340
- import { rest } from 'msw';
341
- import { setupServer } from 'msw/node';
342
-
343
- const server = setupServer(
344
- rest.get('/api/users/:id', (req, res, ctx) => {
345
- return res(
346
- ctx.json({
347
- id: req.params.id,
348
- name: 'John Doe',
349
- email: 'john@example.com',
350
- })
351
- );
352
- })
353
- );
354
-
355
- beforeAll(() => server.listen());
356
- afterEach(() => server.resetHandlers());
357
- afterAll(() => server.close());
358
- ```
334
+ ## ๐Ÿงช Testing API Integration
335
+
336
+ ### Mocking API Calls
337
+
338
+ ```typescript
339
+ // Using MSW (Mock Service Worker)
340
+ import { rest } from 'msw';
341
+ import { setupServer } from 'msw/node';
342
+
343
+ const server = setupServer(
344
+ rest.get('/api/users/:id', (req, res, ctx) => {
345
+ return res(
346
+ ctx.json({
347
+ id: req.params.id,
348
+ name: 'John Doe',
349
+ email: 'john@example.com',
350
+ })
351
+ );
352
+ })
353
+ );
354
+
355
+ beforeAll(() => server.listen());
356
+ afterEach(() => server.resetHandlers());
357
+ afterAll(() => server.close());
358
+ ```
359
359
  ---
360
- ## ๐Ÿ”— Related Documents
361
-
362
- - [State Management](state-management.md) - Server state patterns
363
- - [Error Handling](error-handling.md) - Error handling strategies
364
- - [Security](security.md) - Security best practices
360
+ ## ๐Ÿ”— Related Documents
361
+
362
+ - [State Management](state-management.md) - Server state patterns
363
+ - [Error Handling](error-handling.md) - Error handling strategies
364
+ - [Security](security.md) - Security best practices
365
365
  ---
366
- **Last Updated:** {{GENERATION_DATE}}
367
-
368
- **API Pattern:** {{API_INTEGRATION_PATTERN}}
369
- **Client:** {{API_CLIENT}}
370
-
371
-
372
-
366
+ **Last Updated:** {{GENERATION_DATE}}
367
+
368
+ **API Pattern:** {{API_INTEGRATION_PATTERN}}
369
+ **Client:** {{API_CLIENT}}
370
+
371
+
372
+