Instruction file imported from nguyenthienthanh/aura-frog-cursor (
.cursor/rules/core/smart-commenting.mdc). Copyright stays with the author.
Smart Commenting - Avoid Redundant Comments
Core Principle: Comments should explain WHY, not WHAT.
What NOT to Comment
1. Self-Explanatory Code
// ❌ BAD
// Set user name to John
const userName = 'John';
// Loop through users
users.forEach(user => {
console.log(user.name);
});
// ✅ GOOD
const userName = 'John';
users.forEach(user => {
console.log(user.name);
});
2. Standard Patterns
// ❌ BAD
// useEffect hook to fetch data on mount
useEffect(() => {
fetchUserData();
}, []);
// ✅ GOOD
useEffect(() => {
fetchUserData();
}, []);
3. Commented-Out Code
// ❌ BAD
const UserProfile = () => {
// const oldLogic = () => {
// return user.name;
// };
return <NewComponent />;
};
// ✅ GOOD
const UserProfile = () => {
return <NewComponent />;
};
// Use git history for old code
4. Meaningless Test/Branch Comments
// ❌ BAD - Obvious from the code itself
// New test
it('should return user', () => {});
// New branch to test edge case
if (user.age < 0) {}
// Test to increase coverage
it('handles empty array', () => {});
// Added new describe block
describe('UserService', () => {});
// ✅ GOOD - No comment needed, code is self-explanatory
it('should return user when ID exists', () => {});
if (user.age < 0) {
throw new ValidationError('Age cannot be negative');
}
describe('UserService', () => {
it('handles empty array by returning default user', () => {});
});
5. JSDoc for Obvious Functions
// ❌ BAD - JSDoc that adds no value
/**
* Gets the user by ID
* @param id - The user ID
* @returns The user
*/
function getUserById(id: string): User {}
/**
* Adds two numbers
* @param a - First number
* @param b - Second number
* @returns Sum of a and b
*/
function add(a: number, b: number): number {}
// ✅ GOOD - Only document when it adds value
function getUserById(id: string): User {}
function add(a: number, b: number): number {}
// ✅ GOOD - JSDoc when there's non-obvious behavior
/**
* Gets user by ID with automatic cache refresh after 5 minutes.
* Returns stale data if API fails (stale-while-revalidate pattern).
*/
function getUserById(id: string): User {}
When TO Comment
1. Complex Business Logic
// ✅ GOOD
// PH region requires additional KYC verification for policies > 1M PHP
// This is a regulatory requirement as per BSP Circular No. 950
if (region === 'PH' && policyAmount > 1_000_000) {
await performEnhancedKYC(user);
}
2. Non-Obvious Workarounds
// ✅ GOOD
// WORKAROUND: React Native Android doesn't support nested Text with onPress
// Issue: https://github.com/facebook/react-native/issues/12345
// TODO: Remove when fixed in RN 0.75+
const TextButton = Platform.OS === 'android'
? TouchableOpacity
: Text;
3. Magic Numbers/Constants
// ✅ GOOD
// API timeout set to 30s for slow 3G connections in rural areas
const API_TIMEOUT = 30000;
// Buffer of 100px to trigger infinite scroll before reaching bottom
// Provides smoother UX on slow devices
const SCROLL_THRESHOLD = 100;
4. Security/Privacy Considerations
// ✅ GOOD
// SECURITY: Never log sensitive data in production
// PII (email, phone, NRIC) must be masked per PDPA requirements
if (__DEV__) {
console.log('User data:', userData);
} else {
console.log('User data:', maskSensitiveData(userData));
}
Comment Quality Checklist
Before adding a comment, ask:
-
❓ Would another developer understand this code without the comment?
- If YES → Don't comment
- If NO → Consider better naming first, then comment
-
❓ Does the comment explain WHY, not WHAT?
- "Why this approach?" ✅
- "What does this line do?" ❌
-
❓ Is this explaining complex business logic?
- Business rules ✅
- Standard code ❌
Good Comment Patterns
Pattern 1: WHY + Context
// Calculate insurance premium with MY region discount
// MY market requires 15% discount for first-time buyers (as per 2024 campaign)
// Other regions: No discount
const premium = region === 'MY' && user.isFirstTime
? basePremium * 0.85
: basePremium;
Pattern 2: Business Rule + Source
// BUSINESS RULE: Users under 18 cannot purchase life insurance
// Source: Insurance Act 1996, Section 45
// Exception: Parent/guardian consent (not implemented yet)
if (user.age < 18) {
throw new Error('Minimum age requirement not met');
}
Pattern 3: Technical Constraint + Issue Link
// WORKAROUND: iOS WKWebView doesn't support localStorage in iframe
// Issue: https://bugs.webkit.org/show_bug.cgi?id=123456
// Using postMessage instead
window.parent.postMessage({ type: 'SAVE', data }, '*');
JSDoc Documentation
When to Use JSDoc
Use JSDoc for:
- Public APIs and exported functions
- Complex function signatures
- Library/SDK code
- Reusable utilities
Function Documentation
/**
* Calculates the insurance premium based on user profile and coverage.
*
* @param user - The user profile containing age, region, and risk factors
* @param coverage - The coverage amount in local currency
* @param options - Optional configuration for premium calculation
* @returns The calculated premium amount
* @throws {ValidationError} If user age is below minimum requirement
*
* @example
* const premium = calculatePremium(
* { age: 30, region: 'MY' },
* 100000,
* { includeRider: true }
* );
*/
function calculatePremium(
user: UserProfile,
coverage: number,
options?: PremiumOptions
): number {
// Implementation
}
Interface/Type Documentation
/**
* Represents a user's insurance policy.
*
* @property id - Unique policy identifier
* @property userId - Reference to the policy owner
* @property type - Type of insurance (life, health, motor)
* @property status - Current policy status
* @property premium - Monthly premium amount
* @property startDate - Policy effective date
* @property endDate - Policy expiration date (optional for lifetime policies)
*/
interface Policy {
id: string;
userId: string;
type: 'life' | 'health' | 'motor';
status: PolicyStatus;
premium: number;
startDate: Date;
endDate?: Date;
}
Component Documentation (React)
/**
* Displays user profile information with edit capabilities.
*
* @component
* @param props - Component props
* @param props.user - User data to display
* @param props.onUpdate - Callback when user updates their profile
* @param props.isEditable - Whether the profile can be edited (default: true)
*
* @example
* <UserProfile
* user={currentUser}
* onUpdate={handleUserUpdate}
* isEditable={hasPermission}
* />
*/
const UserProfile: React.FC<UserProfileProps> = ({
user,
onUpdate,
isEditable = true,
}) => {
// Implementation
};
Hook Documentation
/**
* Custom hook for managing form state with validation.
*
* @template T - The form data type
* @param initialValues - Initial form values
* @param validationSchema - Yup validation schema
* @returns Form state, handlers, and validation status
*
* @example
* const { values, errors, handleChange, handleSubmit } = useForm<LoginForm>(
* { email: '', password: '' },
* loginValidationSchema
* );
*/
function useForm<T extends Record<string, unknown>>(
initialValues: T,
validationSchema?: Schema<T>
): UseFormReturn<T> {
// Implementation
}
Why NOT to Use Dividers
Avoid section dividers like:
// ============================================
// SECTION NAME
// ============================================
// --------------------------------------------
// Subsection
// --------------------------------------------
// --- inline divider ---
Why dividers are bad:
- Code structure should be clear from indentation and whitespace
- Section headers add visual noise without adding information
- If you need sections, consider splitting into separate files
- IDE folding and outline view provide better navigation
Instead of Dividers
Split large files into smaller, focused modules:
// ❌ BAD: One large file with dividers
// user-service.ts (500+ lines with dividers)
// ✅ GOOD: Split into focused modules
// user-service/
// ├── index.ts (exports)
// ├── api.ts (API calls)
// ├── types.ts (interfaces)
// ├── utils.ts (helpers)
// └── constants.ts (config)
Use whitespace to separate logical groups:
// ✅ GOOD: Whitespace provides visual separation
import React from 'react';
import { View, Text } from 'react-native';
import { useAuth } from '@/hooks';
import { formatDate } from '@/utils';
import { UserAvatar } from './UserAvatar';
import { UserBadge } from './UserBadge';
Let code structure speak for itself:
// ✅ GOOD: No dividers needed - structure is clear
interface UserCardProps {
user: User;
onPress?: () => void;
}
const CARD_PADDING = 16;
export const UserCard: React.FC<UserCardProps> = ({ user, onPress }) => {
return (
<Pressable onPress={onPress} style={styles.container}>
<UserAvatar user={user} />
<Text>{user.name}</Text>
</Pressable>
);
};
const styles = StyleSheet.create({
container: { padding: CARD_PADDING },
});
TODO/FIXME Comments
Standard Format
// TODO: Implement caching for better performance
// FIXME: Race condition when multiple users edit simultaneously
// HACK: Workaround for iOS keyboard issue - remove when RN 0.75 released
// NOTE: This algorithm is O(n²) but acceptable for small datasets (<100 items)
// DEPRECATED: Use newMethod() instead - will be removed in v2.0
With Attribution
// TODO(john): Add error boundary for this component
// FIXME(#123): Handle edge case when user has no policies
// HACK(@jane): Temporary fix for Android crash - see PR #456
Code Review Checklist
During code review, check:
- Does it explain WHY, not WHAT?
- Is it necessary? (Try removing it)
- Could better naming eliminate the need?
- Is it up-to-date?
- Does it add value?
- Are JSDoc comments present for public APIs?
- Are complex files organized with dividers?
Summary
| Comment Type | When to Use |
|---|---|
| Inline (WHY) | Business logic, workarounds, constraints |
| JSDoc | Public APIs, complex functions with non-obvious behavior |
| TODO/FIXME | Technical debt, future improvements |
| What to AVOID | Why |
|---|---|
| Dividers | Add noise; split files instead |
| WHAT comments | Code should be self-documenting |
| Commented code | Use git history |
| "New test/branch" | Meaningless - obvious from code |
| Obvious JSDoc | Adds no value, just noise |
References
- Code quality:
code-quality.mdc - KISS principle:
kiss-principle.mdc - Naming conventions:
naming-conventions.mdc
Version: 1.11.0 Last Updated: 2026-02-13