Full-Stack Developer
Delegating a Full Feature to Claude Code β JWT Auth Built in 20 Minutes
Key Takeaway
I told an AI coding agent to build JWT authentication for our Django API β models, views, serializers, middleware, and tests. 20 minutes later: complete working feature, 15 test cases, 94% coverage. Nico reviewed it, flagged 2 minor issues, agent fixed them. Total: 30 minutes.
The Problem
Building features from scratch is slow. Not because writing code is hard β because writing complete code is tedious.
JWT authentication in Django. I've built it before. You've probably built it before. Models for users and tokens. Serializers for registration, login, token refresh. Views. URL routing. Middleware for token validation. Settings configuration. Tests for every endpoint β happy path, expired token, invalid token, missing token, wrong permissions.
It's 4-8 hours of work. Not because it's complex β because it's thorough. The auth logic is maybe 30 minutes. The serializer boilerplate is an hour. The test cases are 2-3 hours. Edge cases, error messages, documentation β another hour.
Every hour of that work follows patterns I already know. I'm not solving problems. I'm typing patterns.
The Solution
Claude Code, orchestrated through Mr.Chief's ACP (Agent Communication Protocol), builds the entire feature from a single task description. Thom delegates the work, Claude Code generates the implementation, Nico reviews it, and the agent fixes any issues. I'm involved for 30 seconds β the time it takes to type the request.
The Process
The request is simple:
View details
Me: @thom build a REST API for user authentication with JWT β
Django, include tests. Project: eskimoai-api.
Thom delegates to Claude Code via ACP:
yamlShow code
# ACP task delegation
task:
type: feature_implementation
project: eskimoai-api
framework: django
description: |
Build complete JWT authentication:
- User model (extend AbstractUser if needed)
- Registration endpoint (email, password, name)
- Login endpoint (returns access + refresh tokens)
- Token refresh endpoint
- Token validation middleware
- User profile endpoint (authenticated)
- Password reset flow
- Comprehensive test suite
constraints:
- Use djangorestframework-simplejwt
- Follow existing project patterns (check existing views/serializers)
- Include docstrings and type hints
- Tests must cover: happy path, auth failures, edge cases
- Minimum 90% coverage for new code
Claude Code reads the existing project structure, understands the patterns, and generates:
Models (accounts/models.py):
pythonShow code
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
"""Extended user model with email as primary identifier."""
email = models.EmailField(unique=True)
name = models.CharField(max_length=255)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name', 'username']
class Meta:
db_table = 'accounts_user'
Serializers (accounts/serializers.py):
pythonShow code
from rest_framework import serializers
from django.contrib.auth import get_user_model
from django.contrib.auth.password_validation import validate_password
User = get_user_model()
class RegisterSerializer(serializers.ModelSerializer):
password = serializers.CharField(
write_only=True, validators=[validate_password]
)
password_confirm = serializers.CharField(write_only=True)
class Meta:
model = User
fields = ['email', 'name', 'password', 'password_confirm']
def validate(self, attrs):
if attrs['password'] != attrs.pop('password_confirm'):
raise serializers.ValidationError(
{"password_confirm": "Passwords don't match."}
)
return attrs
def create(self, validated_data):
return User.objects.create_user(
username=validated_data['email'],
**validated_data
)
Middleware (accounts/middleware.py):
pythonShow code
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.exceptions import InvalidToken, TokenError
from django.http import JsonResponse
class JWTAuthMiddleware:
"""Validate JWT on protected endpoints."""
EXEMPT_PATHS = [
'/api/auth/register/',
'/api/auth/login/',
'/api/auth/token/refresh/',
'/health/',
]
def __init__(self, get_response):
self.get_response = get_response
self.jwt_auth = JWTAuthentication()
def __call__(self, request):
if any(request.path.startswith(p) for p in self.EXEMPT_PATHS):
return self.get_response(request)
try:
auth_result = self.jwt_auth.authenticate(request)
if auth_result:
request.user, request.auth = auth_result
except (InvalidToken, TokenError) as e:
return JsonResponse(
{"error": "Invalid or expired token.", "detail": str(e)},
status=401
)
return self.get_response(request)
Tests (accounts/tests/test_auth.py) β 15 test cases:
pythonShow code
class TestRegistration(APITestCase):
def test_register_success(self): ...
def test_register_duplicate_email(self): ...
def test_register_weak_password(self): ...
def test_register_password_mismatch(self): ...
def test_register_missing_fields(self): ...
class TestLogin(APITestCase):
def test_login_success_returns_tokens(self): ...
def test_login_wrong_password(self): ...
def test_login_nonexistent_user(self): ...
def test_login_inactive_user(self): ...
class TestTokenRefresh(APITestCase):
def test_refresh_valid_token(self): ...
def test_refresh_expired_token(self): ...
def test_refresh_invalid_token(self): ...
class TestProtectedEndpoints(APITestCase):
def test_profile_with_valid_token(self): ...
def test_profile_without_token_returns_401(self): ...
def test_profile_with_expired_token(self): ...
The full output: 8 files, ~450 lines of production code, ~350 lines of tests. Generated in 18 minutes.
Then Nico reviews:
View details
π Code Review: JWT Authentication (Nico)
Overall: β
Good implementation. Clean patterns. 2 minor issues.
Issue 1 (LOW): middleware.py line 28
EXEMPT_PATHS uses startswith() β "/health-check/" would
also be exempted. Use exact match or regex.
Issue 2 (LOW): serializers.py line 19
create_user() doesn't explicitly set is_active=True.
Default is True, but explicit is better for auth code.
Verdict: Approve after fixes.
The agent fixes both issues in 2 minutes. Nico re-reviews. Approved.
View details
Thom: β
JWT Authentication β complete
π 8 files created/modified
π§ͺ 15 tests β all passing
π Coverage: 94%
β
Code review: Approved by Nico
Ready for merge. Create MR?
The Results
| Metric | Manual Development | Agent + Review | Improvement |
|---|---|---|---|
| Implementation time | 4-8 hours | 20 minutes | 92% faster |
| Test writing time | 2-3 hours | Included (0 extra) | Eliminated |
| Test coverage | 60-80% (typical) | 94% | +14-34% |
| Code review issues | 3-5 per first review | 2 minor | Fewer iterations |
| Total time to merge-ready | 1-2 days | 30 minutes | 95% faster |
| Developer cost | $200-400 (at contractor rates) | ~$0.50 (API cost) | 99.7% cheaper |
Try It Yourself
Mr.Chief's ACP protocol delegates tasks to Claude Code with project context. The key is the task description: be specific about what you want (endpoints, patterns, test coverage), and point to existing code for style consistency. Always route through a code review agent β AI-generated code is good, but not infallible. The 10-minute review catches what the 20-minute generation misses.
I didn't write a single line. I described what I needed, reviewed the result, and shipped it. That's the future of feature development.
Related case studies
Software Engineer
Code Refactoring at Scale β Agent Migrated 200 Files to New Pattern
Migrating 200 Django files from function-based to class-based views β an AI agent did it in 4 hours with zero regressions. A developer would need 2-3 weeks.
Full-Stack Developer
Auto-Generated API Documentation β From Code to Docs in 3 Minutes
How an AI agent reads Django views, serializers, and models to generate complete OpenAPI specs and markdown API docs in 3 minutes. Auto-updates on every merge.
Software Engineer
Debugging a Production Error β Agent Found the Bug From Logs Alone
A production 500 error affected 23 users. An AI agent diagnosed a race condition from logs alone and shipped a fix PR in 35 minutes. Full incident timeline inside.
Want results like these?
Start free with your own AI team. No credit card required.