Code Standards
General Principles
Section titled “General Principles”Code Quality
Section titled “Code Quality”- Write clean, readable, and maintainable code
- Follow the principle of least surprise
- Keep functions small and focused
- Use meaningful variable and function names
- Comment complex logic, not obvious code
SOLID Principles
Section titled “SOLID Principles”- Single Responsibility Principle
- Open/Closed Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle
Language-Specific Standards
Section titled “Language-Specific Standards”TypeScript/JavaScript
Section titled “TypeScript/JavaScript”Style Guide
Section titled “Style Guide”We follow the Airbnb JavaScript Style Guide with some modifications.
TypeScript Configuration
Section titled “TypeScript Configuration”{ "compilerOptions": { "strict": true, "noImplicitAny": true, "strictNullChecks": true, "noUnusedLocals": true, "noUnusedParameters": true }}Naming Conventions
Section titled “Naming Conventions”// Use PascalCase for classes and typesclass UserService {}interface UserProfile {}type UserId = string;
// Use camelCase for variables, functions, and methodsconst userName = "John";function getUserById(id: string) {}
// Use UPPER_SNAKE_CASE for constantsconst MAX_RETRY_ATTEMPTS = 3;const API_BASE_URL = "https://api.opticworks.com";
// Prefix interfaces with 'I' only when necessary for disambiguationinterface User {} // Preferredinterface IUser {} // Only if needed to distinguish from class
// Use descriptive names// Goodconst activeUsers = users.filter(u => u.isActive);
// Badconst au = users.filter(u => u.isActive);Function Guidelines
Section titled “Function Guidelines”// Prefer arrow functions for callbacksusers.map(user => user.name);
// Use async/await over promisesasync function fetchUser(id: string): Promise<User> { const response = await fetch(`/api/users/${id}`); return response.json();}
// Keep functions focused and small (< 50 lines)function processOrder(order: Order): ProcessedOrder { validateOrder(order); const payment = processPayment(order); const shipment = scheduleShipment(order); return { order, payment, shipment };}Error Handling
Section titled “Error Handling”// Always handle errors explicitlytry { const data = await fetchData(); return processData(data);} catch (error) { logger.error("Failed to process data", error); throw new ProcessingError("Data processing failed", { cause: error });}
// Use custom error classesclass ValidationError extends Error { constructor(message: string, public field: string) { super(message); this.name = "ValidationError"; }}React/Frontend
Section titled “React/Frontend”Component Structure
Section titled “Component Structure”// Functional components with TypeScriptimport React, { useState, useEffect } from 'react';
interface UserCardProps { userId: string; onUserClick?: (userId: string) => void;}
export function UserCard({ userId, onUserClick }: UserCardProps) { const [user, setUser] = useState<User | null>(null);
useEffect(() => { fetchUser(userId).then(setUser); }, [userId]);
if (!user) return <LoadingSpinner />;
return ( <div className="user-card" onClick={() => onUserClick?.(userId)}> <h3>{user.name}</h3> <p>{user.email}</p> </div> );}Hooks Guidelines
Section titled “Hooks Guidelines”// Custom hooks should start with 'use'function useUser(userId: string) { const [user, setUser] = useState<User | null>(null); const [loading, setLoading] = useState(true);
useEffect(() => { fetchUser(userId) .then(setUser) .finally(() => setLoading(false)); }, [userId]);
return { user, loading };}
// Use hooks at the top level only// Never inside conditionals or loopsState Management
Section titled “State Management”// Prefer local state when possibleconst [count, setCount] = useState(0);
// Use context for shared stateconst UserContext = React.createContext<User | null>(null);
// Use Redux/Zustand for complex global stateconst useStore = create((set) => ({ users: [], addUser: (user: User) => set((state) => ({ users: [...state.users, user] })),}));Python
Section titled “Python”Style Guide
Section titled “Style Guide”Follow PEP 8 style guide.
Code Examples
Section titled “Code Examples”# Use type hintsdef get_user(user_id: str) -> Optional[User]: """Fetch user by ID.
Args: user_id: The unique identifier for the user
Returns: User object if found, None otherwise """ return db.query(User).filter(User.id == user_id).first()
# Use descriptive variable namesactive_users = [user for user in users if user.is_active]
# Constants in UPPER_CASEMAX_CONNECTIONS = 100DEFAULT_TIMEOUT = 30
# Class names in PascalCaseclass UserService: def __init__(self, db_connection: Connection): self.db = db_connectionCode Organization
Section titled “Code Organization”Project Structure
Section titled “Project Structure”project/├── src/│ ├── components/ # Reusable UI components│ ├── pages/ # Page components│ ├── services/ # Business logic and API calls│ ├── hooks/ # Custom React hooks│ ├── utils/ # Helper functions│ ├── types/ # TypeScript type definitions│ ├── config/ # Configuration files│ └── constants/ # Application constants├── tests/│ ├── unit/ # Unit tests│ ├── integration/ # Integration tests│ └── e2e/ # End-to-end tests├── public/ # Static assets└── docs/ # DocumentationFile Naming
Section titled “File Naming”# React components: PascalCaseUserProfile.tsxUserProfile.test.tsxUserProfile.module.css
# Utilities and hooks: camelCaseformatDate.tsuseAuth.ts
# Configuration files: kebab-caseeslint-config.jsjest.config.jsDocumentation
Section titled “Documentation”Code Comments
Section titled “Code Comments”// Single-line comments for brief explanationsconst userId = getUserId(); // Extract from token
/* * Multi-line comments for complex logic * explanation or documentation */
/** * JSDoc for functions and classes * * @param userId - The user's unique identifier * @returns The user's profile data * @throws {NotFoundError} If user doesn't exist */async function getUserProfile(userId: string): Promise<UserProfile> { // Implementation}README Files
Section titled “README Files”Every project should include:
- Project description
- Setup instructions
- Environment variables needed
- How to run tests
- Deployment process
- Contributing guidelines
Testing Standards
Section titled “Testing Standards”Test Coverage
Section titled “Test Coverage”- Aim for 80%+ code coverage
- Critical paths must have 100% coverage
- All public APIs must be tested
Test Structure
Section titled “Test Structure”describe('UserService', () => { describe('getUserById', () => { it('should return user when ID exists', async () => { const user = await userService.getUserById('123'); expect(user).toBeDefined(); expect(user.id).toBe('123'); });
it('should throw error when ID does not exist', async () => { await expect( userService.getUserById('invalid') ).rejects.toThrow(NotFoundError); }); });});Testing Best Practices
Section titled “Testing Best Practices”- One assertion per test when possible
- Use descriptive test names
- Follow AAA pattern (Arrange, Act, Assert)
- Mock external dependencies
- Don’t test implementation details
Security Standards
Section titled “Security Standards”Input Validation
Section titled “Input Validation”// Always validate and sanitize user inputfunction createUser(data: unknown): User { const validated = userSchema.parse(data); // Use Zod or similar return db.users.create(validated);}
// Never trust client dataif (!isValidEmail(email)) { throw new ValidationError("Invalid email format");}SQL Injection Prevention
Section titled “SQL Injection Prevention”// Use parameterized queriesconst user = await db.query( 'SELECT * FROM users WHERE id = $1', [userId]);
// Never concatenate user input into SQL// ❌ BADconst user = await db.query(`SELECT * FROM users WHERE id = '${userId}'`);XSS Prevention
Section titled “XSS Prevention”// Sanitize HTML contentimport DOMPurify from 'dompurify';
const cleanHtml = DOMPurify.sanitize(userInput);Authentication & Authorization
Section titled “Authentication & Authorization”// Always verify authenticationfunction requireAuth(req: Request) { if (!req.user) { throw new UnauthorizedError(); }}
// Check permissions before operationsfunction requirePermission(user: User, permission: string) { if (!user.hasPermission(permission)) { throw new ForbiddenError(); }}Performance Standards
Section titled “Performance Standards”Database Queries
Section titled “Database Queries”// Use indexes for frequently queried fields// Load only needed fieldsconst user = await db.users.findOne({ select: ['id', 'name', 'email'], where: { id: userId }});
// Avoid N+1 queriesconst users = await db.users.findMany({ include: { posts: true } // Load related data in one query});Caching
Section titled “Caching”// Cache expensive operationsconst getCachedUser = async (userId: string) => { const cached = await redis.get(`user:${userId}`); if (cached) return JSON.parse(cached);
const user = await db.users.findOne({ id: userId }); await redis.setex(`user:${userId}`, 3600, JSON.stringify(user)); return user;};Frontend Performance
Section titled “Frontend Performance”// Code splittingconst UserDashboard = lazy(() => import('./UserDashboard'));
// Memoizationconst expensiveValue = useMemo(() => computeExpensiveValue(data), [data]);
// Debouncing user inputconst debouncedSearch = useDebouncedCallback( (value) => performSearch(value), 300);Version Control
Section titled “Version Control”Commit Messages
Section titled “Commit Messages”Follow Conventional Commits:
feat: add user profile pagefix: resolve authentication timeout issuedocs: update API documentationrefactor: simplify user service logictest: add tests for payment processingchore: upgrade dependenciesBranch Naming
Section titled “Branch Naming”feature/user-authenticationbugfix/login-timeouthotfix/security-patchrefactor/database-layerCode Review Checklist
Section titled “Code Review Checklist”Before submitting a PR, verify:
- Code follows style guide
- Tests are included and passing
- Documentation is updated
- No console.log or debug code
- Error handling is proper
- Security best practices followed
- Performance considerations addressed
- Code is properly formatted
- No sensitive data committed
Continuous Improvement
Section titled “Continuous Improvement”Refactoring
Section titled “Refactoring”- Regularly refactor to improve code quality
- Use tools like SonarQube for code quality metrics
- Address technical debt in sprint planning
Learning
Section titled “Learning”- Stay updated with language/framework updates
- Share knowledge in tech talks
- Contribute to internal documentation
Resources
Section titled “Resources”- Clean Code by Robert C. Martin
- Airbnb JavaScript Style Guide
- TypeScript Handbook
- React Best Practices
Questions?
Section titled “Questions?”- Ask in #engineering Slack channel
- Review existing code in repositories
- Request code review from senior developers
- Attend weekly architecture meetings