Skip to content

Commit 836bd58

Browse files
committed
fix: final adjustements
1 parent 105cd03 commit 836bd58

File tree

2 files changed

+72
-26
lines changed

2 files changed

+72
-26
lines changed

.github/copilot-instructions.md

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ This is a React-based monitoring and management interface for YDB clusters. The
1919
## Critical Bug Prevention Patterns
2020

2121
### React Performance (MANDATORY)
22+
2223
- **ALWAYS** use `useMemo` for expensive computations, object/array creation
2324
- **ALWAYS** use `useCallback` for functions in effect dependencies
2425
- **ALWAYS** memoize table columns, filtered data, computed values
@@ -27,18 +28,19 @@ This is a React-based monitoring and management interface for YDB clusters. The
2728

2829
```typescript
2930
// ✅ REQUIRED patterns
30-
const displaySegments = useMemo(() =>
31-
segments.filter(segment => segment.visible), [segments]
32-
);
31+
const displaySegments = useMemo(() => segments.filter((segment) => segment.visible), [segments]);
3332
const handleClick = useCallback(() => {
3433
// logic
3534
}, [dependency]);
3635

3736
// ✅ PREFER direct callbacks over useEffect
38-
const handleInputChange = useCallback((value: string) => {
39-
setSearchTerm(value);
40-
onSearchChange?.(value);
41-
}, [onSearchChange]);
37+
const handleInputChange = useCallback(
38+
(value: string) => {
39+
setSearchTerm(value);
40+
onSearchChange?.(value);
41+
},
42+
[onSearchChange],
43+
);
4244

4345
// ❌ AVOID unnecessary useEffect
4446
// useEffect(() => {
@@ -47,11 +49,13 @@ const handleInputChange = useCallback((value: string) => {
4749
```
4850

4951
### Memory & Display Safety
52+
5053
- **ALWAYS** provide fallback values: `Number(value) || 0`
5154
- **NEVER** allow division by zero: `capacity > 0 ? value/capacity : 0`
5255
- **ALWAYS** dispose Monaco Editor: `return () => editor.dispose();` in useEffect
5356

5457
### Security & Input Validation
58+
5559
- **NEVER** expose authentication tokens in logs or console
5660
- **ALWAYS** validate user input before processing
5761
- **NEVER** skip error handling for async operations
@@ -137,19 +141,17 @@ const handleInputChange = useCallback((value: string) => {
137141

138142
```typescript
139143
// ✅ REQUIRED pattern for URL parameters
140-
const sortColumnSchema = z
141-
.enum(['column1', 'column2', 'column3'])
142-
.catch('column1');
144+
const sortColumnSchema = z.enum(['column1', 'column2', 'column3']).catch('column1');
143145

144146
const SortOrderParam: QueryParamConfig<SortOrder[]> = {
145-
encode: (value) => value ? encodeURIComponent(JSON.stringify(value)) : undefined,
146-
decode: (value) => {
147-
try {
148-
return value ? JSON.parse(decodeURIComponent(value)) : [];
149-
} catch {
150-
return [];
151-
}
152-
},
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+
},
153155
};
154156
```
155157

@@ -159,6 +161,14 @@ const SortOrderParam: QueryParamConfig<SortOrder[]> = {
159161
- Time parsing: utilities in `src/utils/timeParsers/`
160162
- Query utilities: `src/utils/query.ts` for SQL/YQL helpers
161163

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+
162172
## Before Making Changes
163173

164174
- Run `npm run lint` and `npm run typecheck` before committing
@@ -173,3 +183,10 @@ const SortOrderParam: QueryParamConfig<SortOrder[]> = {
173183
- `window.api` - Access API methods in browser console
174184
- `window.ydbEditor` - Monaco editor instance
175185
- Enable request tracing with `DEV_ENABLE_TRACING_FOR_ALL_REQUESTS`
186+
187+
## Environment Variables
188+
189+
- `REACT_APP_BACKEND` - Backend URL for single-cluster mode
190+
- `REACT_APP_META_BACKEND` - Meta backend URL for multi-cluster mode
191+
- `PUBLIC_URL` - Base URL for static assets (use `.` for relative paths)
192+
- `GENERATE_SOURCEMAP` - Set to `false` for production builds

AGENTS.md

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,13 @@ src/
9494
## Critical Bug Prevention Patterns
9595

9696
### Memory Management
97+
9798
- **ALWAYS** dispose Monaco Editor instances: `return () => editor.dispose();` in useEffect
9899
- **NEVER** allow memory leaks in long-running components
99100
- Clear timeouts and intervals in cleanup functions
100101

101102
### React Performance (MANDATORY)
103+
102104
- **ALWAYS** use `useMemo` for expensive computations and object/array creation
103105
- **ALWAYS** use `useCallback` for functions passed to dependencies
104106
- **ALWAYS** memoize table columns, filtered data, and computed values
@@ -107,18 +109,19 @@ src/
107109

108110
```typescript
109111
// ✅ REQUIRED patterns
110-
const displaySegments = useMemo(() =>
111-
segments.filter(segment => segment.visible), [segments]
112-
);
112+
const displaySegments = useMemo(() => segments.filter((segment) => segment.visible), [segments]);
113113
const handleClick = useCallback(() => {
114114
// logic
115115
}, [dependency]);
116116

117117
// ✅ PREFER direct callbacks over useEffect
118-
const handleInputChange = useCallback((value: string) => {
119-
setSearchTerm(value);
120-
onSearchChange?.(value);
121-
}, [onSearchChange]);
118+
const handleInputChange = useCallback(
119+
(value: string) => {
120+
setSearchTerm(value);
121+
onSearchChange?.(value);
122+
},
123+
[onSearchChange],
124+
);
122125

123126
// ❌ AVOID unnecessary useEffect
124127
// useEffect(() => {
@@ -127,11 +130,13 @@ const handleInputChange = useCallback((value: string) => {
127130
```
128131

129132
### Display Safety
133+
130134
- **ALWAYS** provide fallback values: `Number(value) || 0`
131135
- **NEVER** allow division by zero: `capacity > 0 ? value/capacity : 0`
132136
- **ALWAYS** handle null/undefined data gracefully
133137

134138
### Security & Input Validation
139+
135140
- **NEVER** expose authentication tokens in logs or console output
136141
- **ALWAYS** validate user input before processing
137142
- **NEVER** skip error handling for async operations
@@ -262,6 +267,31 @@ Complex modals use `@ebay/nice-modal-react` library. Simple dialogs use Gravity
262267

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

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+
265295
### Critical Rules
266296

267297
- **NEVER** call APIs directly - use `window.api.module.method()`
@@ -274,7 +304,6 @@ Uses React Router v5 hooks (`useHistory`, `useParams`, etc.). Always validate ro
274304
- **ALWAYS** follow i18n naming rules from `i18n-naming-ruleset.md`
275305
- **ALWAYS** use Zod schemas for URL parameter validation with fallbacks
276306
- **PREFER** `use-query-params` over `redux-location-state` for new URL parameter handling
277-
- **PREFER** `use-query-params` over `redux-location-state` for new URL parameter handling
278307

279308
### Debugging Tips
280309

0 commit comments

Comments
 (0)