Ensuring Quality in AI-Generated Code: Production Standards
Learn how to review, test, and ensure AI-generated code meets production quality standards before deployment
Ensuring Quality in AI-Generated Code
AI can generate code fast, but speed means nothing if the code isn't production-ready. Here's how to ensure AI-generated code meets the same quality standards as human-written code.
The Quality Framework
1. Never Trust Blindly
Treat AI like a junior developer: review everything.
// AI generates this:
function calculateDiscount(price, discountPercent) {
return price - (price * discountPercent / 100);
}
// You review and find issues:
// ā No input validation
// ā No handling for negative values
// ā No type safety
// ā Precision issues with floats
// After review and improvements:
function calculateDiscount(price: number, discountPercent: number): number {
if (typeof price !== 'number' || typeof discountPercent !== 'number') {
throw new TypeError('Price and discount must be numbers');
}
if (price < 0 || discountPercent < 0 || discountPercent > 100) {
throw new RangeError('Invalid price or discount range');
}
// Use Math.round to handle float precision
const discount = Math.round((price * discountPercent) / 100 * 100) / 100;
return Math.round((price - discount) * 100) / 100;
}
2. Test Everything
Write comprehensive tests for AI-generated code.
describe('calculateDiscount', () => {
// Happy path
test('calculates discount correctly', () => {
expect(calculateDiscount(100, 10)).toBe(90);
expect(calculateDiscount(50.50, 20)).toBe(40.40);
});
// Edge cases AI might miss
test('handles zero discount', () => {
expect(calculateDiscount(100, 0)).toBe(100);
});
test('handles 100% discount', () => {
expect(calculateDiscount(100, 100)).toBe(0);
});
// Error cases
test('throws for negative price', () => {
expect(() => calculateDiscount(-100, 10)).toThrow(RangeError);
});
test('throws for invalid discount', () => {
expect(() => calculateDiscount(100, 150)).toThrow(RangeError);
});
test('throws for non-numeric input', () => {
expect(() => calculateDiscount('100' as any, 10)).toThrow(TypeError);
});
// Precision edge cases
test('handles floating point precision', () => {
expect(calculateDiscount(10.01, 10)).toBe(9.01);
});
});
3. Security Review
AI-generated code may have security vulnerabilities.
Common security issues to check:
// ā SQL Injection vulnerability (AI might generate this)
function getUser(userId) {
return db.query(`SELECT * FROM users WHERE id = ${userId}`);
}
// ā
Parameterized query
function getUser(userId: string) {
return db.query('SELECT * FROM users WHERE id = $1', [userId]);
}
// ā XSS vulnerability
function renderComment(comment) {
return `<div>${comment}</div>`;
}
// ā
Sanitized output
import DOMPurify from 'dompurify';
function renderComment(comment: string) {
const clean = DOMPurify.sanitize(comment);
return `<div>${clean}</div>`;
}
// ā Insecure password handling
function saveUser(password) {
return db.users.create({ password });
}
// ā
Hashed password
import bcrypt from 'bcrypt';
async function saveUser(password: string) {
const hashedPassword = await bcrypt.hash(password, 10);
return db.users.create({ password: hashedPassword });
}
4. Performance Review
Check for performance issues.
// ā AI generates O(n²) solution
function findDuplicates(arr) {
const duplicates = [];
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j] && !duplicates.includes(arr[i])) {
duplicates.push(arr[i]);
}
}
}
return duplicates;
}
// ā
O(n) solution with Set
function findDuplicates(arr: number[]): number[] {
const seen = new Set<number>();
const duplicates = new Set<number>();
for (const item of arr) {
if (seen.has(item)) {
duplicates.add(item);
} else {
seen.add(item);
}
}
return Array.from(duplicates);
}
Quality Checklist
For every AI-generated code, verify:
Functionality
- Does it solve the problem correctly?
- Does it handle edge cases?
- Does it handle errors gracefully?
- Are there any logic bugs?
Security
- No SQL injection vulnerabilities
- No XSS vulnerabilities
- No CSRF vulnerabilities
- Proper input validation
- Sensitive data properly handled
- Authentication/authorization correct
Performance
- Efficient algorithms (time complexity)
- Efficient data structures (space complexity)
- No unnecessary loops or calculations
- Proper caching where needed
- Database queries optimized
Code Quality
- Readable and maintainable
- Properly typed (TypeScript)
- Good naming conventions
- Proper error handling
- Documented where needed
- Follows project conventions
Testing
- Unit tests written
- Edge cases covered
- Error cases tested
- Integration tests if needed
- All tests pass
Accessibility
- Semantic HTML
- ARIA labels where needed
- Keyboard navigation
- Screen reader friendly
Code Review Process
Step 1: Initial Review
Ask yourself:
1. Does this make sense?
2. Could I explain how it works?
3. Are there obvious issues?
4. Does it match our style guide?
Step 2: Test the Code
# Run tests
npm test
# Check types
npm run type-check
# Lint
npm run lint
# Format
npm run format
Step 3: Manual Testing
1. Test happy path
2. Test edge cases
3. Test error cases
4. Test on different browsers/devices
5. Test with real data
Step 4: Security Scan
# Check for vulnerabilities
npm audit
# Run security linter
npm run lint:security
# Check dependencies
npm outdated
Step 5: Performance Test
// Add performance marks
performance.mark('start');
expensiveFunction();
performance.mark('end');
performance.measure('expensiveFunction', 'start', 'end');
const measure = performance.getEntriesByName('expensiveFunction')[0];
console.log(`Execution time: ${measure.duration}ms`);
Common AI Code Issues
Issue 1: Missing Error Handling
// ā AI generated
async function fetchUserData(userId) {
const response = await fetch(`/api/users/${userId}`);
return response.json();
}
// ā
After review
async function fetchUserData(userId: string): Promise<User> {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
logger.error('Failed to fetch user data', { userId, error });
throw new UserFetchError('Failed to fetch user data', { cause: error });
}
}
Issue 2: Type Safety
// ā AI uses 'any'
function processData(data: any) {
return data.items.map((item: any) => item.name);
}
// ā
Proper types
interface DataItem {
id: string;
name: string;
}
interface Data {
items: DataItem[];
}
function processData(data: Data): string[] {
return data.items.map(item => item.name);
}
Issue 3: Not Following Project Patterns
// ā AI uses different pattern
function UserCard({ user }) {
return (
<div className="card">
<h2>{user.name}</h2>
</div>
);
}
// ā
Following project's component pattern
import { Card } from '@/components/ui/card';
import { Heading } from '@/components/ui/heading';
interface UserCardProps {
user: User;
}
export function UserCard({ user }: UserCardProps) {
return (
<Card>
<Heading level={2}>{user.name}</Heading>
</Card>
);
}
Improving AI Output
Guide AI to generate better code:
"Generate a user authentication function that:
- Uses TypeScript with strict types
- Includes comprehensive error handling
- Validates all inputs with Zod
- Uses bcrypt for password hashing
- Includes JSDoc comments
- Follows security best practices
- Returns detailed error messages
- Includes rate limiting
- Logs authentication attempts"
Documentation Standards
AI code needs good documentation:
/**
* Calculates the final price after applying a discount
*
* @param price - The original price (must be >= 0)
* @param discountPercent - The discount percentage (0-100)
* @returns The final price after discount, rounded to 2 decimal places
* @throws {TypeError} If inputs are not numbers
* @throws {RangeError} If price is negative or discount is outside 0-100 range
*
* @example
* ```ts
* calculateDiscount(100, 10); // returns 90
* calculateDiscount(50.50, 20); // returns 40.40
* ```
*/
export function calculateDiscount(
price: number,
discountPercent: number
): number {
// Implementation
}
Conclusion
Ensure AI-generated code quality by:
- Review everything - Treat AI as junior developer
- Test comprehensively - Cover happy path, edge cases, errors
- Check security - Scan for common vulnerabilities
- Verify performance - Ensure efficient algorithms
- Follow standards - Match project conventions
- Document properly - Add clear documentation
AI is a powerful tool, but you're responsible for what goes to production. Never skip the review process. Quality matters more than speed.
Build trust in AI-generated code through rigorous review and testing!
Jordan Patel
Web Developer & Technology Enthusiast