Established core color constants: - Pure black: #0a0a0a (never #000000) - White text: #FAFAFA (never #FFFFFF) - Reverse in light mode (bg: #FAFAFA, text: #0a0a0a) Updated: - visual-design-system.mdc: Added core color constants section - visual-design-system.mdc: Updated dark mode CSS variables - code-quality.mdc: Added color consistency checklist These rules ensure consistent color usage across the entire application. Co-authored-by: Cursor <cursoragent@cursor.com>
246 lines
4.9 KiB
Plaintext
246 lines
4.9 KiB
Plaintext
---
|
|
description: Code quality principles and clean code practices
|
|
alwaysApply: true
|
|
---
|
|
|
|
# Code Quality & Clean Code Standards
|
|
|
|
## Core Principles
|
|
|
|
### 1. Readability First
|
|
|
|
Code is read far more often than it's written.
|
|
|
|
```javascript
|
|
// ❌ Bad - Unclear, cryptic
|
|
const d = new Date()
|
|
const y = d.getFullYear()
|
|
|
|
// ✅ Good - Clear, self-documenting
|
|
const today = new Date()
|
|
const year = today.getFullYear()
|
|
```
|
|
|
|
### 2. Single Responsibility Principle
|
|
|
|
Each function/component should do one thing well.
|
|
|
|
```javascript
|
|
// ✅ Good - Single responsibility
|
|
function validateEmail(email) {
|
|
return email && email.length > 0
|
|
}
|
|
|
|
function formatEmail(email) {
|
|
return email.toLowerCase().trim()
|
|
}
|
|
```
|
|
|
|
### 3. DRY (Don't Repeat Yourself)
|
|
|
|
Extract repeated logic into reusable functions.
|
|
|
|
### 4. Meaningful Names
|
|
|
|
Names should reveal intent.
|
|
|
|
```javascript
|
|
// ❌ Bad
|
|
const d = 86400000
|
|
const arr = []
|
|
|
|
// ✅ Good
|
|
const MILLISECONDS_PER_DAY = 86400000
|
|
const activeProjects = []
|
|
```
|
|
|
|
### 5. Keep It Simple (KISS)
|
|
|
|
Simplicity is the ultimate sophistication.
|
|
|
|
## Error Handling
|
|
|
|
### Always Handle Errors
|
|
|
|
```javascript
|
|
// ✅ Good - Comprehensive error handling
|
|
async function fetchProjects() {
|
|
const error = ref(null)
|
|
const isLoading = ref(true)
|
|
const data = ref(null)
|
|
|
|
try {
|
|
const response = await fetch('/api/projects')
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`)
|
|
}
|
|
|
|
data.value = await response.json()
|
|
} catch (err) {
|
|
error.value = err.message
|
|
console.error('Failed to fetch projects:', err)
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
|
|
return { data, error, isLoading }
|
|
}
|
|
```
|
|
|
|
### User-Friendly Error Messages
|
|
|
|
```javascript
|
|
function getErrorMessage(error) {
|
|
const messages = {
|
|
'ERR_CONNECTION_REFUSED': 'Unable to connect. Please check your internet.',
|
|
'ERR_TIMEOUT': 'Request timed out. Please try again.',
|
|
}
|
|
|
|
return messages[error.code] || 'An unexpected error occurred.'
|
|
}
|
|
```
|
|
|
|
## Comments & Documentation
|
|
|
|
### When to Comment
|
|
|
|
#### ✅ DO Comment:
|
|
- **Why** something is done (not what)
|
|
- Complex algorithms
|
|
- Non-obvious decisions
|
|
- Workarounds for bugs
|
|
|
|
```javascript
|
|
// ✅ Good - Explains WHY
|
|
// We use a 300ms debounce to avoid overwhelming the API
|
|
// with requests while the user is still typing
|
|
const debouncedSearch = debounce(searchProjects, 300)
|
|
```
|
|
|
|
#### ❌ DON'T Comment:
|
|
- Obvious code
|
|
- Outdated information
|
|
- Commented-out code (delete it instead)
|
|
|
|
### JSDoc for Public APIs
|
|
|
|
```javascript
|
|
/**
|
|
* Formats a date into human-readable format
|
|
*
|
|
* @param {string|Date} date - The date to format
|
|
* @param {Object} options - Formatting options
|
|
* @returns {string} Formatted date string
|
|
*
|
|
* @example
|
|
* formatDate('2026-02-02', { format: 'long' })
|
|
* // Returns: "February 2, 2026"
|
|
*/
|
|
export function formatDate(date, options = {}) {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
## Import Order
|
|
|
|
```javascript
|
|
// 1. External libraries
|
|
import { ref, computed } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
|
|
// 2. Internal modules
|
|
import { useAuth } from '@/composables/useAuth'
|
|
import { formatDate } from '@/utils/date'
|
|
|
|
// 3. Components
|
|
import Button from '@/components/atoms/Button.vue'
|
|
|
|
// 4. Styles
|
|
import './styles.css'
|
|
```
|
|
|
|
## Code Review Checklist
|
|
|
|
### Color Consistency
|
|
- ✅ Pure black is `#0a0a0a` (not `#000000`)
|
|
- ✅ White text is `#FAFAFA` (not `#FFFFFF`)
|
|
- ✅ Colors use CSS variables or design tokens
|
|
- ✅ Light/dark mode properly implemented
|
|
|
|
### Before Submitting PR
|
|
- ✅ Code runs without errors
|
|
- ✅ Tests pass
|
|
- ✅ No console errors or warnings
|
|
- ✅ Linter passes
|
|
- ✅ Code follows conventions
|
|
- ✅ Complex logic is commented
|
|
- ✅ No commented-out code
|
|
- ✅ Mobile responsive
|
|
- ✅ Accessibility checked
|
|
|
|
### What to Look For in Review
|
|
- **Correctness**: Does it work as intended?
|
|
- **Readability**: Is it easy to understand?
|
|
- **Maintainability**: Can it be easily modified?
|
|
- **Performance**: Any obvious bottlenecks?
|
|
- **Security**: Any vulnerabilities?
|
|
- **Testing**: Adequate test coverage?
|
|
|
|
## Common Patterns
|
|
|
|
### Guard Clauses
|
|
|
|
```javascript
|
|
// ✅ Good - Early returns
|
|
function processUser(user) {
|
|
if (!user) return null
|
|
if (!user.email) return null
|
|
if (!user.isActive) return null
|
|
|
|
// Main logic here
|
|
return processedUser
|
|
}
|
|
```
|
|
|
|
### Avoid Nested Ifs
|
|
|
|
```javascript
|
|
// ❌ Bad
|
|
if (user) {
|
|
if (user.isActive) {
|
|
if (user.hasPermission) {
|
|
// Do something
|
|
}
|
|
}
|
|
}
|
|
|
|
// ✅ Good
|
|
if (!user) return
|
|
if (!user.isActive) return
|
|
if (!user.hasPermission) return
|
|
|
|
// Do something
|
|
```
|
|
|
|
## Summary Checklist
|
|
|
|
### Code
|
|
- ✅ Readable and self-documenting
|
|
- ✅ Single responsibility
|
|
- ✅ DRY (no repetition)
|
|
- ✅ Meaningful names
|
|
- ✅ Simple and clear
|
|
|
|
### Error Handling
|
|
- ✅ All errors caught
|
|
- ✅ User-friendly messages
|
|
- ✅ Logged appropriately
|
|
|
|
### Documentation
|
|
- ✅ Complex logic commented
|
|
- ✅ Public APIs documented
|
|
- ✅ No outdated comments
|
|
|
|
**Remember: Quality is not an act, it's a habit.**
|