12 KiB
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
anytype - 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:
<Intro/> - 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/*.scsswith 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,
!importantonly 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 issuesnpm run lint- Check for issuesnpm run build- Production build
Windsurf Commands Helper Script
The project includes windsurf-commands.sh for common development tasks:
./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 lintor./windsurf-commands.sh lint - Script provides consistent interface for development commands
- Includes error handling and user-friendly output
Before Committing
- Run
npm run lintfixandnpm run lint - Ensure TypeScript compiles
- Test changes in browser
File Naming
- Components: PascalCase (
MainPage.tsx) - Utilities: camelCase (
helpers.ts) - Styles: kebab-case/camelCase (
main.scss)
Common Patterns
// Component
const ComponentName = (): JSX.Element => {
return <div>{/* content */}</div>;
};
export default ComponentName;
// Interface
interface IComponentProps {
title: string;
isActive: boolean;
}
// 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:
- Split by logical sections: Break large files into feature folders with main component, sub-components, helpers, types, and index.ts
- Extract helper functions: Move utility functions to separate
helpers.tsfiles - Extract types: Move interfaces/types to separate
types.tsfiles - 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:
- Analyze what limit was exceeded
- Choose appropriate strategy
- Plan folder structure
- Execute incrementally (create files, move code, update imports, test)
- 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:
-
Check if dev server is running using
lsof:lsof -i :4000- If output shows a process, server is running
- If no output, start the server with
npm run dev
-
Verify server accessibility:
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
- Ensure dev server is running on port 4000
- Install Playwright browsers if needed (use
mcp0_browser_installif errors occur) - Navigate to
http://localhost:4000
Step 2: Visual Testing
Use Playwright MCP to verify visual elements:
-
Take accessibility snapshot (
mcp0_browser_snapshot):- Captures page structure and content
- Better than screenshots for testing
- Use this to verify all sections are present
-
Check key sections are visible:
- Intro section with name/title
- Achievements section
- Experience section with carousel
- Projects section
- Skills and Links section
- Footer
-
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
- Test at different viewport sizes using
Step 3: Functional Testing
Test interactive elements:
-
Navigation and scrolling:
- Verify smooth scroll behavior (if
prefers-reduced-motion: no-preference) - Test anchor links if present
- Check scroll-triggered animations (AOS)
- Verify smooth scroll behavior (if
-
Carousel functionality (Splide):
- Click next/previous arrows using
mcp0_browser_click - Verify slides change correctly
- Check pagination dots are clickable
- Ensure carousel is responsive
- Click next/previous arrows using
-
Interactive elements:
- Test any buttons, links, or accordions
- Verify hover states work
- Check click handlers fire correctly
- Test form inputs if present
-
External links:
- Verify PDF links open correctly (CV, research papers)
- Check social media links
- Ensure
target="_blank"andrel="noopener noreferrer"where needed
Step 4: Accessibility Testing
-
Contrast ratios:
- Use
mcp0_browser_evaluateto 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)
- Use
-
Keyboard navigation:
- Use
mcp0_browser_press_keyto test Tab navigation - Verify focus indicators are visible
- Check all interactive elements are keyboard accessible
- Test Escape key for modals/overlays
- Use
-
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
-
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
-
Console errors:
- Use
mcp0_browser_console_messagesto check for errors - Verify no React warnings in development
- Check for missing image errors
- Look for failed network requests
- Use
-
Network requests:
- Use
mcp0_browser_network_requeststo inspect requests - Verify images are optimized (using Next.js Image)
- Check for unnecessary requests
- Ensure no 404s or failed requests
- Use
-
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
-
Section transitions:
- Scroll through all sections
- Verify spacing between sections is consistent
- Check that animations don't overlap or conflict
-
Data consistency:
- Verify project data displays correctly
- Check experience timeline is accurate
- Ensure skills list is complete and categorized
-
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
// 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
// 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
- Visual issues: Take screenshot with
mcp0_browser_take_screenshotfor detailed inspection - Functional issues: Use
mcp0_browser_evaluateto inspect element state - Network issues: Check
mcp0_browser_network_requestsfor failed requests - Console errors: Review
mcp0_browser_console_messagesfor stack traces - Timing issues: Use
mcp0_browser_wait_forto 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