Introduction
AI coding assistants are now part of modern software development. Developers use them to generate functions, write tests, fix bugs, create database queries, refactor code, build APIs, and even modify deployment configuration. This can save time, but it also introduces a serious problem: AI-generated code can look correct while hiding security issues, broken logic, missing edge cases, unsafe dependencies, or production risks.
The main mistake many developers make is treating AI-generated code as finished code. It is not. AI-generated code should be treated like code written by a junior developer who works very fast but does not fully understand your project, your database, your security rules, your business logic, or your production environment.
This is why every developer needs an AI-generated code review checklist.
According to the 2025 Stack Overflow Developer Survey, more developers distrust the accuracy of AI tools than trust them, which confirms the need for human verification in real development workflows. GitHub’s Octoverse also shows that AI, agents, and typed languages are driving major changes in software development, meaning AI-assisted coding will continue to grow rather than disappear.
In this guide, you will learn how to review AI-generated code before committing, merging, or deploying it. The goal is not to reject AI tools. The goal is to use them safely.
Table of Contents
- Why AI-generated code needs careful review
- The main risks of AI-generated code
- Step 1: Inspect the Git diff
- Step 2: Understand what changed
- Step 3: Review security-sensitive code
- Step 4: Check dependencies and packages
- Step 5: Review database migrations
- Step 6: Run framework-specific checks
- Step 7: Test locally before committing
- Step 8: Review deployment risks
- Step 9: Prepare rollback commands
- Django-specific AI code review checklist
- Python-specific AI code review checklist
- Common mistakes developers make
- Best practices for working with AI coding agents
- Final checklist
- FAQ
- Conclusion
Why AI-Generated Code Needs Careful Review
AI-generated code is useful because it can quickly produce boilerplate, suggest solutions, generate tests, explain errors, and automate repetitive work. However, AI does not truly understand your complete application unless you provide it with enough context.
Even when an AI agent has access to your project folder, it can still:
- Modify unrelated files
- Remove important validation
- Add insecure shortcuts
- Generate code that works locally but fails in production
- Add unnecessary dependencies
- Create broken migrations
- Change authentication logic accidentally
- Expose secrets
- Break SEO metadata
- Damage existing UI behavior
- Ignore performance concerns
- Introduce hidden bugs
The risk becomes higher when the AI is allowed to edit multiple files automatically.
This is especially important for Django, Laravel, Flask, React, Express, Docker, Nginx, and production server configurations. A small generated change in authentication, permissions, migrations, environment variables, or deployment files can create serious problems.
OWASP’s Top 10 for LLM Applications includes risks such as insecure output handling and supply chain vulnerabilities, which are directly relevant when developers copy, execute, or deploy AI-generated output without proper validation.
The Main Risks of AI-Generated Code
1. Code That Works but Is Not Secure
AI can generate code that passes a simple test but fails basic security requirements.
Example:
def user_profile(request, user_id):
user = User.objects.get(id=user_id)
return render(request, "profile.html", {"profile_user": user})
This code works, but it may allow any logged-in user to view another user’s profile if permission checks are missing.
A safer version:
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseForbidden
from django.contrib.auth.models import User
@login_required
def user_profile(request, user_id):
profile_user = get_object_or_404(User, id=user_id)
if request.user != profile_user and not request.user.is_staff:
return HttpResponseForbidden("You do not have permission to view this profile.")
return render(request, "profile.html", {"profile_user": profile_user})
The second version checks authentication and authorization.
2. Code That Ignores Your Business Logic
AI may generate technically valid code that does not match your project rules.
For example, if your website only allows institutional emails, AI may generate a registration form without checking the required domain.
Bad example:
if form.is_valid():
form.save()
Better example:
email = form.cleaned_data.get("email", "").lower()
allowed_domains = ["uae.ac.ma", "etu.uae.ac.ma"]
if not any(email.endswith("@" + domain) for domain in allowed_domains):
form.add_error("email", "Please use your institutional email address.")
else:
form.save()
The code is not only about syntax. It must respect project rules.
3. Code That Adds Risky Dependencies
AI tools sometimes suggest installing packages without explaining why they are needed.
Example:
pip install django-random-auth-helper
Before accepting any dependency, ask:
- Is the package maintained?
- Is it popular enough to trust?
- Does it have recent releases?
- Does it have known vulnerabilities?
- Can I solve the problem without adding it?
- Is the package name suspiciously similar to a known package?
Supply chain risk is a real concern in modern software development. OWASP includes supply chain vulnerabilities as one of the risks in LLM application security.
4. Code That Breaks Production Configuration
AI-generated changes to files like these require special attention:
settings.py
.env
docker-compose.yml
Dockerfile
nginx.conf
gunicorn.conf.py
requirements.txt
package.json
package-lock.json
pyproject.toml
A small mistake can cause:
- 502 Bad Gateway errors
- Static files not loading
- Database connection failures
- Redis connection errors
- HTTPS redirect loops
- Broken media uploads
- Security headers not working
- Debug mode enabled in production
Never deploy AI-generated infrastructure changes without careful review.
Step 1: Inspect the Git Diff Before Anything Else
Before reading the code in your editor, start with Git.
Run:
git status
This shows which files were modified, added, deleted, or renamed.
Example output:
modified: blog/views.py
modified: blog/models.py
modified: templates/blog/article_detail.html
modified: requirements.txt
new file: blog/migrations/0024_add_featured_score.py
Now inspect the actual changes:
git diff
For staged changes:
git diff --staged
For a specific file:
git diff blog/views.py
For a summary:
git diff --stat
For changed file names only:
git diff --name-only
This gives you a quick overview of what the AI changed.
What to Look for in the Git Diff
When reviewing the diff, check for:
- Unexpected file changes
- Deleted logic
- Removed validation
- Added dependencies
- Modified settings
- Changed permissions
- Hardcoded secrets
- Database schema changes
- Large unexplained rewrites
- Formatting-only changes mixed with logic changes
A dangerous AI-generated diff might look harmless at first.
Example:
- if request.user != article.author:
- return HttpResponseForbidden()
+ # Allow access for now
This is a serious authorization bug.
Another example:
- DEBUG = os.getenv("DEBUG", "False") == "True"
+ DEBUG = True
This is dangerous in production.
Step 2: Understand What Changed
After checking the diff, classify the change.
Ask yourself:
- Is this a view change?
- Is this a model change?
- Is this a migration change?
- Is this a template change?
- Is this an API change?
- Is this a deployment change?
- Is this a security change?
- Is this a dependency change?
- Is this a performance-related change?
This classification helps you choose the right review checklist.
Low-Risk Changes
Examples:
- Text changes
- CSS improvements
- Simple template layout updates
- Documentation updates
- Minor UI fixes
Even low-risk changes should be reviewed, but they usually require less testing.
Medium-Risk Changes
Examples:
- New views
- New forms
- Query changes
- Cache changes
- API response changes
- Template logic
- Static file changes
- New utility functions
These require local testing and code review.
High-Risk Changes
Examples:
- Authentication changes
- Authorization changes
- Payment logic
- User data handling
- Admin panel changes
- File upload changes
- Database migrations
- Production settings
- Docker/Nginx changes
- Dependency updates
- Security middleware changes
High-risk changes should never be deployed directly to production without staging tests and rollback planning.
Step 3: Review Security-Sensitive Code
Security review is the most important part of AI-generated code review.
Authentication
Check whether the code correctly verifies who the user is.
In Django, make sure protected views use:
from django.contrib.auth.decorators import login_required
@login_required
def dashboard(request):
return render(request, "dashboard.html")
For class-based views:
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import TemplateView
class DashboardView(LoginRequiredMixin, TemplateView):
template_name = "dashboard.html"
Authorization
Authentication answers: “Who are you?”
Authorization answers: “Are you allowed to do this?”
Example of unsafe code:
article = Article.objects.get(id=article_id)
article.delete()
Better:
from django.shortcuts import get_object_or_404
from django.http import HttpResponseForbidden
article = get_object_or_404(Article, id=article_id)
if article.author != request.user and not request.user.is_staff:
return HttpResponseForbidden("You cannot delete this article.")
article.delete()
AI often remembers authentication but forgets authorization.
User Data Protection
If AI-generated code touches user data, check:
- Can users access only their own data?
- Are private fields hidden?
- Is sensitive data logged?
- Are email addresses exposed?
- Are admin-only fields visible?
- Are database queries filtered by
request.user?
Bad example:
orders = Order.objects.all()
Better:
orders = Order.objects.filter(user=request.user)
File Upload Security
If AI modifies file upload logic, check:
- File size limits
- File type validation
- Safe file names
- Media storage configuration
- Access control
- Virus scanning if needed
- Avoid executing uploaded files
Example validation:
def validate_upload(file):
allowed_content_types = ["image/jpeg", "image/png", "image/webp"]
max_size = 2 * 1024 * 1024
if file.content_type not in allowed_content_types:
raise ValueError("Only JPEG, PNG, and WebP images are allowed.")
if file.size > max_size:
raise ValueError("File size must be less than 2MB.")
Secrets and Environment Variables
Search for secrets before committing:
git diff | grep -i "secret\|password\|token\|api_key\|private"
Also check:
git grep -i "SECRET_KEY"
git grep -i "API_KEY"
git grep -i "password"
git grep -i "token"
Never commit:
SECRET_KEY = "real-production-secret"
DATABASE_PASSWORD = "real-password"
GEMINI_API_KEY = "real-api-key"
Use environment variables:
import os
SECRET_KEY = os.environ.get("SECRET_KEY")
GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
Step 4: Check Dependencies and Packages
AI tools often suggest new dependencies. This is convenient but risky.
Python Dependency Review
If requirements.txt changed, inspect it:
git diff requirements.txt
Check installed packages:
pip list
Check outdated packages:
pip list --outdated
Run a vulnerability scan:
pip install pip-audit
pip-audit
You can also use:
pip install safety
safety check
Node Dependency Review
If the project uses JavaScript packages, inspect:
git diff package.json
git diff package-lock.json
Run:
npm audit
Or:
npm audit fix
Be careful with automatic fixes. They can introduce breaking changes.
Dependency Review Checklist
Before accepting a new package, ask:
- Why is this package needed?
- Is there a built-in alternative?
- Is the package maintained?
- Is the package from a trusted source?
- Does it have many open security issues?
- Does it request unnecessary permissions?
- Is the package name suspicious?
- Does it modify authentication, encryption, or network behavior?
Do not accept dependencies blindly.
Step 5: Review Database Migrations
Database migrations are high-risk because they change your data structure.
In Django, check migration files carefully:
python manage.py makemigrations --check
Show migration plan:
python manage.py showmigrations
Preview SQL:
python manage.py sqlmigrate app_name 0001
For example:
python manage.py sqlmigrate blog 0024
Migration Review Checklist
Check whether the migration:
- Deletes a table
- Deletes a column
- Renames a field
- Changes nullability
- Adds a unique constraint
- Changes default values
- Adds a non-null field without a safe default
- Modifies indexes
- Affects large tables
- Includes data migration logic
Dangerous migration example:
migrations.RemoveField(
model_name="article",
name="slug",
)
This could break URLs and SEO.
Another dangerous example:
migrations.AlterField(
model_name="userprofile",
name="email",
field=models.EmailField(unique=True),
)
If duplicate emails exist, deployment may fail.
Safe Migration Habit
Before production migration:
python manage.py migrate --plan
Backup database:
pg_dump -U your_user -d your_database > backup_before_migration.sql
Then deploy to staging first.
Step 6: Run Framework-Specific Checks
For Django projects, run:
python manage.py check
For production security checks:
python manage.py check --deploy
Run tests:
python manage.py test
Check migrations:
python manage.py makemigrations --check --dry-run
Collect static files:
python manage.py collectstatic --dry-run
If using Docker:
docker compose exec web python manage.py check
docker compose exec web python manage.py check --deploy
docker compose exec web python manage.py test
If using a production compose file:
docker compose --env-file .env.prod -f docker-compose.yml -f docker-compose.prod.yml config
This validates your Docker Compose configuration.
Step 7: Test the Change Locally Before Committing
Never commit AI-generated code before testing it locally.
Basic Local Testing Checklist
Run the development server:
python manage.py runserver
Then test:
- Does the page load?
- Does login still work?
- Does logout still work?
- Does registration still work?
- Are permissions respected?
- Are forms validated correctly?
- Are errors displayed clearly?
- Are uploaded files displayed correctly?
- Are static files loading?
- Are database queries working?
- Are admin pages still accessible?
- Are redirects correct?
- Are SEO meta tags still present?
Test Edge Cases
AI-generated code often handles the happy path but misses edge cases.
Test:
- Empty input
- Very long input
- Invalid email
- Duplicate records
- Unauthorized user
- Anonymous user
- Missing file
- Large file
- Invalid URL
- Deleted object
- Expired token
- Database record not found
Example Django test:
from django.test import TestCase
from django.urls import reverse
from django.contrib.auth.models import User
class DashboardAccessTest(TestCase):
def test_anonymous_user_is_redirected(self):
response = self.client.get(reverse("dashboard"))
self.assertEqual(response.status_code, 302)
def test_logged_in_user_can_access_dashboard(self):
user = User.objects.create_user(
username="testuser",
password="StrongPassword123"
)
self.client.login(username="testuser", password="StrongPassword123")
response = self.client.get(reverse("dashboard"))
self.assertEqual(response.status_code, 200)
Step 8: Review Deployment Risks
AI-generated deployment changes must be reviewed slowly.
Check these files carefully:
Dockerfile
docker-compose.yml
docker-compose.prod.yml
nginx.conf
gunicorn.conf.py
.env.example
settings.py
requirements.txt
entrypoint.sh
Docker Review Checklist
Run:
docker compose config
Build locally:
docker compose build
Start services:
docker compose up
Check logs:
docker compose logs web
docker compose logs nginx
docker compose logs db
docker compose logs redis
Check running containers:
docker compose ps
Nginx Review Checklist
Check whether AI changed:
server_name- SSL certificate paths
- Static file aliases
- Media file aliases
- Proxy headers
- Upstream service name
- Redirect rules
- HTTP to HTTPS redirects
- Client upload size
- Security headers
Example safe proxy configuration:
location / {
proxy_pass http://web:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
A wrong upstream name can break the site with a 502 error.
Step 9: Prepare Rollback Commands
Before deploying AI-generated changes, prepare rollback commands.
Git Rollback
View commits:
git log --oneline
Revert a commit safely:
git revert <commit_hash>
Reset local changes before commit:
git restore .
Unstage files:
git restore --staged .
Restore one file:
git restore path/to/file.py
Docker Rollback
If your previous image is available:
docker compose down
docker compose up -d
If you use tagged images:
docker pull your-image:previous
docker compose up -d
Check logs:
docker compose logs -f web
Database Rollback
Database rollback is more sensitive.
Before migration:
pg_dump -U your_user -d your_database > backup_before_ai_change.sql
Restore if needed:
psql -U your_user -d your_database < backup_before_ai_change.sql
For Django migration rollback:
python manage.py migrate app_name previous_migration_name
Example:
python manage.py migrate blog 0023
Only rollback migrations if you understand the data impact.
Django-Specific AI Code Review Checklist
For a Django project, use this checklist before committing AI-generated code.
Commands to Run
python manage.py check
python manage.py check --deploy
python manage.py makemigrations --check --dry-run
python manage.py showmigrations
python manage.py test
If using Docker:
docker compose exec web python manage.py check
docker compose exec web python manage.py check --deploy
docker compose exec web python manage.py test
Django Settings Checklist
Review:
DEBUG
ALLOWED_HOSTS
CSRF_TRUSTED_ORIGINS
SECURE_SSL_REDIRECT
SESSION_COOKIE_SECURE
CSRF_COOKIE_SECURE
SECURE_HSTS_SECONDS
STATIC_URL
STATIC_ROOT
MEDIA_URL
MEDIA_ROOT
DATABASES
CACHES
EMAIL_BACKEND
Dangerous change:
ALLOWED_HOSTS = ["*"]
Better:
ALLOWED_HOSTS = ["mofidtech.fr", "www.mofidtech.fr"]
Dangerous:
DEBUG = True
Better:
DEBUG = os.getenv("DEBUG", "False") == "True"
Django Views Checklist
Check:
- Does the view require login?
- Does it check ownership?
- Does it handle missing objects?
- Does it validate form input?
- Does it use
get_object_or_404? - Does it avoid exposing private data?
- Does it redirect correctly?
- Does it use messages properly?
- Does it avoid duplicate logic?
Django Template Checklist
Check:
- Are variables escaped by default?
- Did AI add
|safeunnecessarily? - Are forms protected with CSRF?
- Are URLs generated with
{% url %}? - Are static files loaded correctly?
- Are images using correct media URLs?
- Are SEO tags preserved?
- Are Open Graph tags preserved?
Dangerous:
{{ user_input|safe }}
Better:
{{ user_input }}
Only use safe for trusted, sanitized content.
Django Model Checklist
Check:
- Did AI change field names?
- Did AI change
blankornullbehavior? - Did AI add
unique=True? - Did AI change
upload_to? - Did AI modify
__str__? - Did AI remove indexes?
- Did AI change slug behavior?
- Did AI affect existing data?
Example slug protection:
from django.utils.text import slugify
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super().save(*args, **kwargs)
Before accepting this, check whether your project already has a custom slug strategy.
Python-Specific AI Code Review Checklist
For Python code, check:
- Type errors
- Unused imports
- Overly broad exceptions
- Hardcoded paths
- Hardcoded credentials
- Inefficient loops
- Missing input validation
- Missing error handling
- Insecure use of
evalorexec - Unsafe file operations
Avoid:
eval(user_input)
Use safer alternatives depending on the use case.
Python Quality Commands
Install and run Ruff:
pip install ruff
ruff check .
Format code:
ruff format .
Type checking with mypy:
pip install mypy
mypy .
Run tests:
pytest
Or:
python -m unittest
Common Mistakes Developers Make With AI-Generated Code
Mistake 1: Accepting the Entire Diff Without Reading It
This is the most dangerous mistake.
AI may change files you did not ask it to change. Always inspect:
git diff --stat
git diff
Mistake 2: Testing Only the Happy Path
AI-generated code often works only when everything is perfect.
Test invalid input, missing records, unauthorized users, and edge cases.
Mistake 3: Ignoring Authentication and Authorization
A page that works is not necessarily safe.
Every protected resource must answer:
- Is the user logged in?
- Is the user allowed to access this object?
Mistake 4: Blindly Installing Dependencies
Every new dependency increases your attack surface.
Check before installing.
Mistake 5: Deploying Without Rollback Plan
Before deployment, know how to return to the previous state.
Prepare:
- Git rollback
- Database backup
- Docker rollback
- Log monitoring
Mistake 6: Letting AI Modify Production Settings
Never let AI casually change production settings.
Review every setting manually.
Best Practices for Working With AI Coding Agents
1. Give the AI a Limited Task
Bad prompt:
Improve my project.
Better prompt:
Update only the article_detail.html template to improve the layout. Do not modify models, views, settings, URLs, migrations, or dependencies.
2. Ask the AI to Explain Every File It Changed
Use this prompt:
List every file you modified. For each file, explain exactly what changed, why it changed, and whether the change affects security, database schema, authentication, deployment, or user data.
3. Ask for a Risk Level
Use this prompt:
Classify this change as Low, Medium, or High risk. Explain the reason. Include possible rollback steps.
4. Ask for Tests
Use:
Generate tests for the changes you made. Include tests for unauthorized users, invalid input, and edge cases.
5. Use Small Commits
Do not allow one AI session to create a giant commit.
Use small commits:
git add blog/views.py
git commit -m "Add permission check to article edit view"
Then continue.
Final AI-Generated Code Review Checklist
Use this before committing or deploying AI-generated code.
Git Checklist
git status
git diff --stat
git diff
git diff --staged
Check:
- Unexpected files
- Deleted code
- Modified settings
- New dependencies
- New migrations
- Secrets
- Permission logic
Security Checklist
Check:
- Authentication
- Authorization
- CSRF protection
- User data access
- File upload validation
- Input validation
- Output escaping
- Secrets
- Admin access
- API permissions
Django Checklist
Run:
python manage.py check
python manage.py check --deploy
python manage.py makemigrations --check --dry-run
python manage.py showmigrations
python manage.py test
Check:
- Views
- Forms
- Models
- Templates
- URLs
- Settings
- Middleware
- Migrations
Dependency Checklist
Run:
pip-audit
npm audit
Check:
- New packages
- Package reputation
- Lock files
- Known vulnerabilities
- Unnecessary dependencies
Deployment Checklist
Check:
- Docker config
- Nginx config
- Environment variables
- Static files
- Media files
- Database migrations
- Redis/cache
- Logs
- SSL/HTTPS
- Rollback plan
Rollback Checklist
Prepare:
git log --oneline
git revert <commit_hash>
Backup database:
pg_dump -U your_user -d your_database > backup_before_deploy.sql
Monitor logs:
docker compose logs -f web
docker compose logs -f nginx
Practical Example: Reviewing an AI-Generated Django Change
Imagine an AI agent modified your Django article system.
Changed files:
blog/models.py
blog/views.py
blog/urls.py
templates/blog/article_detail.html
requirements.txt
blog/migrations/0025_article_reading_time.py
Start with:
git status
git diff --stat
Then inspect each file:
git diff blog/models.py
git diff blog/views.py
git diff requirements.txt
Check migration:
python manage.py sqlmigrate blog 0025
Run Django checks:
python manage.py check
python manage.py makemigrations --check --dry-run
python manage.py test
Check dependencies:
pip-audit
Test manually:
- Open article detail page
- Check article image
- Check SEO title
- Check meta description
- Check Open Graph image
- Check related articles
- Check comments
- Check admin article edit page
Only commit after review:
git add blog/models.py blog/views.py blog/urls.py templates/blog/article_detail.html blog/migrations/0025_article_reading_time.py
git commit -m "Add article reading time with safe review"
FAQ
1. Is AI-generated code safe?
AI-generated code can be useful, but it should not be considered safe automatically. It must be reviewed, tested, and checked for security issues before being committed or deployed.
2. Should I commit AI-generated code directly?
No. You should first inspect the Git diff, run tests, review security-sensitive areas, and verify that the change matches your project requirements.
3. What is the first command I should run after an AI agent modifies my project?
Run:
git status
Then:
git diff --stat
git diff
These commands show what changed.
4. How do I review AI-generated Django code?
Run Django checks, inspect views, forms, models, templates, URLs, settings, and migrations. Pay special attention to authentication, authorization, user data, and production settings.
5. Can AI-generated code introduce security vulnerabilities?
Yes. AI-generated code can introduce broken access control, insecure dependencies, exposed secrets, unsafe file uploads, XSS risks, SQL injection risks, and production misconfigurations.
6. Should I allow AI to modify migrations?
Only with caution. Migrations affect the database and can break production data. Always inspect migration files and run migration plans before deployment.
7. How do I check if AI added a dangerous dependency?
Review requirements.txt, package.json, and lock files. Run tools like pip-audit or npm audit, and verify the package reputation before accepting it.
8. What is the biggest mistake when using AI coding agents?
The biggest mistake is accepting all AI-generated changes without reading the diff. Always review every changed file.
9. Should AI-generated code go through code review?
Yes. AI-generated code should go through the same or stricter review process as human-written code.
10. Can I use AI safely in production projects?
Yes, but only with a disciplined workflow: small changes, Git review, tests, security checks, staging deployment, monitoring, and rollback planning.
Conclusion
AI coding tools are powerful, but they do not remove the developer’s responsibility. They can generate code quickly, but speed is not the same as correctness, security, or production readiness.
A professional developer should treat AI-generated code as a draft. Before committing or deploying it, you should inspect the Git diff, review security-sensitive areas, check dependencies, test locally, validate migrations, and prepare rollback commands.
The best workflow is simple:
Generate → Review → Test → Secure → Commit → Deploy Carefully
AI can help you write code faster, but your review process is what keeps your project safe.
For MofidTech readers, this topic is especially important because many developers now use AI tools with Django, Docker, Nginx, APIs, databases, and production deployments. A strong review checklist can prevent broken websites, security issues, and dangerous production mistakes.
💬 Comments
No comments yet. Be the first to comment!
Login to comment.