Skip to content

Commit 932917b

Browse files
Copilotastandrik
andauthored
feat: improve guidelines basing on reviews (#2662)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: astandrik <[email protected]> Co-authored-by: astandrik <[email protected]>
1 parent eb90c31 commit 932917b

File tree

3 files changed

+239
-0
lines changed

3 files changed

+239
-0
lines changed

.github/copilot-instructions.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,50 @@ This is a React-based monitoring and management interface for YDB clusters. The
1616
- Use React Router v5 (NOT v6) for routing
1717
- Use Monaco Editor 0.52 for code editing features
1818

19+
## Critical Bug Prevention Patterns
20+
21+
### React Performance (MANDATORY)
22+
23+
- **ALWAYS** use `useMemo` for expensive computations, object/array creation
24+
- **ALWAYS** use `useCallback` for functions in effect dependencies
25+
- **ALWAYS** memoize table columns, filtered data, computed values
26+
- **AVOID** `useEffect` when possible - prefer direct approaches with `useCallback`
27+
- **PREFER** direct event handlers and callbacks over useEffect for user interactions
28+
29+
```typescript
30+
// ✅ REQUIRED patterns
31+
const displaySegments = useMemo(() => segments.filter((segment) => segment.visible), [segments]);
32+
const handleClick = useCallback(() => {
33+
// logic
34+
}, [dependency]);
35+
36+
// ✅ PREFER direct callbacks over useEffect
37+
const handleInputChange = useCallback(
38+
(value: string) => {
39+
setSearchTerm(value);
40+
onSearchChange?.(value);
41+
},
42+
[onSearchChange],
43+
);
44+
45+
// ❌ AVOID unnecessary useEffect
46+
// useEffect(() => {
47+
// onSearchChange?.(searchTerm);
48+
// }, [searchTerm, onSearchChange]);
49+
```
50+
51+
### Memory & Display Safety
52+
53+
- **ALWAYS** provide fallback values: `Number(value) || 0`
54+
- **NEVER** allow division by zero: `capacity > 0 ? value/capacity : 0`
55+
- **ALWAYS** dispose Monaco Editor: `return () => editor.dispose();` in useEffect
56+
57+
### Security & Input Validation
58+
59+
- **NEVER** expose authentication tokens in logs or console
60+
- **ALWAYS** validate user input before processing
61+
- **NEVER** skip error handling for async operations
62+
1963
## Critical Coding Rules
2064

2165
### API Architecture
@@ -88,18 +132,50 @@ This is a React-based monitoring and management interface for YDB clusters. The
88132
- Use React Router v5 hooks (`useHistory`, `useParams`)
89133
- Always validate route params exist before use
90134

135+
### URL Parameter Management (MANDATORY)
136+
137+
- **PREFER** `use-query-params` over `redux-location-state` for new development
138+
- **ALWAYS** use Zod schemas for URL parameter validation with fallbacks
139+
- **ALWAYS** use `z.enum([...]).catch(defaultValue)` pattern for safe parsing
140+
- Use custom `QueryParamConfig` objects for encoding/decoding complex parameters
141+
142+
```typescript
143+
// ✅ REQUIRED pattern for URL parameters
144+
const sortColumnSchema = z.enum(['column1', 'column2', 'column3']).catch('column1');
145+
146+
const SortOrderParam: QueryParamConfig<SortOrder[]> = {
147+
encode: (value) => (value ? encodeURIComponent(JSON.stringify(value)) : undefined),
148+
decode: (value) => {
149+
try {
150+
return value ? JSON.parse(decodeURIComponent(value)) : [];
151+
} catch {
152+
return [];
153+
}
154+
},
155+
};
156+
```
157+
91158
## Common Utilities
92159

93160
- Formatters: `formatBytes()`, `formatDateTime()` from `src/utils/dataFormatters/`
94161
- Time parsing: utilities in `src/utils/timeParsers/`
95162
- Query utilities: `src/utils/query.ts` for SQL/YQL helpers
96163

164+
## Development Commands
165+
166+
```bash
167+
npm run lint # Run all linters before committing
168+
npm run typecheck # TypeScript type checking
169+
npm run unused # Find unused code
170+
```
171+
97172
## Before Making Changes
98173

99174
- Run `npm run lint` and `npm run typecheck` before committing
100175
- Follow conventional commit message format
101176
- Use conventional commit format for PR titles with lowercase subjects (e.g., "fix: update api endpoints", "feat: add new component", "chore: update dependencies")
102177
- PR title subjects must be lowercase (no proper nouns, sentence-case, start-case, pascal-case, or upper-case)
178+
- PR title must not exceed 72 characters (keep them concise and descriptive)
103179
- Ensure all user-facing text is internationalized
104180
- Test with a local YDB instance when possible
105181

@@ -108,3 +184,10 @@ This is a React-based monitoring and management interface for YDB clusters. The
108184
- `window.api` - Access API methods in browser console
109185
- `window.ydbEditor` - Monaco editor instance
110186
- Enable request tracing with `DEV_ENABLE_TRACING_FOR_ALL_REQUESTS`
187+
188+
## Environment Variables
189+
190+
- `REACT_APP_BACKEND` - Backend URL for single-cluster mode
191+
- `REACT_APP_META_BACKEND` - Meta backend URL for multi-cluster mode
192+
- `PUBLIC_URL` - Base URL for static assets (use `.` for relative paths)
193+
- `GENERATE_SOURCEMAP` - Set to `false` for production builds

AGENTS.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,57 @@ src/
9191
3. **Feature-based Organization**: Features grouped with their state, API, and components
9292
4. **Separation of Concerns**: Clear separation between UI and business logic
9393

94+
## Critical Bug Prevention Patterns
95+
96+
### Memory Management
97+
98+
- **ALWAYS** dispose Monaco Editor instances: `return () => editor.dispose();` in useEffect
99+
- **NEVER** allow memory leaks in long-running components
100+
- Clear timeouts and intervals in cleanup functions
101+
102+
### React Performance (MANDATORY)
103+
104+
- **ALWAYS** use `useMemo` for expensive computations and object/array creation
105+
- **ALWAYS** use `useCallback` for functions passed to dependencies
106+
- **ALWAYS** memoize table columns, filtered data, and computed values
107+
- **AVOID** `useEffect` when possible - prefer direct approaches with `useCallback`
108+
- **PREFER** direct event handlers and callbacks over useEffect for user interactions
109+
110+
```typescript
111+
// ✅ REQUIRED patterns
112+
const displaySegments = useMemo(() => segments.filter((segment) => segment.visible), [segments]);
113+
const handleClick = useCallback(() => {
114+
// logic
115+
}, [dependency]);
116+
117+
// ✅ PREFER direct callbacks over useEffect
118+
const handleInputChange = useCallback(
119+
(value: string) => {
120+
setSearchTerm(value);
121+
onSearchChange?.(value);
122+
},
123+
[onSearchChange],
124+
);
125+
126+
// ❌ AVOID unnecessary useEffect
127+
// useEffect(() => {
128+
// onSearchChange?.(searchTerm);
129+
// }, [searchTerm, onSearchChange]);
130+
```
131+
132+
### Display Safety
133+
134+
- **ALWAYS** provide fallback values: `Number(value) || 0`
135+
- **NEVER** allow division by zero: `capacity > 0 ? value/capacity : 0`
136+
- **ALWAYS** handle null/undefined data gracefully
137+
138+
### Security & Input Validation
139+
140+
- **NEVER** expose authentication tokens in logs or console output
141+
- **ALWAYS** validate user input before processing
142+
- **NEVER** skip error handling for async operations
143+
- Sanitize data before displaying in UI components
144+
94145
## Important Development Notes
95146

96147
### Testing Backend Connection
@@ -216,6 +267,31 @@ Complex modals use `@ebay/nice-modal-react` library. Simple dialogs use Gravity
216267

217268
Uses React Router v5 hooks (`useHistory`, `useParams`, etc.). Always validate route params exist before using them.
218269

270+
### URL Parameter Management
271+
272+
- **PREFER** `use-query-params` over `redux-location-state` for new development
273+
- **ALWAYS** use Zod schemas for URL parameter validation with fallbacks
274+
- Use custom `QueryParamConfig` objects for encoding/decoding complex parameters
275+
- Use `z.enum([...]).catch(defaultValue)` pattern for safe parsing with fallbacks
276+
277+
```typescript
278+
// ✅ PREFERRED pattern for URL parameters
279+
const sortColumnSchema = z.enum(['column1', 'column2', 'column3']).catch('column1');
280+
281+
const SortOrderParam: QueryParamConfig<SortOrder[]> = {
282+
encode: (value) => (value ? encodeURIComponent(JSON.stringify(value)) : undefined),
283+
decode: (value) => {
284+
try {
285+
return value ? JSON.parse(decodeURIComponent(value)) : [];
286+
} catch {
287+
return [];
288+
}
289+
},
290+
};
291+
292+
const [urlParam, setUrlParam] = useQueryParam('sort', SortOrderParam);
293+
```
294+
219295
### Critical Rules
220296

221297
- **NEVER** call APIs directly - use `window.api.module.method()`
@@ -226,6 +302,8 @@ Uses React Router v5 hooks (`useHistory`, `useParams`, etc.). Always validate ro
226302
- **ALWAYS** handle loading states in UI
227303
- **ALWAYS** validate route params exist before use
228304
- **ALWAYS** follow i18n naming rules from `i18n-naming-ruleset.md`
305+
- **ALWAYS** use Zod schemas for URL parameter validation with fallbacks
306+
- **PREFER** `use-query-params` over `redux-location-state` for new URL parameter handling
229307

230308
### Debugging Tips
231309

CLAUDE.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,57 @@ src/
9191
3. **Feature-based Organization**: Features grouped with their state, API, and components
9292
4. **Separation of Concerns**: Clear separation between UI and business logic
9393

94+
## Critical Bug Prevention Patterns
95+
96+
### Memory Management
97+
98+
- **ALWAYS** dispose Monaco Editor instances: `return () => editor.dispose();` in useEffect
99+
- **NEVER** allow memory leaks in long-running components
100+
- Clear timeouts and intervals in cleanup functions
101+
102+
### React Performance (MANDATORY)
103+
104+
- **ALWAYS** use `useMemo` for expensive computations and object/array creation
105+
- **ALWAYS** use `useCallback` for functions passed to dependencies
106+
- **ALWAYS** memoize table columns, filtered data, and computed values
107+
- **AVOID** `useEffect` when possible - prefer direct approaches with `useCallback`
108+
- **PREFER** direct event handlers and callbacks over useEffect for user interactions
109+
110+
```typescript
111+
// ✅ REQUIRED patterns
112+
const displaySegments = useMemo(() => segments.filter((segment) => segment.visible), [segments]);
113+
const handleClick = useCallback(() => {
114+
// logic
115+
}, [dependency]);
116+
117+
// ✅ PREFER direct callbacks over useEffect
118+
const handleInputChange = useCallback(
119+
(value: string) => {
120+
setSearchTerm(value);
121+
onSearchChange?.(value);
122+
},
123+
[onSearchChange],
124+
);
125+
126+
// ❌ AVOID unnecessary useEffect
127+
// useEffect(() => {
128+
// onSearchChange?.(searchTerm);
129+
// }, [searchTerm, onSearchChange]);
130+
```
131+
132+
### Display Safety
133+
134+
- **ALWAYS** provide fallback values: `Number(value) || 0`
135+
- **NEVER** allow division by zero: `capacity > 0 ? value/capacity : 0`
136+
- **ALWAYS** handle null/undefined data gracefully
137+
138+
### Security & Input Validation
139+
140+
- **NEVER** expose authentication tokens in logs or console output
141+
- **ALWAYS** validate user input before processing
142+
- **NEVER** skip error handling for async operations
143+
- Sanitize data before displaying in UI components
144+
94145
## Important Development Notes
95146

96147
### Testing Backend Connection
@@ -216,6 +267,31 @@ Complex modals use `@ebay/nice-modal-react` library. Simple dialogs use Gravity
216267

217268
Uses React Router v5 hooks (`useHistory`, `useParams`, etc.). Always validate route params exist before using them.
218269

270+
### URL Parameter Management
271+
272+
- **PREFER** `use-query-params` over `redux-location-state` for new development
273+
- **ALWAYS** use Zod schemas for URL parameter validation with fallbacks
274+
- Use custom `QueryParamConfig` objects for encoding/decoding complex parameters
275+
- Use `z.enum([...]).catch(defaultValue)` pattern for safe parsing with fallbacks
276+
277+
```typescript
278+
// ✅ PREFERRED pattern for URL parameters
279+
const sortColumnSchema = z.enum(['column1', 'column2', 'column3']).catch('column1');
280+
281+
const SortOrderParam: QueryParamConfig<SortOrder[]> = {
282+
encode: (value) => (value ? encodeURIComponent(JSON.stringify(value)) : undefined),
283+
decode: (value) => {
284+
try {
285+
return value ? JSON.parse(decodeURIComponent(value)) : [];
286+
} catch {
287+
return [];
288+
}
289+
},
290+
};
291+
292+
const [urlParam, setUrlParam] = useQueryParam('sort', SortOrderParam);
293+
```
294+
219295
### Critical Rules
220296

221297
- **NEVER** call APIs directly - use `window.api.module.method()`
@@ -226,6 +302,8 @@ Uses React Router v5 hooks (`useHistory`, `useParams`, etc.). Always validate ro
226302
- **ALWAYS** handle loading states in UI
227303
- **ALWAYS** validate route params exist before use
228304
- **ALWAYS** follow i18n naming rules from `i18n-naming-ruleset.md`
305+
- **ALWAYS** use Zod schemas for URL parameter validation with fallbacks
306+
- **PREFER** `use-query-params` over `redux-location-state` for new URL parameter handling
229307

230308
### Debugging Tips
231309

0 commit comments

Comments
 (0)