Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,50 @@ This is a React-based monitoring and management interface for YDB clusters. The
- Use React Router v5 (NOT v6) for routing
- Use Monaco Editor 0.52 for code editing features

## Critical Bug Prevention Patterns

### React Performance (MANDATORY)

- **ALWAYS** use `useMemo` for expensive computations, object/array creation
- **ALWAYS** use `useCallback` for functions in effect dependencies
- **ALWAYS** memoize table columns, filtered data, computed values
- **AVOID** `useEffect` when possible - prefer direct approaches with `useCallback`
- **PREFER** direct event handlers and callbacks over useEffect for user interactions

```typescript
// ✅ REQUIRED patterns
const displaySegments = useMemo(() => segments.filter((segment) => segment.visible), [segments]);
const handleClick = useCallback(() => {
// logic
}, [dependency]);

// ✅ PREFER direct callbacks over useEffect
const handleInputChange = useCallback(
(value: string) => {
setSearchTerm(value);
onSearchChange?.(value);
},
[onSearchChange],
);

// ❌ AVOID unnecessary useEffect
// useEffect(() => {
// onSearchChange?.(searchTerm);
// }, [searchTerm, onSearchChange]);
```

### Memory & Display Safety

- **ALWAYS** provide fallback values: `Number(value) || 0`
- **NEVER** allow division by zero: `capacity > 0 ? value/capacity : 0`
- **ALWAYS** dispose Monaco Editor: `return () => editor.dispose();` in useEffect

### Security & Input Validation

- **NEVER** expose authentication tokens in logs or console
- **ALWAYS** validate user input before processing
- **NEVER** skip error handling for async operations

## Critical Coding Rules

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

### URL Parameter Management (MANDATORY)

- **PREFER** `use-query-params` over `redux-location-state` for new development
- **ALWAYS** use Zod schemas for URL parameter validation with fallbacks
- **ALWAYS** use `z.enum([...]).catch(defaultValue)` pattern for safe parsing
- Use custom `QueryParamConfig` objects for encoding/decoding complex parameters

```typescript
// ✅ REQUIRED pattern for URL parameters
const sortColumnSchema = z.enum(['column1', 'column2', 'column3']).catch('column1');

const SortOrderParam: QueryParamConfig<SortOrder[]> = {
encode: (value) => (value ? encodeURIComponent(JSON.stringify(value)) : undefined),
decode: (value) => {
try {
return value ? JSON.parse(decodeURIComponent(value)) : [];
} catch {
return [];
}
},
};
```

## Common Utilities

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

## Development Commands

```bash
npm run lint # Run all linters before committing
npm run typecheck # TypeScript type checking
npm run unused # Find unused code
```

## Before Making Changes

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

Expand All @@ -108,3 +184,10 @@ This is a React-based monitoring and management interface for YDB clusters. The
- `window.api` - Access API methods in browser console
- `window.ydbEditor` - Monaco editor instance
- Enable request tracing with `DEV_ENABLE_TRACING_FOR_ALL_REQUESTS`

## Environment Variables

- `REACT_APP_BACKEND` - Backend URL for single-cluster mode
- `REACT_APP_META_BACKEND` - Meta backend URL for multi-cluster mode
- `PUBLIC_URL` - Base URL for static assets (use `.` for relative paths)
- `GENERATE_SOURCEMAP` - Set to `false` for production builds
78 changes: 78 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,57 @@ src/
3. **Feature-based Organization**: Features grouped with their state, API, and components
4. **Separation of Concerns**: Clear separation between UI and business logic

## Critical Bug Prevention Patterns

### Memory Management

- **ALWAYS** dispose Monaco Editor instances: `return () => editor.dispose();` in useEffect
- **NEVER** allow memory leaks in long-running components
- Clear timeouts and intervals in cleanup functions

### React Performance (MANDATORY)

- **ALWAYS** use `useMemo` for expensive computations and object/array creation
- **ALWAYS** use `useCallback` for functions passed to dependencies
- **ALWAYS** memoize table columns, filtered data, and computed values
- **AVOID** `useEffect` when possible - prefer direct approaches with `useCallback`
- **PREFER** direct event handlers and callbacks over useEffect for user interactions

```typescript
// ✅ REQUIRED patterns
const displaySegments = useMemo(() => segments.filter((segment) => segment.visible), [segments]);
const handleClick = useCallback(() => {
// logic
}, [dependency]);

// ✅ PREFER direct callbacks over useEffect
const handleInputChange = useCallback(
(value: string) => {
setSearchTerm(value);
onSearchChange?.(value);
},
[onSearchChange],
);

// ❌ AVOID unnecessary useEffect
// useEffect(() => {
// onSearchChange?.(searchTerm);
// }, [searchTerm, onSearchChange]);
```

### Display Safety

- **ALWAYS** provide fallback values: `Number(value) || 0`
- **NEVER** allow division by zero: `capacity > 0 ? value/capacity : 0`
- **ALWAYS** handle null/undefined data gracefully

### Security & Input Validation

- **NEVER** expose authentication tokens in logs or console output
- **ALWAYS** validate user input before processing
- **NEVER** skip error handling for async operations
- Sanitize data before displaying in UI components

## Important Development Notes

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

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

### URL Parameter Management

- **PREFER** `use-query-params` over `redux-location-state` for new development
- **ALWAYS** use Zod schemas for URL parameter validation with fallbacks
- Use custom `QueryParamConfig` objects for encoding/decoding complex parameters
- Use `z.enum([...]).catch(defaultValue)` pattern for safe parsing with fallbacks

```typescript
// ✅ PREFERRED pattern for URL parameters
const sortColumnSchema = z.enum(['column1', 'column2', 'column3']).catch('column1');

const SortOrderParam: QueryParamConfig<SortOrder[]> = {
encode: (value) => (value ? encodeURIComponent(JSON.stringify(value)) : undefined),
decode: (value) => {
try {
return value ? JSON.parse(decodeURIComponent(value)) : [];
} catch {
return [];
}
},
};

const [urlParam, setUrlParam] = useQueryParam('sort', SortOrderParam);
```

### Critical Rules

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

### Debugging Tips

Expand Down
78 changes: 78 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,57 @@ src/
3. **Feature-based Organization**: Features grouped with their state, API, and components
4. **Separation of Concerns**: Clear separation between UI and business logic

## Critical Bug Prevention Patterns

### Memory Management

- **ALWAYS** dispose Monaco Editor instances: `return () => editor.dispose();` in useEffect
- **NEVER** allow memory leaks in long-running components
- Clear timeouts and intervals in cleanup functions

### React Performance (MANDATORY)

- **ALWAYS** use `useMemo` for expensive computations and object/array creation
- **ALWAYS** use `useCallback` for functions passed to dependencies
- **ALWAYS** memoize table columns, filtered data, and computed values
- **AVOID** `useEffect` when possible - prefer direct approaches with `useCallback`
- **PREFER** direct event handlers and callbacks over useEffect for user interactions

```typescript
// ✅ REQUIRED patterns
const displaySegments = useMemo(() => segments.filter((segment) => segment.visible), [segments]);
const handleClick = useCallback(() => {
// logic
}, [dependency]);

// ✅ PREFER direct callbacks over useEffect
const handleInputChange = useCallback(
(value: string) => {
setSearchTerm(value);
onSearchChange?.(value);
},
[onSearchChange],
);

// ❌ AVOID unnecessary useEffect
// useEffect(() => {
// onSearchChange?.(searchTerm);
// }, [searchTerm, onSearchChange]);
```

### Display Safety

- **ALWAYS** provide fallback values: `Number(value) || 0`
- **NEVER** allow division by zero: `capacity > 0 ? value/capacity : 0`
- **ALWAYS** handle null/undefined data gracefully

### Security & Input Validation

- **NEVER** expose authentication tokens in logs or console output
- **ALWAYS** validate user input before processing
- **NEVER** skip error handling for async operations
- Sanitize data before displaying in UI components

## Important Development Notes

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

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

### URL Parameter Management

- **PREFER** `use-query-params` over `redux-location-state` for new development
- **ALWAYS** use Zod schemas for URL parameter validation with fallbacks
- Use custom `QueryParamConfig` objects for encoding/decoding complex parameters
- Use `z.enum([...]).catch(defaultValue)` pattern for safe parsing with fallbacks

```typescript
// ✅ PREFERRED pattern for URL parameters
const sortColumnSchema = z.enum(['column1', 'column2', 'column3']).catch('column1');

const SortOrderParam: QueryParamConfig<SortOrder[]> = {
encode: (value) => (value ? encodeURIComponent(JSON.stringify(value)) : undefined),
decode: (value) => {
try {
return value ? JSON.parse(decodeURIComponent(value)) : [];
} catch {
return [];
}
},
};

const [urlParam, setUrlParam] = useQueryParam('sort', SortOrderParam);
```

### Critical Rules

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

### Debugging Tips

Expand Down
Loading