|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +This file provides guidance to AI coding assistants when working with this codebase. Designed for OpenAI Codex, GitHub Copilot, Claude, Cursor, and other AI development tools. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +YDB Embedded UI is a web-based monitoring and management interface for YDB (Yet another DataBase) clusters. It provides comprehensive tools for viewing database diagnostics, managing storage/nodes/tablets, executing queries, and monitoring cluster health. |
| 8 | + |
| 9 | +## Tech Stack |
| 10 | + |
| 11 | +- **Framework**: React 18.3 with TypeScript 5.x |
| 12 | +- **State Management**: Redux Toolkit 2.x with RTK Query |
| 13 | +- **UI Components**: Gravity UI (@gravity-ui/uikit) 7.x |
| 14 | +- **Routing**: React Router v5 (not v6) |
| 15 | +- **Build Tool**: Create React App with react-app-rewired |
| 16 | +- **Code Editor**: Monaco Editor 0.52 |
| 17 | +- **Testing**: Jest + React Testing Library (unit), Playwright (E2E) |
| 18 | +- **Package Manager**: npm |
| 19 | +- **Node Version**: 18+ recommended |
| 20 | + |
| 21 | +## Essential Development Commands |
| 22 | + |
| 23 | +### Quick Start |
| 24 | + |
| 25 | +```bash |
| 26 | +npm ci # Install dependencies |
| 27 | +npm run dev # Start development server (port 3000) |
| 28 | +``` |
| 29 | + |
| 30 | +### Build Commands |
| 31 | + |
| 32 | +```bash |
| 33 | +npm run build # Standard production build |
| 34 | +npm run build:embedded # Build for embedding in YDB servers |
| 35 | +npm run build:embedded:archive # Build embedded version + create zip |
| 36 | +npm run build:embedded-mc # Build multi-cluster embedded version |
| 37 | +npm run analyze # Analyze bundle size with source-map-explorer |
| 38 | +npm run package # Build library distribution |
| 39 | +``` |
| 40 | + |
| 41 | +### Code Quality (Run these before committing!) |
| 42 | + |
| 43 | +```bash |
| 44 | +npm run lint # Run all linters (JS/TS + CSS) |
| 45 | +npm run typecheck # TypeScript type checking |
| 46 | +npm run unused # Find unused code |
| 47 | +``` |
| 48 | + |
| 49 | +### Testing |
| 50 | + |
| 51 | +```bash |
| 52 | +npm test # Run unit tests |
| 53 | +npm test -- --watch # Run tests in watch mode |
| 54 | +npm run test:e2e # Run Playwright E2E tests |
| 55 | +npm run test:e2e:local # Run E2E against local dev server |
| 56 | +``` |
| 57 | + |
| 58 | +## Architecture Overview |
| 59 | + |
| 60 | +### State Management |
| 61 | + |
| 62 | +- Uses Redux Toolkit with RTK Query for API calls |
| 63 | +- State organized by feature domains in `src/store/reducers/` |
| 64 | +- API endpoints injected using RTK Query's `injectEndpoints` pattern |
| 65 | +- Each domain has its reducer file (e.g., `cluster.ts`, `tenant.ts`) |
| 66 | + |
| 67 | +### API Architecture |
| 68 | + |
| 69 | +Modular API service pattern with domain-specific modules: |
| 70 | + |
| 71 | +- `YdbEmbeddedAPI` is the main API class |
| 72 | +- Modules: `ViewerAPI`, `StorageAPI`, `TabletsAPI`, `SchemeAPI`, etc. |
| 73 | +- API services in `src/services/api/` directory |
| 74 | + |
| 75 | +### Component Organization |
| 76 | + |
| 77 | +``` |
| 78 | +src/ |
| 79 | +├── components/ # Reusable UI components |
| 80 | +├── containers/ # Feature-specific containers |
| 81 | +├── services/ # API services and parsers |
| 82 | +├── store/ # Redux store and reducers |
| 83 | +├── types/ # TypeScript definitions |
| 84 | +└── utils/ # Utility functions |
| 85 | +``` |
| 86 | + |
| 87 | +### Key Architectural Patterns |
| 88 | + |
| 89 | +1. **Component Registry Pattern**: Runtime registration of extensible components |
| 90 | +2. **Slots Pattern**: Component composition with extensibility points |
| 91 | +3. **Feature-based Organization**: Features grouped with their state, API, and components |
| 92 | +4. **Separation of Concerns**: Clear separation between UI and business logic |
| 93 | + |
| 94 | +## Important Development Notes |
| 95 | + |
| 96 | +### Testing Backend Connection |
| 97 | + |
| 98 | +To test with a local YDB instance: |
| 99 | + |
| 100 | +```bash |
| 101 | +# Pull and run YDB docker (use specific version or nightly) |
| 102 | +docker pull ghcr.io/ydb-platform/local-ydb:nightly |
| 103 | +docker run -dp 8765:8765 ghcr.io/ydb-platform/local-ydb:nightly |
| 104 | + |
| 105 | +# Start the UI |
| 106 | +npm run dev |
| 107 | + |
| 108 | +# View Swagger API documentation |
| 109 | +# Navigate to: http://localhost:8765/viewer/api/ |
| 110 | +``` |
| 111 | + |
| 112 | +### Environment Configuration |
| 113 | + |
| 114 | +Create `.env` file for custom backend: |
| 115 | + |
| 116 | +``` |
| 117 | +REACT_APP_BACKEND=http://your-cluster:8765 # Single cluster mode |
| 118 | +``` |
| 119 | + |
| 120 | +### Before Committing |
| 121 | + |
| 122 | +- The project uses Husky pre-commit hooks that automatically run linting |
| 123 | +- Commit messages must follow conventional commit format |
| 124 | +- Always run `npm run lint` and `npm run typecheck` to catch issues early |
| 125 | + |
| 126 | +### UI Framework |
| 127 | + |
| 128 | +The project uses Gravity UI (@gravity-ui/uikit) as the primary component library. When adding new UI components, prefer using Gravity UI components over custom implementations. |
| 129 | + |
| 130 | +### Testing Patterns |
| 131 | + |
| 132 | +- Unit tests are colocated with source files in `__test__` directories |
| 133 | +- E2E tests use Playwright with page objects pattern in `tests/` directory |
| 134 | +- When writing tests, follow existing patterns in the codebase |
| 135 | +- E2E tests use CSS class selectors for element selection |
| 136 | +- Test artifacts are stored in `./playwright-artifacts/` directory |
| 137 | +- Environment variables for E2E tests: |
| 138 | + - `PLAYWRIGHT_BASE_URL` - Override test URL |
| 139 | + - `PLAYWRIGHT_APP_BACKEND` - Specify backend for tests |
| 140 | + |
| 141 | +### Routing |
| 142 | + |
| 143 | +- Uses React Router v5 (not v6) |
| 144 | +- Route definitions in `src/routes.ts` |
| 145 | +- Supports both single-cluster and multi-cluster modes |
| 146 | + |
| 147 | +## Critical Implementation Patterns |
| 148 | + |
| 149 | +### API Calls |
| 150 | + |
| 151 | +All API calls go through `window.api` global object with domain-specific modules (viewer, schema, storage, etc.) |
| 152 | + |
| 153 | +### Table Implementation |
| 154 | + |
| 155 | +Use `PaginatedTable` component for data grids with virtual scrolling. Tables require columns, fetchData function, and a unique tableName. |
| 156 | + |
| 157 | +### Redux Toolkit Query Pattern |
| 158 | + |
| 159 | +API endpoints are injected using RTK Query's `injectEndpoints` pattern. Queries wrap `window.api` calls and provide hooks with loading states, error handling, and caching. |
| 160 | + |
| 161 | +### Common UI Components |
| 162 | + |
| 163 | +- **Notifications**: Use `createToast` utility for user notifications |
| 164 | +- **Error Display**: Use `ResponseError` component for API errors |
| 165 | +- **Loading States**: Use `Loader` and `TableSkeleton` components |
| 166 | + |
| 167 | +### Class Names Convention |
| 168 | + |
| 169 | +Uses BEM naming convention with `cn()` utility from `utils/cn`. Create a block function with component name and use it for element and modifier classes. |
| 170 | + |
| 171 | +### Type Naming Convention |
| 172 | + |
| 173 | +- API Types: Prefixed with 'T' (e.g., `TTenantInfo`, `TClusterInfo`) |
| 174 | +- Located in `src/types/api/` directory |
| 175 | + |
| 176 | +### Common Utilities |
| 177 | + |
| 178 | +- **Formatters**: `src/utils/dataFormatters/` - `formatBytes()`, `formatDateTime()` |
| 179 | +- **Parsers**: `src/utils/timeParsers/` - Time parsing utilities |
| 180 | +- **Query Utils**: `src/utils/query.ts` - SQL/YQL query helpers |
| 181 | + |
| 182 | +### Internationalization (i18n) |
| 183 | + |
| 184 | +All user-facing text must be internationalized using the i18n system. Follow the naming rules from `i18n-naming-ruleset.md`: |
| 185 | + |
| 186 | +- **Component Structure**: Each component has an `i18n/` folder with `en.json` and `index.ts` |
| 187 | +- **Registration**: Use `registerKeysets()` with a unique component name |
| 188 | +- **Key Format**: Follow `<context>_<content>` pattern (e.g., `action_save`, `field_name`, `alert_error`) |
| 189 | +- **Context Prefixes**: |
| 190 | + - `action_` - buttons, links, menu items |
| 191 | + - `field_` - form fields, table columns |
| 192 | + - `title_` - page/section titles |
| 193 | + - `alert_` - notifications, errors |
| 194 | + - `context_` - descriptions, hints |
| 195 | + - `confirm_` - confirmation dialogs |
| 196 | + - `value_` - status values, options |
| 197 | +- **NEVER** use hardcoded strings in UI components |
| 198 | +- **ALWAYS** create i18n entries for all user-visible text |
| 199 | + |
| 200 | +### Performance Considerations |
| 201 | + |
| 202 | +- Tables use virtual scrolling for large datasets |
| 203 | +- Monaco Editor is lazy loaded |
| 204 | +- Use `React.memo` for expensive renders |
| 205 | +- Batch API requests when possible |
| 206 | + |
| 207 | +### Form Handling Pattern |
| 208 | + |
| 209 | +Always use controlled components with validation. Clear errors on user input and validate before submission. Use Gravity UI form components with proper error states. |
| 210 | + |
| 211 | +### Dialog/Modal Pattern |
| 212 | + |
| 213 | +Complex modals use `@ebay/nice-modal-react` library. Simple dialogs use Gravity UI `Dialog` component with proper loading states. |
| 214 | + |
| 215 | +### Navigation (React Router v5) |
| 216 | + |
| 217 | +Uses React Router v5 hooks (`useHistory`, `useParams`, etc.). Always validate route params exist before using them. |
| 218 | + |
| 219 | +### Critical Rules |
| 220 | + |
| 221 | +- **NEVER** call APIs directly - use `window.api.module.method()` |
| 222 | +- **NEVER** mutate state in RTK Query - return new objects/arrays |
| 223 | +- **NEVER** hardcode user-facing strings - use i18n |
| 224 | +- **ALWAYS** use `cn()` for classNames: `const b = cn('component-name')` |
| 225 | +- **ALWAYS** clear errors on user input |
| 226 | +- **ALWAYS** handle loading states in UI |
| 227 | +- **ALWAYS** validate route params exist before use |
| 228 | +- **ALWAYS** follow i18n naming rules from `i18n-naming-ruleset.md` |
| 229 | + |
| 230 | +### Debugging Tips |
| 231 | + |
| 232 | +- `window.api` - Access API methods in browser console |
| 233 | +- `window.ydbEditor` - Monaco editor instance |
| 234 | +- Enable request tracing with `DEV_ENABLE_TRACING_FOR_ALL_REQUESTS` |
| 235 | + |
| 236 | +## Deployment Configuration |
| 237 | + |
| 238 | +### Production Build |
| 239 | + |
| 240 | +The production build is optimized for embedding in YDB servers: |
| 241 | + |
| 242 | +```bash |
| 243 | +# Standard web deployment |
| 244 | +npm run build |
| 245 | + |
| 246 | +# Embedded deployment (relative paths, no source maps) |
| 247 | +npm run build:embedded |
| 248 | + |
| 249 | +# Multi-cluster embedded deployment |
| 250 | +npm run build:embedded-mc |
| 251 | +``` |
| 252 | + |
| 253 | +Build artifacts are placed in `/build` directory. For embedded deployments, files should be served from `/monitoring` path on YDB cluster hosts. |
| 254 | + |
| 255 | +### Environment Variables |
| 256 | + |
| 257 | +- `REACT_APP_BACKEND` - Backend URL for single-cluster mode |
| 258 | +- `REACT_APP_META_BACKEND` - Meta backend URL for multi-cluster mode |
| 259 | +- `PUBLIC_URL` - Base URL for static assets (use `.` for relative paths) |
| 260 | +- `GENERATE_SOURCEMAP` - Set to `false` for production builds |
| 261 | + |
| 262 | +## Common Issues & Troubleshooting |
| 263 | + |
| 264 | +### Development Issues |
| 265 | + |
| 266 | +1. **Port 3000 already in use**: Kill the process using the port or change the PORT env variable |
| 267 | +2. **Docker connection issues**: Ensure Docker is running and port 8765 is not blocked |
| 268 | +3. **TypeScript errors on build**: Run `npm run typecheck` to identify issues before building |
| 269 | +4. **Lint errors blocking commit**: Run `npm run lint` to fix auto-fixable issues |
| 270 | + |
| 271 | +### API Connection Issues |
| 272 | + |
| 273 | +1. **CORS errors**: Check if backend allows localhost:3000 origin in development |
| 274 | +2. **Authentication failures**: Verify credentials and authentication method |
| 275 | +3. **Network timeouts**: Check backend availability and network configuration |
| 276 | + |
| 277 | +### Performance Issues |
| 278 | + |
| 279 | +1. **Large table rendering**: Tables use virtual scrolling - ensure `PaginatedTable` is used |
| 280 | +2. **Bundle size**: Run `npm run analyze` to identify large dependencies |
| 281 | +3. **Memory leaks**: Check for missing cleanup in useEffect hooks |
| 282 | + |
| 283 | +## Reference Resources |
| 284 | + |
| 285 | +- **YDB Documentation**: https://ydb.tech/en/docs/ |
| 286 | +- **Gravity UI Components**: https://gravity-ui.com/ |
| 287 | +- **Redux Toolkit**: https://redux-toolkit.js.org/ |
| 288 | +- **React Router v5**: https://v5.reactrouter.com/ |
| 289 | +- **Monaco Editor**: https://microsoft.github.io/monaco-editor/ |
| 290 | + |
| 291 | +### Internal Resources |
| 292 | + |
| 293 | +- **Swagger API**: Available at http://localhost:8765/viewer/api/ in development |
| 294 | +- **YDB Monitoring Docs**: https://ydb.tech/en/docs/maintenance/embedded_monitoring/ydb_monitoring |
| 295 | +- **Project Roadmap**: See ROADMAP.md in repository root |
0 commit comments