Code Standards & Conventions
Architecture Overview
TypeScript Standards
Type Definitions
// DO: Use explicit types
interface User {
id: string;
name: string;
email: string;
role: UserRole;
createdAt: Date;
}
// DON'T: Avoid any
const userData: any = fetchUser(); // ❌
// DO: Use proper typing
const userData: User = await fetchUser(); // ✅
Null Handling
// DO: Use optional chaining
const userName = user?.profile?.name;
// DO: Use nullish coalescing
const displayName = userName ?? 'Anonymous';
// DON'T: Use direct null checks
const userDisplay = userName ? userName : 'Anonymous'; // ❌
React Components
Component Structure
// DO: Use functional components with TypeScript
interface Props {
title: string;
onAction: () => void;
children?: React.ReactNode;
}
const MyComponent: React.FC<Props> = ({ title, onAction, children }) => {
return (
<div>
<h1>{title}</h1>
{children}
<button onClick={onAction}>Click Me</button>
</div>
);
};
Hooks Usage
// DO: Use proper dependency arrays
const MyComponent: React.FC = () => {
const [data, setData] = useState<Data[]>([]);
useEffect(() => {
fetchData().then(setData);
}, []); // Empty array for mount-only
useEffect(() => {
processData(data);
}, [data]); // Include all dependencies
};
API Standards
Request/Response Types
// DO: Define clear interface contracts
interface ApiResponse<T> {
data: T;
status: number;
message: string;
timestamp: string;
}
interface ApiError {
code: string;
message: string;
details?: Record<string, unknown>;
}
Error Handling
// DO: Use proper error handling
try {
const response = await api.post<ApiResponse<User>>('/users', userData);
return response.data;
} catch (error) {
if (error instanceof ApiError) {
logger.error('API Error:', error.message);
throw new BusinessError(error.message);
}
throw error;
}
Database Access
Entity Definitions
// DO: Use proper entity decorators
@Entity()
class User {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ length: 100 })
name: string;
@Column({ unique: true })
email: string;
@CreateDateColumn()
createdAt: Date;
}
Testing Standards
Unit Tests
// DO: Write descriptive test cases
describe('UserService', () => {
describe('createUser', () => {
it('should create a new user with valid data', async () => {
const userData = {
name: 'Test User',
email: 'test@example.com'
};
const user = await userService.createUser(userData);
expect(user).toMatchObject(userData);
});
it('should throw error for duplicate email', async () => {
await expect(
userService.createUser(existingUserData)
).rejects.toThrow('Email already exists');
});
});
});
Code Quality Tools
ESLint Configuration
module.exports = {
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended'
],
rules: {
'no-console': 'error',
'@typescript-eslint/explicit-function-return-type': 'error',
'react/prop-types': 'off'
}
};
Prettier Configuration
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"bracketSpacing": true,
"arrowParens": "always"
}
Documentation Standards
Code Comments
/**
* Processes a user transaction
* @param userId - The ID of the user
* @param amount - Transaction amount
* @param type - Type of transaction
* @returns Promise resolving to transaction result
* @throws {InsufficientFundsError} If user has insufficient funds
*/
async function processTransaction(
userId: string,
amount: number,
type: TransactionType
): Promise<TransactionResult> {
// Implementation
}
API Documentation
/**
* @api {post} /api/users Create User
* @apiName CreateUser
* @apiGroup Users
* @apiVersion 1.0.0
*
* @apiParam {String} name User's full name
* @apiParam {String} email User's email address
*
* @apiSuccess {String} id User's unique ID
* @apiSuccess {String} name User's name
* @apiSuccess {String} email User's email
*
* @apiError {Object} error Error object
* @apiError {String} error.message Error message
*/
Security Standards
Input Validation
// DO: Validate all inputs
const schema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(8).required(),
});
const { error, value } = schema.validate(input);
if (error) {
throw new ValidationError(error.message);
}
Authentication
// DO: Use proper authentication middleware
const authenticateUser = async (
req: Request,
res: Response,
next: NextFunction
): Promise<void> => {
try {
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
throw new AuthError('No token provided');
}
const user = await verifyToken(token);
req.user = user;
next();
} catch (error) {
next(new AuthError('Invalid token'));
}
};
Performance Standards
Optimization Guidelines
// DO: Implement caching
const cache = new NodeCache({ stdTTL: 600 });
async function getCachedData(key: string): Promise<Data> {
const cached = cache.get<Data>(key);
if (cached) {
return cached;
}
const data = await fetchData(key);
cache.set(key, data);
return data;
}