Skip to content

Commit 95c6127

Browse files
committed
Update cleanup-improve-code-quality.md
1 parent bb76265 commit 95c6127

File tree

1 file changed

+121
-94
lines changed

1 file changed

+121
-94
lines changed

guides/routines/cleanup-improve-code-quality.md

Lines changed: 121 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Overview
44

5-
This document provides a systematic approach to improving code quality through proper organization, naming conventions, and documentation. This routine should be applied to TypeScript/JavaScript files in React, Next.js, and Convex backend projects.
5+
This document provides a systematic step-by-step approach to improving code quality for individual TypeScript/JavaScript files in React, Next.js, and Convex backend projects. Follow these steps in order for each file you're cleaning up.
66

77
## Core Principles
88

@@ -11,19 +11,27 @@ This document provides a systematic approach to improving code quality through p
1111
3. **Clear Boundaries**: Internal vs. external APIs must be obvious
1212
4. **Self-Documenting**: Functions and interfaces must explain their purpose
1313

14-
## Cleanup Steps
14+
## Step-by-Step File Cleanup Process
1515

16-
### 0. Identify Files for Cleanup
16+
### Step 0: Identify Target Files
1717

1818
Target only modified TypeScript/JavaScript files:
1919

2020
```bash
2121
git status --porcelain | grep -E '\.(ts|tsx|js|jsx)$' | awk '{print $2}'
2222
```
2323

24-
### 1. Add Comments to All Functions
24+
**For each file, follow steps 1-6 in order:**
2525

26-
**Every function requires a comment.**
26+
### Step 1: Add Comments to All Functions
27+
28+
**Action**: Add a descriptive comment above every function (exported and internal).
29+
30+
**What to do:**
31+
- Place a comment directly above each function declaration
32+
- Describe what the function does, not how it does it
33+
- Use present tense ("Creates", "Validates", "Displays")
34+
- Note: Internal functions should already have `_` prefix (see Step 2)
2735

2836
```typescript
2937
/**
@@ -35,7 +43,6 @@ export async function createUser(userData: CreateUserRequest): Promise<string> {
3543

3644
/**
3745
* Validates email format using regex pattern.
38-
* Internal helper function for user validation.
3946
*/
4047
function _validateEmail(email: string): boolean {
4148
// Implementation
@@ -49,25 +56,64 @@ export function UserProfile({ userId }: UserProfileProps) {
4956
}
5057
```
5158

52-
### 2. Prefix Internal Functions and Interfaces with Underscore
59+
### Step 2: Prefix Internal Elements with Underscore
5360

54-
**All non-exported elements must be prefixed with `_`.**
61+
**Action**: Add `_` prefix to all non-exported functions, interfaces, types, and constants.
62+
63+
**What to do:**
64+
- Scan through the file for any function, interface, type, or constant that is NOT exported
65+
- Add `_` prefix to the name
66+
- Update all references to use the new prefixed name
5567

5668
```typescript
5769
// Functions
5870
function _validateInput(input: string): boolean { }
5971

60-
// Interfaces and Types
72+
// Interfaces and Types
6173
interface _UserState { }
6274
type _ValidationResult = { };
6375

6476
// Constants
6577
const _DEFAULT_TIMEOUT = 5000;
6678
```
6779

68-
### 3. File Organization Structure
80+
### Step 3: Eliminate All `any` Types
81+
82+
**Action**: Replace every instance of `any` with proper types.
6983

70-
**Organize file contents in this exact order:**
84+
**What to do:**
85+
- Search for all occurrences of `any` in the file
86+
- Replace with specific interfaces, types, or `unknown` with type guards
87+
- Use proper React event types and Convex context types
88+
89+
```typescript
90+
// ❌ Replace this
91+
function processData(data: any): any { }
92+
93+
// ✅ With this
94+
interface DataItem {
95+
id: string;
96+
value: number;
97+
}
98+
function processData(data: DataItem[]): number[] { }
99+
100+
// ✅ Use proper event types
101+
function handleClick(event: React.MouseEvent<HTMLButtonElement>) { }
102+
103+
// ✅ Use proper Convex context types
104+
import { type MutationCtx, type QueryCtx } from './_generated/server';
105+
```
106+
107+
### Step 4: Reorganize File Structure
108+
109+
**Action**: Rearrange the entire file contents in this exact order.
110+
111+
**What to do:**
112+
1. Move all imports to the top (external libraries first, then internal imports)
113+
2. Move all exported interfaces and types to the top (after imports)
114+
3. Move all internal interfaces and types (prefixed with `_`) next
115+
4. Move all exported functions/components next
116+
5. Move all internal helper functions to the bottom
71117

72118
```typescript
73119
// 1. Imports (external first, then internal)
@@ -91,51 +137,15 @@ function _validateUserData(userData: CreateUserRequest): _ValidationResult { }
91137
function _formatDisplayName(firstName: string, lastName: string): string { }
92138
```
93139

94-
### 4. Replace `any` Types with Proper Types
95-
96-
**Eliminate all `any` usage.**
97-
98-
```typescript
99-
// ❌ Never use any
100-
function processData(data: any): any { }
101-
102-
// ✅ Always use specific types
103-
interface DataItem {
104-
id: string;
105-
value: number;
106-
}
107-
function processData(data: DataItem[]): number[] { }
108-
109-
// ✅ Use unknown and type guards for API responses
110-
function handleApiResponse(response: { data: unknown }) {
111-
if (isValidData(response.data)) {
112-
console.log(response.data);
113-
}
114-
}
115-
116-
// ✅ Use specific event types
117-
function handleClick(event: React.MouseEvent<HTMLButtonElement>) { }
118-
119-
// ✅ Use proper Convex context types
120-
import { type MutationCtx, type QueryCtx } from './_generated/server';
121-
122-
export const getUser = async (ctx: QueryCtx, args: { userId: string }) => { };
123-
export const createUser = async (ctx: MutationCtx, args: { name: string }) => { };
124-
```
125-
126-
### 5. Prioritize High-Level Interfaces
127-
128-
**Place most important interfaces at the top in this order:**
129-
1. Main entity interfaces
130-
2. Component props interfaces
131-
3. API request/response interfaces
132-
4. Internal interfaces (prefixed with `_`)
140+
### Step 5: Apply React Performance Optimizations
133141

134-
## React Performance Rules
142+
**Action**: Add `useCallback` and `useMemo` where appropriate.
135143

136-
### Use useCallback and useMemo
137-
138-
**Apply these hooks strategically:**
144+
**What to do:**
145+
- Wrap functions passed as props in `useCallback`
146+
- Wrap functions used as dependencies in other hooks in `useCallback`
147+
- Wrap expensive calculations in `useMemo`
148+
- **Do NOT** wrap primitive values or simple operations
139149

140150
```typescript
141151
// ✅ Use useCallback for functions passed as props
@@ -150,89 +160,106 @@ const analytics = useMemo(() => {
150160
}, {});
151161
}, [users, filter]);
152162

153-
// ❌ Don't memoize primitive values or simple operations
163+
// ❌ Don't memoize these
154164
const displayName = `${user.firstName} ${user.lastName}`; // String - no useMemo
155165
const isAdult = user.age >= 18; // Boolean - no useMemo
156166
const count = users.length; // Number - no useMemo
157-
const isEmpty = !users.length; // Boolean - no useMemo
158167
```
159168

160-
**useCallback Required For:**
161-
- Functions passed as props to child components
162-
- Functions used as dependencies in other hooks
163-
164-
**useMemo Required For:**
165-
- Expensive calculations or data transformations
166-
- Complex filtering, sorting, or data processing
169+
### Step 6: Final Quality Check
167170

168-
**useMemo NOT Required For:**
169-
- Primitive values (boolean, string, number)
170-
- Simple property access or basic arithmetic
171-
- Array.length or basic object property checks
171+
**Action**: Verify the file meets all quality standards.
172172

173-
## Quality Checklist
173+
**Checklist for each file:**
174174

175-
**Before marking a file complete, verify:**
176-
177-
### General
175+
**General Structure:**
178176
- [ ] All functions have descriptive comments
179-
- [ ] Non-exported items prefixed with `_`
180-
- [ ] Public interfaces at top, helpers at bottom
181-
- [ ] File organization follows exact structure
177+
- [ ] All non-exported items are prefixed with `_`
178+
- [ ] File follows the exact organization structure (imports → public types → internal types → exported functions → internal functions)
182179

183-
### TypeScript
184-
- [ ] Zero usage of `any` type
185-
- [ ] Proper React event types
186-
- [ ] Convex functions use `QueryCtx`/`MutationCtx`
187-
- [ ] All parameters and returns explicitly typed
180+
**TypeScript Quality:**
181+
- [ ] Zero usage of `any` type anywhere in the file
182+
- [ ] All React event handlers use proper event types
183+
- [ ] All Convex functions use `QueryCtx`/`MutationCtx` types
184+
- [ ] All function parameters and return types are explicitly typed
188185

189-
### React Performance
190-
- [ ] `useCallback` for props and hook dependencies
191-
- [ ] `useMemo` for expensive operations only
192-
- [ ] No unnecessary memoization of simple values
186+
**React Performance:**
187+
- [ ] Functions passed as props are wrapped in `useCallback`
188+
- [ ] Functions used as hook dependencies are wrapped in `useCallback`
189+
- [ ] Expensive calculations are wrapped in `useMemo`
190+
- [ ] Simple values (strings, booleans, numbers) are NOT memoized
193191

194-
## Example: Before and After
192+
## Complete Example: Before and After
195193

196-
### Before
194+
### Before Cleanup
197195
```typescript
198196
import React from 'react';
199197

200198
function validateEmail(email: string) {
201199
return /\S+@\S+\.\S+/.test(email);
202200
}
203201

204-
export function UserForm({ onSubmit }: UserFormProps) { }
202+
export function UserForm({ onSubmit }: UserFormProps) {
203+
const handleSubmit = (data: any) => {
204+
if (validateEmail(data.email)) {
205+
onSubmit(data);
206+
}
207+
};
208+
return <form onSubmit={handleSubmit}>...</form>;
209+
}
205210

206211
interface UserFormProps {
207212
onSubmit: (data: FormData) => void;
208213
}
209214
```
210215

211-
### After
216+
### After Cleanup (Following All 6 Steps)
212217
```typescript
213-
import React from 'react';
218+
// 1. Imports
219+
import React, { useCallback } from 'react';
214220

215-
/**
216-
* Props for the UserForm component.
217-
*/
221+
// 2. Public interfaces
218222
export interface UserFormProps {
219223
onSubmit: (data: FormData) => void;
220224
}
221225

226+
// 3. Internal types
227+
interface _FormData {
228+
email: string;
229+
name: string;
230+
}
231+
232+
// 4. Exported components
222233
/**
223234
* User registration form with validation and submission handling.
224235
*/
225236
export function UserForm({ onSubmit }: UserFormProps) {
226-
// Implementation using helper functions below
237+
/**
238+
* Handles form submission with email validation.
239+
*/
240+
const handleSubmit = useCallback((data: _FormData) => {
241+
if (_validateEmail(data.email)) {
242+
onSubmit(data);
243+
}
244+
}, [onSubmit]);
245+
246+
return <form onSubmit={handleSubmit}>...</form>;
227247
}
228248

249+
// 5. Internal helper functions
229250
/**
230251
* Validates email format using regex pattern.
231-
* Internal helper function for form validation.
232252
*/
233253
function _validateEmail(email: string): boolean {
234254
return /\S+@\S+\.\S+/.test(email);
235255
}
236256
```
237257

238-
This routine ensures code is maintainable, readable, and follows consistent patterns that make it easier for teams to collaborate and for AI agents to understand and work with the codebase.
258+
## Usage Instructions
259+
260+
1. **Select a file** from your git status that needs cleanup
261+
2. **Work through steps 1-6** in exact order for that file
262+
3. **Complete the checklist** in Step 6 before moving to the next file
263+
4. **Repeat** for each file that needs cleanup
264+
265+
This step-by-step approach ensures consistent, high-quality code that is maintainable and follows team standards.

0 commit comments

Comments
 (0)