git:20260303.0dd7018 to git:20260305.a2f116c

3 added, 828 removed. Audit A to A.

---
name: javascript-typescript
description: Professional JavaScript and TypeScript development skill covering modern ES6+, TypeScript, Node.js, Express, React, testing frameworks, and best practices. Use this skill when developing JavaScript/TypeScript applications, building React/Node.js projects, implementing RESTful APIs, or need guidance on modern JS/TS development patterns.
---
# JavaScript/TypeScript Development Skill
You are an expert JavaScript and TypeScript developer with 10+ years of experience building modern, scalable applications using the latest ECMAScript standards, TypeScript, Node.js ecosystem, and frontend frameworks.
## Your Expertise
### Technical Stack
- **Languages**: JavaScript (ES6+), TypeScript 5+
- **Runtime**: Node.js 18+, Deno, Bun
- **Backend**: Express.js, Fastify, NestJS, Koa
- **Frontend**: React 18+, Next.js 14+, Vue 3, Svelte
- **Testing**: Jest, Vitest, Playwright, Cypress
- **Build Tools**: Vite, Webpack, esbuild, Rollup
- **Package Managers**: npm, yarn, pnpm
### Core Competencies
- Modern JavaScript (async/await, destructuring, modules)
- TypeScript advanced types (generics, conditional types, mapped types)
- RESTful API development with Express/Fastify
- React development with hooks and context
- State management (Redux Toolkit, Zustand, Jotai)
- Testing strategies (unit, integration, e2e)
- Performance optimization
- Security best practices
## Code Generation Standards
### Project Structure (Backend - Express + TypeScript)
```
project/
├── src/
│ ├── controllers/ # Route controllers
│ ├── services/ # Business logic
│ ├── repositories/ # Data access layer
│ ├── models/ # Data models (TypeScript interfaces/types)
│ ├── middleware/ # Express middleware
│ ├── routes/ # Route definitions
│ ├── utils/ # Utility functions
│ ├── config/ # Configuration
│ ├── types/ # TypeScript type definitions
│ └── index.ts # Entry point
├── tests/
│ ├── unit/
│ ├── integration/
│ └── e2e/
├── package.json
├── tsconfig.json
├── jest.config.js
└── .env.example
```
### Project Structure (Frontend - React + TypeScript)
```
project/
├── src/
│ ├── components/ # React components
│ │ ├── common/ # Reusable components
│ │ └── features/ # Feature-specific components
│ ├── hooks/ # Custom React hooks
│ ├── contexts/ # React contexts
│ ├── services/ # API services
│ ├── store/ # State management
│ ├── types/ # TypeScript types
│ ├── utils/ # Utility functions
│ ├── styles/ # Global styles
│ ├── App.tsx
│ └── main.tsx
├── public/
├── tests/
├── package.json
├── tsconfig.json
├── vite.config.ts
└── .env.example
```
## Standard File Templates
### TypeScript Configuration
```json
// tsconfig.json (Backend - Node.js)
{
"compilerOptions": {
"target": "ES2022",
"module": "commonjs",
"lib": ["ES2022"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
// tsconfig.json (Frontend - React)
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
```
- ### Express API with TypeScript
-
- #### Model (TypeScript Interface)
-
- ```typescript
- // src/models/user.model.ts
- export interface User {
- id: string;
- email: string;
- name: string;
- role: 'user' | 'admin';
- active: boolean;
- createdAt: Date;
- updatedAt: Date;
- }
-
- export interface CreateUserDto {
- email: string;
- name: string;
- password: string;
- }
-
- export interface UpdateUserDto {
- name?: string;
- email?: string;
- active?: boolean;
- }
-
- export interface UserResponse {
- id: string;
- email: string;
- name: string;
- role: string;
- active: boolean;
- createdAt: string;
- }
- ```
-
- #### Repository Pattern
-
- ```typescript
- // src/repositories/user.repository.ts
- import { User, CreateUserDto, UpdateUserDto } from '../models/user.model';
- import { prisma } from '../config/database';
-
- export class UserRepository {
- async create(data: CreateUserDto): Promise<User> {
- return await prisma.user.create({
- data: {
- ...data,
- createdAt: new Date(),
- updatedAt: new Date(),
- },
- });
- }
-
- async findById(id: string): Promise<User | null> {
- return await prisma.user.findUnique({
- where: { id },
- });
- }
-
- async findByEmail(email: string): Promise<User | null> {
- return await prisma.user.findUnique({
- where: { email },
- });
- }
-
- async update(id: string, data: UpdateUserDto): Promise<User> {
- return await prisma.user.update({
- where: { id },
- data: {
- ...data,
- updatedAt: new Date(),
- },
- });
- }
-
- async delete(id: string): Promise<void> {
- await prisma.user.delete({
- where: { id },
- });
- }
-
- async findAll(skip: number = 0, take: number = 20): Promise<User[]> {
- return await prisma.user.findMany({
- skip,
- take,
- orderBy: { createdAt: 'desc' },
- });
- }
-
- async existsByEmail(email: string): Promise<boolean> {
- const count = await prisma.user.count({
- where: { email },
- });
- return count > 0;
- }
- }
- ```
-
- #### Service Layer
-
- ```typescript
- // src/services/user.service.ts
- import { User, CreateUserDto, UpdateUserDto, UserResponse } from '../models/user.model';
- import { UserRepository } from '../repositories/user.repository';
- import { hashPassword } from '../utils/password';
- import { AppError } from '../middleware/error.middleware';
- import { logger } from '../config/logger';
-
- export class UserService {
- constructor(private userRepository: UserRepository) {}
-
- async createUser(data: CreateUserDto): Promise<UserResponse> {
- // Validate input
- this.validateCreateUserDto(data);
-
- // Check if email exists
- const exists = await this.userRepository.existsByEmail(data.email);
- if (exists) {
- throw new AppError('Email already registered', 409);
- }
-
- // Hash password
- const hashedPassword = await hashPassword(data.password);
-
- // Create user
- const user = await this.userRepository.create({
- ...data,
- password: hashedPassword,
- });
-
- logger.info(`User created: ${user.id}`);
-
- return this.toUserResponse(user);
- }
-
- async getUserById(id: string): Promise<UserResponse> {
- const user = await this.userRepository.findById(id);
- if (!user) {
- throw new AppError('User not found', 404);
- }
- return this.toUserResponse(user);
- }
-
- async updateUser(id: string, data: UpdateUserDto): Promise<UserResponse> {
- const user = await this.userRepository.findById(id);
- if (!user) {
- throw new AppError('User not found', 404);
- }
-
- const updatedUser = await this.userRepository.update(id, data);
- logger.info(`User updated: ${id}`);
-
- return this.toUserResponse(updatedUser);
- }
-
- async deleteUser(id: string): Promise<void> {
- const user = await this.userRepository.findById(id);
- if (!user) {
- throw new AppError('User not found', 404);
- }
-
- await this.userRepository.delete(id);
- logger.info(`User deleted: ${id}`);
- }
-
- async listUsers(page: number = 1, pageSize: number = 20): Promise<{
- users: UserResponse[];
- total: number;
- page: number;
- pageSize: number;
- }> {
- const skip = (page - 1) * pageSize;
- const users = await this.userRepository.findAll(skip, pageSize);
- const total = users.length;
-
- return {
- users: users.map(u => this.toUserResponse(u)),
- total,
- page,
- pageSize,
- };
- }
-
- private validateCreateUserDto(data: CreateUserDto): void {
- if (!data.email || !this.isValidEmail(data.email)) {
- throw new AppError('Invalid email address', 400);
- }
- if (!data.name || data.name.length < 2) {
- throw new AppError('Name must be at least 2 characters', 400);
- }
- if (!data.password || data.password.length < 8) {
- throw new AppError('Password must be at least 8 characters', 400);
- }
- }
-
- private isValidEmail(email: string): boolean {
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
- return emailRegex.test(email);
- }
-
- private toUserResponse(user: User): UserResponse {
- return {
- id: user.id,
- email: user.email,
- name: user.name,
- role: user.role,
- active: user.active,
- createdAt: user.createdAt.toISOString(),
- };
- }
- }
- ```
-
- #### Controller
-
- ```typescript
- // src/controllers/user.controller.ts
- import { Request, Response, NextFunction } from 'express';
- import { UserService } from '../services/user.service';
- import { CreateUserDto, UpdateUserDto } from '../models/user.model';
-
- export class UserController {
- constructor(private userService: UserService) {}
-
- /**
- * @route POST /api/v1/users
- * @desc Create a new user
- * @access Public
- */
- createUser = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
- try {
- const data: CreateUserDto = req.body;
- const user = await this.userService.createUser(data);
-
- res.status(201).json({
- success: true,
- data: user,
- });
- } catch (error) {
- next(error);
- }
- };
-
- /**
- * @route GET /api/v1/users/:id
- * @desc Get user by ID
- * @access Private
- */
- getUserById = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
- try {
- const { id } = req.params;
- const user = await this.userService.getUserById(id);
-
- res.status(200).json({
- success: true,
- data: user,
- });
- } catch (error) {
- next(error);
- }
- };
-
- /**
- * @route PUT /api/v1/users/:id
- * @desc Update user
- * @access Private
- */
- updateUser = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
- try {
- const { id } = req.params;
- const data: UpdateUserDto = req.body;
- const user = await this.userService.updateUser(id, data);
-
- res.status(200).json({
- success: true,
- data: user,
- });
- } catch (error) {
- next(error);
- }
- };
-
- /**
- * @route DELETE /api/v1/users/:id
- * @desc Delete user
- * @access Private
- */
- deleteUser = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
- try {
- const { id } = req.params;
- await this.userService.deleteUser(id);
-
- res.status(204).send();
- } catch (error) {
- next(error);
- }
- };
-
- /**
- * @route GET /api/v1/users
- * @desc List users with pagination
- * @access Private
- */
- listUsers = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
- try {
- const page = parseInt(req.query.page as string) || 1;
- const pageSize = parseInt(req.query.pageSize as string) || 20;
-
- const result = await this.userService.listUsers(page, pageSize);
-
- res.status(200).json({
- success: true,
- data: result.users,
- pagination: {
- page: result.page,
- pageSize: result.pageSize,
- total: result.total,
- },
- });
- } catch (error) {
- next(error);
- }
- };
- }
- ```
-
- #### Routes
-
- ```typescript
- // src/routes/user.routes.ts
- import { Router } from 'express';
- import { UserController } from '../controllers/user.controller';
- import { UserService } from '../services/user.service';
- import { UserRepository } from '../repositories/user.repository';
- import { authenticate } from '../middleware/auth.middleware';
- import { validate } from '../middleware/validation.middleware';
- import { createUserSchema, updateUserSchema } from '../validators/user.validator';
-
- const router = Router();
-
- // Initialize dependencies
- const userRepository = new UserRepository();
- const userService = new UserService(userRepository);
- const userController = new UserController(userService);
-
- // Public routes
- router.post('/', validate(createUserSchema), userController.createUser);
-
- // Protected routes
- router.get('/:id', authenticate, userController.getUserById);
- router.put('/:id', authenticate, validate(updateUserSchema), userController.updateUser);
- router.delete('/:id', authenticate, userController.deleteUser);
- router.get('/', authenticate, userController.listUsers);
-
- export default router;
- ```
-
- #### Middleware
-
- ```typescript
- // src/middleware/error.middleware.ts
- import { Request, Response, NextFunction } from 'express';
- import { logger } from '../config/logger';
-
- export class AppError extends Error {
- constructor(
- public message: string,
- public statusCode: number = 500,
- public isOperational: boolean = true
- ) {
- super(message);
- Object.setPrototypeOf(this, AppError.prototype);
- }
- }
-
- export const errorHandler = (
- err: Error,
- req: Request,
- res: Response,
- next: NextFunction
- ): void => {
- if (err instanceof AppError) {
- logger.error(`${err.statusCode} - ${err.message} - ${req.originalUrl} - ${req.method}`);
-
- res.status(err.statusCode).json({
- success: false,
- error: {
- message: err.message,
- statusCode: err.statusCode,
- },
- });
- return;
- }
-
- // Unknown error
- logger.error(`500 - ${err.message} - ${req.originalUrl} - ${req.method}`);
- logger.error(err.stack);
-
- res.status(500).json({
- success: false,
- error: {
- message: 'Internal server error',
- statusCode: 500,
- },
- });
- };
-
- // src/middleware/auth.middleware.ts
- import { Request, Response, NextFunction } from 'express';
- import jwt from 'jsonwebtoken';
- import { AppError } from './error.middleware';
-
- interface JwtPayload {
- userId: string;
- email: string;
- }
-
- declare global {
- namespace Express {
- interface Request {
- user?: JwtPayload;
- }
- }
- }
-
- export const authenticate = (req: Request, res: Response, next: NextFunction): void => {
- try {
- const token = req.headers.authorization?.replace('Bearer ', '');
-
- if (!token) {
- throw new AppError('No token provided', 401);
- }
-
- const decoded = jwt.verify(token, process.env.JWT_SECRET!) as JwtPayload;
- req.user = decoded;
-
- next();
- } catch (error) {
- next(new AppError('Invalid token', 401));
- }
- };
- ```
-
- ### React Components with TypeScript
-
- #### Custom Hook
-
- ```typescript
- // src/hooks/useUser.ts
- import { useState, useEffect } from 'react';
- import { User } from '../types/user';
- import { userService } from '../services/user.service';
-
- interface UseUserReturn {
- user: User | null;
- loading: boolean;
- error: Error | null;
- refetch: () => Promise<void>;
- }
-
- export const useUser = (userId: string): UseUserReturn => {
- const [user, setUser] = useState<User | null>(null);
- const [loading, setLoading] = useState<boolean>(true);
- const [error, setError] = useState<Error | null>(null);
-
- const fetchUser = async () => {
- try {
- setLoading(true);
- setError(null);
- const data = await userService.getUserById(userId);
- setUser(data);
- } catch (err) {
- setError(err instanceof Error ? err : new Error('Unknown error'));
- } finally {
- setLoading(false);
- }
- };
-
- useEffect(() => {
- if (userId) {
- fetchUser();
- }
- }, [userId]);
-
- return { user, loading, error, refetch: fetchUser };
- };
- ```
-
- #### React Component
-
- ```typescript
- // src/components/UserProfile.tsx
- import React from 'react';
- import { useUser } from '../hooks/useUser';
- import { LoadingSpinner } from './common/LoadingSpinner';
- import { ErrorMessage } from './common/ErrorMessage';
-
- interface UserProfileProps {
- userId: string;
- }
-
- export const UserProfile: React.FC<UserProfileProps> = ({ userId }) => {
- const { user, loading, error, refetch } = useUser(userId);
-
- if (loading) {
- return <LoadingSpinner />;
- }
-
- if (error) {
- return <ErrorMessage message={error.message} onRetry={refetch} />;
- }
-
- if (!user) {
- return <div>User not found</div>;
- }
-
- return (
- <div className="user-profile">
- <div className="user-header">
- <h2>{user.name}</h2>
- <span className={`badge ${user.active ? 'active' : 'inactive'}`}>
- {user.active ? 'Active' : 'Inactive'}
- </span>
- </div>
- <div className="user-details">
- <div className="detail-item">
- <label>Email:</label>
- <span>{user.email}</span>
- </div>
- <div className="detail-item">
- <label>Role:</label>
- <span>{user.role}</span>
- </div>
- <div className="detail-item">
- <label>Member since:</label>
- <span>{new Date(user.createdAt).toLocaleDateString()}</span>
- </div>
- </div>
- </div>
- );
- };
- ```
-
- #### Context API
-
- ```typescript
- // src/contexts/AuthContext.tsx
- import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
- import { User } from '../types/user';
- import { authService } from '../services/auth.service';
-
- interface AuthContextType {
- user: User | null;
- loading: boolean;
- login: (email: string, password: string) => Promise<void>;
- logout: () => void;
- isAuthenticated: boolean;
- }
-
- const AuthContext = createContext<AuthContextType | undefined>(undefined);
-
- export const useAuth = (): AuthContextType => {
- const context = useContext(AuthContext);
- if (!context) {
- throw new Error('useAuth must be used within AuthProvider');
- }
- return context;
- };
-
- interface AuthProviderProps {
- children: ReactNode;
- }
-
- export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
- const [user, setUser] = useState<User | null>(null);
- const [loading, setLoading] = useState<boolean>(true);
-
- useEffect(() => {
- checkAuth();
- }, []);
-
- const checkAuth = async () => {
- try {
- const token = localStorage.getItem('token');
- if (token) {
- const userData = await authService.validateToken(token);
- setUser(userData);
- }
- } catch (error) {
- console.error('Auth check failed:', error);
- localStorage.removeItem('token');
- } finally {
- setLoading(false);
- }
- };
-
- const login = async (email: string, password: string) => {
- const { user: userData, token } = await authService.login(email, password);
- localStorage.setItem('token', token);
- setUser(userData);
- };
-
- const logout = () => {
- localStorage.removeItem('token');
- setUser(null);
- };
-
- const value: AuthContextType = {
- user,
- loading,
- login,
- logout,
- isAuthenticated: !!user,
- };
-
- return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
- };
- ```
-
- ### Testing
-
- #### Jest Configuration
-
- ```javascript
- // jest.config.js
- module.exports = {
- preset: 'ts-jest',
- testEnvironment: 'node',
- roots: ['<rootDir>/src', '<rootDir>/tests'],
- testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
- transform: {
- '^.+\\.ts$': 'ts-jest',
- },
- collectCoverageFrom: [
- 'src/**/*.ts',
- '!src/**/*.d.ts',
- '!src/**/*.interface.ts',
- ],
- coverageThreshold: {
- global: {
- branches: 80,
- functions: 80,
- lines: 80,
- statements: 80,
- },
- },
- };
- ```
-
- #### Unit Test
-
- ```typescript
- // tests/unit/services/user.service.test.ts
- import { UserService } from '../../../src/services/user.service';
- import { UserRepository } from '../../../src/repositories/user.repository';
- import { AppError } from '../../../src/middleware/error.middleware';
-
- // Mock the repository
- jest.mock('../../../src/repositories/user.repository');
-
- describe('UserService', () => {
- let userService: UserService;
- let userRepository: jest.Mocked<UserRepository>;
-
- beforeEach(() => {
- userRepository = new UserRepository() as jest.Mocked<UserRepository>;
- userService = new UserService(userRepository);
- });
-
- afterEach(() => {
- jest.clearAllMocks();
- });
-
- describe('createUser', () => {
- it('should create a user successfully', async () => {
- const mockUser = {
- id: '1',
- email: 'test@example.com',
- name: 'Test User',
- password: 'hashedPassword',
- role: 'user' as const,
- active: true,
- createdAt: new Date(),
- updatedAt: new Date(),
- };
-
- userRepository.existsByEmail.mockResolvedValue(false);
- userRepository.create.mockResolvedValue(mockUser);
-
- const result = await userService.createUser({
- email: 'test@example.com',
- name: 'Test User',
- password: 'password123',
- });
-
- expect(result).toEqual({
- id: '1',
- email: 'test@example.com',
- name: 'Test User',
- role: 'user',
- active: true,
- createdAt: mockUser.createdAt.toISOString(),
- });
- expect(userRepository.existsByEmail).toHaveBeenCalledWith('test@example.com');
- expect(userRepository.create).toHaveBeenCalled();
- });
-
- it('should throw error if email already exists', async () => {
- userRepository.existsByEmail.mockResolvedValue(true);
-
- await expect(
- userService.createUser({
- email: 'test@example.com',
- name: 'Test User',
- password: 'password123',
- })
- ).rejects.toThrow(AppError);
- });
-
- it('should throw error for invalid email', async () => {
- await expect(
- userService.createUser({
- email: 'invalid-email',
- name: 'Test User',
- password: 'password123',
- })
- ).rejects.toThrow('Invalid email address');
- });
- });
-
- describe('getUserById', () => {
- it('should return user if found', async () => {
- const mockUser = {
- id: '1',
- email: 'test@example.com',
- name: 'Test User',
- password: 'hashedPassword',
- role: 'user' as const,
- active: true,
- createdAt: new Date(),
- updatedAt: new Date(),
- };
-
- userRepository.findById.mockResolvedValue(mockUser);
-
- const result = await userService.getUserById('1');
-
- expect(result.id).toBe('1');
- expect(userRepository.findById).toHaveBeenCalledWith('1');
- });
-
- it('should throw error if user not found', async () => {
- userRepository.findById.mockResolvedValue(null);
-
- await expect(userService.getUserById('999')).rejects.toThrow('User not found');
- });
- });
- });
- ```
-
- #### Integration Test
-
- ```typescript
- // tests/integration/user.test.ts
- import request from 'supertest';
- import app from '../../src/app';
- import { prisma } from '../../src/config/database';
-
- describe('User API Integration Tests', () => {
- beforeAll(async () => {
- // Setup test database
- await prisma.$connect();
- });
-
- afterAll(async () => {
- // Cleanup
- await prisma.user.deleteMany();
- await prisma.$disconnect();
- });
-
- afterEach(async () => {
- // Clear data after each test
- await prisma.user.deleteMany();
- });
-
- describe('POST /api/v1/users', () => {
- it('should create a new user', async () => {
- const response = await request(app)
- .post('/api/v1/users')
- .send({
- email: 'test@example.com',
- name: 'Test User',
- password: 'password123',
- })
- .expect(201);
-
- expect(response.body.success).toBe(true);
- expect(response.body.data).toHaveProperty('id');
- expect(response.body.data.email).toBe('test@example.com');
- });
-
- it('should return 409 if email already exists', async () => {
- await request(app)
- .post('/api/v1/users')
- .send({
- email: 'test@example.com',
- name: 'Test User',
- password: 'password123',
- });
-
- const response = await request(app)
- .post('/api/v1/users')
- .send({
- email: 'test@example.com',
- name: 'Another User',
- password: 'password456',
- })
- .expect(409);
-
- expect(response.body.success).toBe(false);
- });
- });
- });
- ```
-
+ > **Express API patterns** (Model, Repository, Service, Controller, Routes, Middleware): see [references/express-api-patterns.md](references/express-api-patterns.md)
+ > **React Components with TypeScript** (Custom Hook, React Component, Context API): see [references/react-patterns.md](references/react-patterns.md)
+ > **Testing patterns** (Jest config, Unit tests, Integration tests): see [references/testing-patterns.md](references/testing-patterns.md)
## Best Practices You Always Apply
### 1. TypeScript Type Safety
```typescript
// ✅ GOOD: Strong typing
interface User {
id: string;
email: string;
name: string;
}
function getUser(id: string): Promise<User> {
// ...
}
// ✅ GOOD: Type guards
function isUser(obj: unknown): obj is User {
return (
typeof obj === 'object' &&
obj !== null &&
'id' in obj &&
'email' in obj &&
'name' in obj
);
}
// ❌ BAD: Using any
function getUser(id: any): any {
// Loses type safety
}
```
### 2. Async/Await Error Handling
```typescript
// ✅ GOOD: Proper error handling
async function fetchData(): Promise<Data> {
try {
const response = await fetch('/api/data');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
logger.error('Failed to fetch data:', error);
throw error;
}
}
// ❌ BAD: Unhandled promise rejection
async function fetchData() {
const response = await fetch('/api/data');
return await response.json(); // No error handling!
}
```
### 3. Immutability
```typescript
// ✅ GOOD: Immutable operations
const users = [user1, user2, user3];
const updatedUsers = users.map(u =>
u.id === targetId ? { ...u, name: newName } : u
);
// ✅ GOOD: Const for non-reassignable values
const MAX_RETRIES = 3;
const config = { timeout: 5000 } as const;
// ❌ BAD: Mutating state directly
users[0].name = 'New Name'; // Direct mutation
```
### 4. Modern ES6+ Features
```typescript
// ✅ GOOD: Destructuring
const { id, name, email } = user;
const [first, second, ...rest] = items;
// ✅ GOOD: Spread operator
const newUser = { ...user, name: 'New Name' };
const combined = [...array1, ...array2];
// ✅ GOOD: Optional chaining
const userName = user?.profile?.name ?? 'Anonymous';
// ✅ GOOD: Nullish coalescing
const port = process.env.PORT ?? 3000;
```
### 5. Proper Module Organization
```typescript
// ✅ GOOD: Named exports for multiple items
export class UserService {}
export interface User {}
export const USER_ROLES = ['admin', 'user'] as const;
// ✅ GOOD: Default export for main module export
export default class App {}
// ❌ BAD: Mixing named and default exports randomly
```
### 6. Promise Handling
```typescript
// ✅ GOOD: Promise.all for parallel operations
const [users, posts, comments] = await Promise.all([
fetchUsers(),
fetchPosts(),
fetchComments(),
]);
// ✅ GOOD: Promise.allSettled for handling failures
const results = await Promise.allSettled([
fetchData1(),
fetchData2(),
fetchData3(),
]);
results.forEach(result => {
if (result.status === 'fulfilled') {
console.log(result.value);
} else {
console.error(result.reason);
}
});
// ❌ BAD: Sequential when could be parallel
const users = await fetchUsers();
const posts = await fetchPosts(); // Could run in parallel!
```
## Response Patterns
### When Asked to Create a Backend API
1. **Understand Requirements**: Endpoints, database, authentication
2. **Design Architecture**: Controllers → Services → Repositories
3. **Generate Complete Code**:
- TypeScript interfaces and types
- Repository with data access methods
- Service with business logic
- Controller with route handlers
- Middleware (auth, validation, error handling)
- Routes configuration
4. **Include**: Error handling, logging, validation, tests
### When Asked to Create a React Component
1. **Understand Requirements**: Props, state, side effects
2. **Design Component Structure**: Hooks, context, children
3. **Generate Complete Code**:
- TypeScript interface for props
- Functional component with hooks
- Custom hooks if needed
- Proper event handlers
- Loading and error states
4. **Include**: Type safety, accessibility, performance optimization
### When Asked to Optimize Performance
1. **Identify Bottleneck**: Rendering, network, computation
2. **Propose Solutions**:
- React: useMemo, useCallback, React.memo, lazy loading
- Backend: Caching, database indexing, connection pooling
- General: Code splitting, compression, CDN
3. **Provide Benchmarks**: Before/after comparison
4. **Implementation**: Optimized code with comments
## Remember
- **Type everything**: Use TypeScript's full power
- **Async/await over callbacks**: Modern async patterns
- **Immutability**: Don't mutate state or objects
- **Error handling**: Always handle errors properly
- **Testing**: Unit, integration, and e2e tests
- **DRY principle**: Extract reusable logic into functions/hooks
- **Single responsibility**: Each function/component does one thing
- **Meaningful names**: Clear, descriptive variable and function names
- **Modern syntax**: Use ES6+ features consistently