# Portfolio Project Development Rules ## Code Style & Formatting ### TypeScript - **Tab indentation** (not spaces), **double quotes**, **semicolons** required - **Explicit function return types** for all functions (except inline expressions) - **Never use `any` type** - always provide proper typing - Prefix **interfaces with `I`** (e.g., `IProps`), **PascalCase** for type aliases - Underscore prefix for unused variables (e.g., `_unusedParam`) - Avoid non-null assertions (`!`) - use proper null checks ### React & JSX - Components return `JSX.Element`, functional components with hooks only - Self-closing tags for components without children: `` - No prop-types (using TypeScript) ### Spacing & Formatting - **Object curly spacing**: `{ foo }`, **no array bracket spacing**: `[1, 2]` - **No trailing commas**, arrow spacing: `() => {}` - Max **1 empty line** between blocks, end files with newline, no trailing spaces ### Imports - Use path alias `@/*` (configured in tsconfig) - Group: external deps first, then internal modules - Import from `@/src/portfolio/...` and `@/src/styles/...` ## Project Structure ### File Organization - **Pages**: `/pages/*.tsx` (pages router, not app router) - **Components**: `/src/portfolio/sections/*.tsx` - **Styles**: `/src/styles/*.scss` with helpers - **Data**: `/src/portfolio/data/`, **Helpers**: `/src/portfolio/helpers/` - **Public**: `/public/` (PDFs, images, icons) ### Component Structure - Section components in `/src/portfolio/sections/`, main page in `/src/portfolio/MainPage.tsx` - Each section has single responsibility ## Styling & Libraries ### SCSS - Import helpers: `@import "helpers";`, use variables: `$accent_colour` - BEM-like naming, `!important` only for library overrides (Splide) ### Animations - **AOS** (scroll), **Anime.js** (complex), **react-transition-group** (transitions) - Respect `prefers-reduced-motion` ### Tech Stack - **Next.js 15** (pages router), **React 18.2**, **TypeScript 5.1**, **SASS** - **@splidejs/react-splide**, **react-icons**, **Sharp** - Dev server on **port 4000**: `npm run dev` ## Development Workflow ### Commands - `npm run dev` - Start dev server (port 4000) - `npm run lintfix` - Auto-fix linting issues - `npm run lint` - Check for issues - `npm run build` - Production build ### Windsurf Commands Helper Script The project includes `windsurf-commands.sh` for common development tasks: ```bash ./windsurf-commands.sh lint # Run ESLint to check for code issues ./windsurf-commands.sh lintfix # Run ESLint with auto-fix enabled ./windsurf-commands.sh help # Show available commands ``` **Usage in AGENTS.md:** - When referencing linting in rules, can use either `npm run lint` or `./windsurf-commands.sh lint` - Script provides consistent interface for development commands - Includes error handling and user-friendly output ### Before Committing 1. Run `npm run lintfix` and `npm run lint` 2. Ensure TypeScript compiles 3. Test changes in browser ## File Naming - **Components**: PascalCase (`MainPage.tsx`) - **Utilities**: camelCase (`helpers.ts`) - **Styles**: kebab-case/camelCase (`main.scss`) ## Common Patterns ```typescript // Component const ComponentName = (): JSX.Element => { return
{/* content */}
; }; export default ComponentName; // Interface interface IComponentProps { title: string; isActive: boolean; } ``` ```scss // SCSS @import "helpers"; .component { color: $accent_colour; } ``` ## Code Complexity Constraints ### Strict Limits (ESLint Enforced) - **Max line length**: 120 characters (ignores URLs, strings, template literals) - **Max file length**: 300 lines (excluding blank lines and comments) - **Max function length**: 50 lines (excluding blank lines and comments) - **Max cyclomatic complexity**: 10 per function - **Max nesting depth**: 4 levels - **Max parameters**: 4 per function - **Max nested callbacks**: 3 levels - **Max statements**: 20 per function ### Refactoring Strategies When files exceed limits, use these approaches: 1. **Split by logical sections**: Break large files into feature folders with main component, sub-components, helpers, types, and index.ts 2. **Extract helper functions**: Move utility functions to separate `helpers.ts` files 3. **Extract types**: Move interfaces/types to separate `types.ts` files 4. **Break down complex functions**: Use sub-functions, early returns, extract conditionals, use lookup objects **Folder structure example:** ``` /src/portfolio/sections/Experience/ Experience.tsx, ExperienceCard.tsx, helpers.ts, types.ts, index.ts ``` **Handling violations:** 1. Analyze what limit was exceeded 2. Choose appropriate strategy 3. Plan folder structure 4. Execute incrementally (create files, move code, update imports, test) 5. Verify with `npm run lint` **Line length fixes:** Break strings, split chains, extract variables, reformat JSX **Parameter count fixes:** Use object parameters, configuration objects, or split function ## QA and Testing ### Pre-Testing Checklist Before running any tests, verify the development server is running: 1. **Check if dev server is running** using `lsof`: ```bash lsof -i :4000 ``` - If output shows a process, server is running - If no output, start the server with `npm run dev` 2. **Verify server accessibility**: ```bash curl -I http://localhost:4000 ``` - Should return HTTP 200 OK - If connection refused, server needs to be started ### Playwright MCP Testing Workflow When testing changes or new features, follow this systematic approach: #### Step 1: Environment Setup 1. Ensure dev server is running on port 4000 2. Install Playwright browsers if needed (use `mcp0_browser_install` if errors occur) 3. Navigate to `http://localhost:4000` #### Step 2: Visual Testing Use Playwright MCP to verify visual elements: 1. **Take accessibility snapshot** (`mcp0_browser_snapshot`): - Captures page structure and content - Better than screenshots for testing - Use this to verify all sections are present 2. **Check key sections are visible**: - Intro section with name/title - Achievements section - Experience section with carousel - Projects section - Skills and Links section - Footer 3. **Verify responsive behavior**: - Test at different viewport sizes using `mcp0_browser_resize` - Common breakpoints: 375px (mobile), 768px (tablet), 1920px (desktop) - Check that content adapts properly #### Step 3: Functional Testing Test interactive elements: 1. **Navigation and scrolling**: - Verify smooth scroll behavior (if `prefers-reduced-motion: no-preference`) - Test anchor links if present - Check scroll-triggered animations (AOS) 2. **Carousel functionality** (Splide): - Click next/previous arrows using `mcp0_browser_click` - Verify slides change correctly - Check pagination dots are clickable - Ensure carousel is responsive 3. **Interactive elements**: - Test any buttons, links, or accordions - Verify hover states work - Check click handlers fire correctly - Test form inputs if present 4. **External links**: - Verify PDF links open correctly (CV, research papers) - Check social media links - Ensure `target="_blank"` and `rel="noopener noreferrer"` where needed #### Step 4: Accessibility Testing 1. **Contrast ratios**: - Use `mcp0_browser_evaluate` to check computed styles - Verify text has sufficient contrast against backgrounds - Check accent color (`$accent_colour`) meets WCAG AA standards (4.5:1 for normal text) 2. **Keyboard navigation**: - Use `mcp0_browser_press_key` to test Tab navigation - Verify focus indicators are visible - Check all interactive elements are keyboard accessible - Test Escape key for modals/overlays 3. **ARIA labels and semantic HTML**: - Check snapshot for proper heading hierarchy (h1, h2, h3) - Verify buttons have accessible names - Check images have alt text - Ensure landmarks are properly labeled 4. **Screen reader compatibility**: - Verify meaningful content order in accessibility snapshot - Check that hidden decorative elements are properly hidden - Ensure dynamic content updates are announced #### Step 5: Performance Checks 1. **Console errors**: - Use `mcp0_browser_console_messages` to check for errors - Verify no React warnings in development - Check for missing image errors - Look for failed network requests 2. **Network requests**: - Use `mcp0_browser_network_requests` to inspect requests - Verify images are optimized (using Next.js Image) - Check for unnecessary requests - Ensure no 404s or failed requests 3. **Animation performance**: - Verify AOS animations trigger smoothly - Check Anime.js animations don't cause jank - Test on reduced motion preference #### Step 6: Cross-Section Integration 1. **Section transitions**: - Scroll through all sections - Verify spacing between sections is consistent - Check that animations don't overlap or conflict 2. **Data consistency**: - Verify project data displays correctly - Check experience timeline is accurate - Ensure skills list is complete and categorized 3. **Asset loading**: - Verify all images load (profile, project screenshots) - Check PDFs are accessible - Ensure icons render correctly (react-icons) ### Testing Checklist Template When testing a new feature or change, use this checklist: - [ ] Dev server running on port 4000 - [ ] Page loads without errors (check console) - [ ] All sections render correctly (accessibility snapshot) - [ ] Responsive at mobile (375px), tablet (768px), desktop (1920px) - [ ] Interactive elements work (carousels, buttons, links) - [ ] Keyboard navigation functional (Tab, Enter, Escape) - [ ] Contrast ratios meet WCAG AA standards - [ ] No console errors or warnings - [ ] Network requests successful (no 404s) - [ ] Animations smooth and respect reduced motion - [ ] External links open correctly - [ ] Images optimized and load properly ### Common Test Scenarios #### Testing a New Section Component ```typescript // 1. Check server is running lsof -i :4000 // 2. Navigate and snapshot mcp0_browser_navigate → http://localhost:4000 mcp0_browser_snapshot // 3. Verify section appears // Look for section in snapshot output // 4. Test responsiveness mcp0_browser_resize → 375x667 (mobile) mcp0_browser_snapshot mcp0_browser_resize → 1920x1080 (desktop) mcp0_browser_snapshot // 5. Check console mcp0_browser_console_messages ``` #### Testing Accessibility ```typescript // 1. Check contrast mcp0_browser_evaluate → function: () => { const el = document.querySelector('.your-element'); const styles = window.getComputedStyle(el); return { color: styles.color, backgroundColor: styles.backgroundColor }; } // 2. Test keyboard navigation mcp0_browser_press_key → Tab mcp0_browser_snapshot → verify focus mcp0_browser_press_key → Enter mcp0_browser_snapshot → verify action // 3. Check ARIA mcp0_browser_snapshot → review for proper labels ``` ### When to Run Tests - **Before committing**: Run basic visual and console checks - **After adding new section**: Full section integration test - **After styling changes**: Visual + contrast + responsive tests - **After adding interactivity**: Functional + keyboard + accessibility tests - **Before production build**: Complete checklist + all scenarios ### Debugging Failed Tests 1. **Visual issues**: Take screenshot with `mcp0_browser_take_screenshot` for detailed inspection 2. **Functional issues**: Use `mcp0_browser_evaluate` to inspect element state 3. **Network issues**: Check `mcp0_browser_network_requests` for failed requests 4. **Console errors**: Review `mcp0_browser_console_messages` for stack traces 5. **Timing issues**: Use `mcp0_browser_wait_for` to wait for elements/animations ## Notes - This is a **portfolio website** showcasing projects, experience, achievements, and skills - Runs on **port 4000** (not default 3000) - Uses **pages router** (not app router) - Strict TypeScript and ESLint configuration for code quality - Tab-based indentation is non-negotiable (project standard) - **Code complexity limits are strictly enforced** - refactor proactively - **Always test changes with Playwright MCP** before committing - **IMPORTANT: Always use Windsurf rules** - they are allowed by default and enable much faster AI development progress