add: AGENTS.md
This commit is contained in:
189
AGENTS.md
Normal file
189
AGENTS.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# AGENTS.md - Coding Guidelines for RagusaIT Web
|
||||
|
||||
## Build Commands
|
||||
|
||||
```bash
|
||||
# Development server (port 3000)
|
||||
npm run dev
|
||||
|
||||
# Production build
|
||||
npm run build
|
||||
|
||||
# Preview production build
|
||||
npm run preview
|
||||
```
|
||||
|
||||
## Test Commands
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
npx vitest
|
||||
|
||||
# Run tests in watch mode
|
||||
npx vitest --watch
|
||||
|
||||
# Run tests with coverage
|
||||
npx vitest --coverage
|
||||
|
||||
# Run a single test file
|
||||
npx vitest src/components/ui/__tests__/Button.test.tsx
|
||||
|
||||
# Run tests matching a pattern
|
||||
npx vitest --grep "Button"
|
||||
|
||||
# Run specific test by name
|
||||
npx vitest -t "passes aria-label to the button element"
|
||||
```
|
||||
|
||||
## Code Style Guidelines
|
||||
|
||||
### TypeScript
|
||||
|
||||
- Use **strict TypeScript** configuration
|
||||
- Always define explicit return types for functions
|
||||
- Use `type` for type definitions, `interface` for object shapes that may be extended
|
||||
- Avoid `any` - use `unknown` when type is uncertain
|
||||
|
||||
### Imports (Order)
|
||||
|
||||
1. React imports
|
||||
2. Third-party libraries (alphabetical)
|
||||
3. Absolute imports from project (`@/components`, `@/utils`)
|
||||
4. Relative imports
|
||||
5. CSS/SCSS imports last
|
||||
|
||||
```typescript
|
||||
import { useState, useEffect } from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useTranslation } from '../../i18n';
|
||||
import { debounce } from '../../utils/debounce';
|
||||
import styles from './Navbar.module.css';
|
||||
```
|
||||
|
||||
### Component Structure
|
||||
|
||||
- Use **named exports** for all components
|
||||
- Props interface should be named `[ComponentName]Props`
|
||||
- Place props interface immediately before component
|
||||
- Use CSS Modules for styling (`.module.css`)
|
||||
- Destructure props in function signature with defaults
|
||||
|
||||
```typescript
|
||||
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
variant?: 'primary' | 'secondary' | 'outline';
|
||||
size?: 'sm' | 'md' | 'lg';
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
export function Button({
|
||||
variant = 'primary',
|
||||
size = 'md',
|
||||
isLoading = false,
|
||||
children,
|
||||
...props
|
||||
}: ButtonProps) {
|
||||
// Implementation
|
||||
}
|
||||
```
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
- **Components**: PascalCase (e.g., `Navbar`, `Button`)
|
||||
- **Hooks**: camelCase with `use` prefix (e.g., `useRateLimit`, `useTypingEffect`)
|
||||
- **Utilities**: camelCase (e.g., `debounce`, `formatDate`)
|
||||
- **Types/Interfaces**: PascalCase (e.g., `ButtonProps`, `Translations`)
|
||||
- **Constants**: UPPER_SNAKE_CASE for module-level constants
|
||||
- **Files**: Match default export name (e.g., `Navbar.tsx` exports `Navbar`)
|
||||
|
||||
### Error Handling
|
||||
|
||||
- Use try-catch for async operations
|
||||
- Provide meaningful error messages
|
||||
- Use early returns to avoid nested conditionals
|
||||
- Clean up resources (timers, event listeners) in useEffect cleanup
|
||||
|
||||
```typescript
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
if (!ticking) {
|
||||
window.requestAnimationFrame(() => {
|
||||
setIsScrolled(window.scrollY > 20);
|
||||
ticking = false;
|
||||
});
|
||||
ticking = true;
|
||||
}
|
||||
};
|
||||
window.addEventListener('scroll', handleScroll, { passive: true });
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, []);
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
- Add `// @vitest-environment jsdom` at top of test files
|
||||
- Use `describe` and `it` blocks with descriptive names
|
||||
- Clean up after each test with `cleanup()` from testing-library
|
||||
- Mock external dependencies appropriately
|
||||
- Test behavior, not implementation
|
||||
|
||||
```typescript
|
||||
// @vitest-environment jsdom
|
||||
import { render, screen, cleanup } from '@testing-library/react';
|
||||
import { describe, it, expect, afterEach } from 'vitest';
|
||||
|
||||
describe('Button', () => {
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
});
|
||||
|
||||
it('renders with correct aria-label', () => {
|
||||
render(<Button aria-label="Submit">Click</Button>);
|
||||
expect(screen.getByRole('button', { name: /submit/i })).toBeTruthy();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Performance
|
||||
|
||||
- Use `React.lazy()` for code splitting on routes
|
||||
- Memoize expensive calculations with `useMemo`
|
||||
- Use `requestAnimationFrame` for scroll/resize handlers
|
||||
- Debounce expensive operations (use `debounce` utility)
|
||||
- Add `will-change` CSS sparingly for GPU acceleration
|
||||
|
||||
### Accessibility
|
||||
|
||||
- Always include meaningful `aria-label` for interactive elements
|
||||
- Use semantic HTML elements (`<header>`, `<nav>`, `<main>`)
|
||||
- Ensure keyboard navigation works
|
||||
- Test with screen readers
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── components/
|
||||
│ ├── effects/ # Visual effects (WebGL, animations)
|
||||
│ ├── layout/ # Layout components (Navbar, Footer)
|
||||
│ ├── sections/ # Page sections (Hero, Services)
|
||||
│ └── ui/ # Reusable UI components (Button, Input)
|
||||
├── hooks/ # Custom React hooks
|
||||
├── i18n/ # Internationalization (de.ts, en.ts)
|
||||
├── pages/ # Route components
|
||||
├── styles/ # Global styles
|
||||
└── utils/ # Utility functions
|
||||
```
|
||||
|
||||
### State Management
|
||||
|
||||
- Use React Context for global state (e.g., i18n)
|
||||
- Prefer local state when possible
|
||||
- Use `useRef` for DOM references and mutable values
|
||||
- Store user preferences in localStorage with proper keys
|
||||
|
||||
### Comments
|
||||
|
||||
- Use JSDoc for exported functions
|
||||
- Explain "why" not "what" in comments
|
||||
- Keep comments concise and meaningful
|
||||
Reference in New Issue
Block a user