Documentation Index Fetch the complete documentation index at: https://docs.thesozocrm.com/llms.txt
Use this file to discover all available pages before exploring further.
Cursor AI & Clean Code Guide
This guide covers how to effectively use Cursor AI coding assistant while maintaining clean code, good architecture, and team standards.
Using Cursor AI Effectively
When to Use Cursor
✅ Great For
Boilerplate code generation
Refactoring repetitive code
Writing tests
Documentation
Debugging assistance
Code explanations
❌ Not For
Replacing code reviews
Skipping understanding
Blindly accepting suggestions
Complex business logic without review
Security-sensitive code without validation
Cursor Best Practices
Always Review Generated Code
Never blindly accept AI suggestions!
Review every line of generated code
Understand what it does before committing
Test thoroughly before pushing
Ask questions if something is unclear
// ❌ Bad: Accepting AI code without review
// AI generated this, looks good, ship it!
// ✅ Good: Review and understand
// AI suggested this approach. Let me verify:
// 1. Does it handle edge cases?
// 2. Is it consistent with our patterns?
// 3. Are there security concerns?
// 4. Does it need tests?
Be specific about what you want: ❌ Vague: “Fix this bug” ✅ Specific: “Fix the infinite loop in useRegionAggregates hook. The issue is that regionAggregates is in the useEffect dependency array, causing re-renders. Use a stable reference key instead.” ✅ Better: “Refactor this component to use useMemo instead of useState for derived values. The grouped deals should only recalculate when deals or searchTerm change, not on every render.”
Give Cursor the full picture: When asking for help, include:
What you’re trying to accomplish
What’s not working
Relevant code snippets
Error messages
Expected behavior
// ✅ Good prompt:
// "I'm working on the GhostTeamDailyBreakdown component.
// The hourly results aren't showing up. The data exists in Firestore
// (I checked the console), but the UI shows all zeros.
// Here's the component code: [paste code]
// Here's the service method: [paste code]"
Don’t expect perfect code on first try:
First response might be close but not perfect
Ask follow-up questions
Request specific improvements
Refine until it matches our standards
Example conversation:
“Generate a service for ghost hourly results”
“Add error handling with proper logging”
“Make it follow our service pattern from ghostDailyResultsService”
“Add JSDoc comments for all methods”
Use Cursor as a learning tool:
Ask “Why did you suggest this approach?”
Request explanations of complex code
Learn new patterns and techniques
Understand trade-offs
Don’t just copy-paste - understand the reasoning!
Cursor Prompt Templates
Good Prompt Template
Refactoring Prompt
I'm working on [feature/component name].
**Context:**
- [What you're building]
- [Why you're building it]
- [Any constraints or requirements]
**Current Issue:**
- [What's not working]
- [Error messages if any]
- [Expected vs actual behavior]
**Relevant Code:**
[Paste relevant code snippets]
**What I Need:**
- [Specific request]
- [Follow our project patterns]
- [Include error handling]
Clean Code Principles
Code Quality Standards
Code should read like well-written prose: // ❌ Bad: Unclear intent
const d = new Date ();
const f = d . getFullYear ();
const m = d . getMonth () + 1 ;
const r = await fetch ( `/api/data?y= ${ f } &m= ${ m } ` );
// ✅ Good: Clear and self-documenting
const today = new Date ();
const currentYear = today . getFullYear ();
const currentMonth = today . getMonth () + 1 ;
const monthlyData = await fetchMonthlyData ( currentYear , currentMonth );
Rules:
Use descriptive variable names
Avoid abbreviations (unless universally understood)
Extract complex expressions into named variables
Use constants for magic numbers
Each function/component should do ONE thing well: // ❌ Bad: Does too much
async function handleDealSubmit ( formData ) {
// Validate
if ( ! formData . customerName ) return ;
// Format
const formatted = formatDealData ( formData );
// Save
await saveDeal ( formatted );
// Update UI
setDeals ([ ... deals , formatted ]);
// Send email
await sendNotification ( formatted );
// Log
logger . info ( 'Deal saved' );
}
// ✅ Good: Single responsibility
async function handleDealSubmit ( formData ) {
const validated = validateDealForm ( formData );
if ( ! validated . isValid ) {
showValidationErrors ( validated . errors );
return ;
}
const deal = await saveDeal ( formData );
await notifyDealCreated ( deal );
return deal ;
}
3. DRY (Don't Repeat Yourself)
Extract repeated logic into reusable functions: // ❌ Bad: Repeated logic
const formatDeal1 = ( deal ) => {
return {
id: deal . id ,
name: deal . customerName ?. trim () || 'Unknown' ,
amount: deal . amount || 0 ,
date: deal . date || new Date (). toISOString ()
};
};
const formatDeal2 = ( deal ) => {
return {
id: deal . id ,
name: deal . customerName ?. trim () || 'Unknown' ,
amount: deal . amount || 0 ,
date: deal . date || new Date (). toISOString ()
};
};
// ✅ Good: Reusable function
function formatDeal ( deal ) {
return {
id: deal . id ,
name: deal . customerName ?. trim () || 'Unknown' ,
amount: deal . amount || 0 ,
date: deal . date || new Date (). toISOString ()
};
}
4. Explicit Over Implicit
Make intentions clear: // ❌ Bad: Implicit behavior
const dealerFee = selectedDeal ?. dealerFeePercentageNew || "29.16" ;
// What if dealerFeePercentageNew is 0? This breaks!
// ✅ Good: Explicit checks
const dealerFee = selectedDeal ?. dealerFeePercentageNew !== undefined
? selectedDeal . dealerFeePercentageNew
: "29.16" ;
// ✅ Even better: Named constant
const DEFAULT_DEALER_FEE = "29.16" ;
const dealerFee = selectedDeal ?. dealerFeePercentageNew ?? DEFAULT_DEALER_FEE ;
Rules:
Use explicit undefined/null checks
Avoid truthy/falsy checks for numbers (0 is valid!)
Use named constants instead of magic values
Make edge cases obvious
Always handle errors gracefully: // ❌ Bad: Silent failure
try {
await riskyOperation ();
} catch ( error ) {
// User has no idea what happened
}
// ✅ Good: Comprehensive error handling
try {
await riskyOperation ();
toast . success ( 'Operation completed successfully' );
} catch ( error ) {
logger . error ( 'Operation failed:' , error );
const errorMessage = handleError ( error , 'Operation Name' );
toast . error ( `❌ ${ errorMessage } ` );
// Optionally: Report to error tracking
reportError ( error , { context: 'Operation Name' });
}
Rules:
Never swallow errors silently
Always provide user feedback
Log errors for debugging
Handle edge cases explicitly
Code Review Checklist
Before submitting code (AI-generated or not), check:
Architectural Design Principles
Project Structure
src/
├── features/ # Feature-based organization
│ ├── deals/ # Deal management feature
│ │ ├── components/ # Feature-specific components
│ │ ├── hooks/ # Feature-specific hooks
│ │ ├── pages/ # Feature pages
│ │ └── services/ # Feature-specific services
│ └── admin/ # Admin features
├── shared/ # Shared across features
│ ├── components/ # Reusable UI components
│ ├── hooks/ # Shared hooks
│ ├── services/ # Shared business logic
│ └── utils/ # Utility functions
└── core/ # Core app infrastructure
├── auth/ # Authentication
├── layout/ # Layout components
└── routing/ # Route configuration
Design Patterns
Separate business logic from UI: // ✅ Good: Service handles business logic
// services/dealService.js
class DealService {
async createDeal ( dealData ) {
// Validation
const validated = this . validateDeal ( dealData );
if ( ! validated . isValid ) {
throw new ValidationError ( validated . errors );
}
// Business logic
const deal = this . formatDealForStorage ( dealData );
// Data persistence
const docRef = await addDoc ( collection ( db , 'deals' ), deal );
// Return formatted result
return { id: docRef . id , ... deal };
}
}
// Component uses service
const handleSubmit = async ( formData ) => {
try {
const deal = await dealService . createDeal ( formData );
toast . success ( 'Deal created!' );
return deal ;
} catch ( error ) {
toast . error ( handleError ( error , 'Create Deal' ));
}
};
Benefits:
Reusable business logic
Easier to test
Clear separation of concerns
Extract component logic into reusable hooks: // ✅ Good: Logic in custom hook
// hooks/useDeals.js
function useDeals ( filters ) {
const [ deals , setDeals ] = useState ([]);
const [ loading , setLoading ] = useState ( true );
const [ error , setError ] = useState ( null );
useEffect (() => {
async function fetchDeals () {
try {
setLoading ( true );
const data = await dealService . getDeals ( filters );
setDeals ( data );
} catch ( err ) {
setError ( err );
} finally {
setLoading ( false );
}
}
fetchDeals ();
}, [ filters ]);
return { deals , loading , error };
}
// Component is clean
function DealList ({ filters }) {
const { deals , loading , error } = useDeals ( filters );
if ( loading ) return < LoadingSpinner /> ;
if ( error ) return < ErrorMessage error = { error } /> ;
return < DealGrid deals = { deals } /> ;
}
Build complex UIs from simple components: // ✅ Good: Composed components
function DealCard ({ deal }) {
return (
< Card >
< DealHeader deal = { deal } />
< DealDetails deal = { deal } />
< DealActions deal = { deal } />
</ Card >
);
}
function DealHeader ({ deal }) {
return (
< div className = "deal-header" >
< h3 > { deal . customerName } </ h3 >
< StatusBadge status = { deal . status } />
</ div >
);
}
// ❌ Bad: Monolithic component
function DealCard ({ deal }) {
return (
< div className = "deal-card" >
< div className = "deal-header" >
< h3 > { deal . customerName } </ h3 >
< span className = { `status ${ deal . status } ` } > { deal . status } </ span >
</ div >
{ /* 200 more lines... */ }
</ div >
);
}
Make components testable and flexible: // ✅ Good: Dependencies injected
function DealList ({ dealService = defaultDealService }) {
// Can swap dealService for testing
}
// In tests
const mockService = { getDeals: jest . fn () };
render ( < DealList dealService = { mockService } /> );
// ❌ Bad: Hard dependencies
function DealList () {
const deals = await dealService . getDeals (); // Can't test easily
}
File Organization Rules
Feature-Based Group related code together:
Components
Hooks
Services
Tests
All in the same feature folder
Shared Code Only put in shared/ if:
Used by 2+ features
Core infrastructure
Truly reusable
One Component Per File Each component gets its own file:
DealCard.jsx
DealCard.test.jsx
DealCard.styles.css (if needed)
Index Exports Use index files for clean imports: // features/deals/index.js
export { default as DealCard } from './DealCard' ;
export { default as DealList } from './DealList' ;
// Usage
import { DealCard , DealList } from '@/features/deals' ;
Common Anti-Patterns to Avoid
❌ Infinite Loops in useEffect
// ❌ Bad: Infinite loop
const [ data , setData ] = useState ([]);
useEffect (() => {
setData ( processData ( data )); // data changes, triggers effect again!
}, [ data ]);
// ✅ Good: Stable dependencies
const processedData = useMemo (() => {
return processData ( rawData );
}, [ rawData ]);
❌ Mutating State Directly
// ❌ Bad: Direct mutation
deals . push ( newDeal );
setDeals ( deals );
// ✅ Good: Immutable update
setDeals ([ ... deals , newDeal ]);
❌ Missing Dependency Arrays
// ❌ Bad: Missing dependencies
useEffect (() => {
fetchData ( userId ); // userId not in deps!
}, []); // Empty array
// ✅ Good: Complete dependencies
useEffect (() => {
fetchData ( userId );
}, [ userId ]);
// ❌ Bad: Passing props through many levels
< App user = { user } >
< Layout user = { user } >
< Header user = { user } >
< UserMenu user = { user } />
</ Header >
</ Layout >
</ App >
// ✅ Good: Use context or state management
< UserProvider value = { user } >
< App >
< Layout >
< Header >
< UserMenu /> { /* Gets user from context */ }
</ Header >
</ Layout >
</ App >
</ UserProvider >
Cursor + Code Review Workflow
Step-by-Step Process
1. Use Cursor for Initial Code
Ask Cursor to generate code
Review the generated code
Understand what it does
Ask follow-up questions if needed
2. Refine with Cursor
Request specific improvements
Ask for error handling
Request tests
Ensure it follows our patterns
3. Manual Review
Read through the code yourself
Test locally
Check edge cases
Verify error handling
4. Self-Review Checklist
Run through the code review checklist
Fix any issues you find
Remove debug code
Add comments where needed
5. Submit PR
Write clear PR description
Link to Linear issue
Request code review
Be ready to explain your code
Quick Reference
Cursor Prompt Cheat Sheet
Task Prompt Template Generate component ”Create a React component for [name] that [does X]. Follow our project patterns from [similar component].” Refactor code ”Refactor this code to [goal]. Maintain existing functionality but [improvement].” Add error handling ”Add comprehensive error handling to this function. Include user feedback and logging.” Write tests ”Write unit tests for [function/component]. Test happy path, edge cases, and error scenarios.” Fix bug ”Fix [specific bug]. The issue is [description]. Here’s the code: [paste]“ Explain code ”Explain what this code does and why it’s structured this way.”
Code Quality Checklist
Resources
Clean Code Book Robert C. Martin’s classic
React Patterns Common React patterns
Project Docs Check /docs folder for project-specific guides
Remember : Cursor is a powerful tool, but you’re still the developer. Review, understand, and own your code!
Last Updated : November 12, 2025