Refactoring Agent Examples

Eliminate duplication

📄 players/views.py
-18 lines+11 linesExtract Mixin
Extract Mixin
BEFOREAuth logic mixed with business logic
24
@method_decorator(login_required, name='dispatch')
25
class AdminManageUsersView(View):
29
    def get(self, request, *args, **kwargs):
×2 DUPLICATED
30
        # Check if the current user is an admin
31
        try:
32
            player = Player.objects.get(user=request.user)
33
            if not player.is_admin:
34
                return HttpResponseForbidden("...")
35
        except Player.DoesNotExist:
36
            return HttpResponseForbidden("...")
38
        # Get all users...
...
        ...
52
    def post(self, request, *args, **kwargs):
53
        # Check if the current user is an admin
54
        try:
55
            player = Player.objects.get(user=request.user)
56
            if not player.is_admin:
57
                return HttpResponseForbidden("...")
58
        except Player.DoesNotExist:
59
            return HttpResponseForbidden("...")
61
        # Handle user deletion...
NEW CLASSline 10
10
class AdminRequiredMixin(LoginRequiredMixin):
11
    """Mixin to require admin status."""
12
    def dispatch(self, request, *args, **kwargs):
13
        try:
14
            player = Player.objects.get(user=request.user)
15
        except Player.DoesNotExist:
16
            return HttpResponseForbidden("...")
17
        if not player.is_admin:
18
            return HttpResponseForbidden("...")
19
        return super().dispatch(request, *args, **kwargs)
AFTERAuth logic cleanly separated
38
class AdminManageUsersView(AdminRequiredMixin, View):
42
    def get(self, request, *args, **kwargs):
43
        # Get all players and map...
...
        ...
59
    def post(self, request, *args, **kwargs):
60
        # Handle user deletion...

Remove indirection

📄 pages/_app.tsx
-4 linesRemove Indirection
BEFOREUnnecessary wrapper function
42
                      <Layout>
43
                        <Component {...pageProps} />
44
                        <UserTracking />
USELESS WRAPPER
45
                        <LoginTracking />
46
                      </Layout>
...
...
118
function LoginTracking() {
119
  return <LoginTracker />;
120
}
AFTERDirect component usage
42
                      <Layout>
43
                        <Component {...pageProps} />
44
                        <UserTracking />
45
                        <LoginTracker />
46
                      </Layout>
...

Separate logic

📄 features/auth/hooks.ts → features/auth/storage.ts
-25 lines+3 linesExtract Storage Logic
BEFOREStorage logic mixed with UI hook
...
40
export const useLastUsedLogin = () => {
41
  const [logins, setLogins] = useState<LastUsedLogin[]>([]);
43
  // Load from localStorage on mount
44
  useEffect(() => {
UI HOOK+ STORAGE LOGIC
45
    if (typeof window === "undefined") return;
47
    try {
48
      const stored = localStorage.getItem(STORAGE_KEY);
49
      if (stored) {
50
        const parsed = JSON.parse(stored) as LastUsedLogin[];
51
        // Filter out expired entries
52
        const now = Date.now();
53
        const valid = parsed.filter(
54
          (login) =>
55
            now - login.timestamp < EXPIRATION_DAYS * 24 * 60 * 60 * 1000,
56
        );
57
        setLogins(valid);
59
        // Update localStorage if we filtered anything
60
        if (valid.length !== parsed.length) {
61
          localStorage.setItem(STORAGE_KEY, JSON.stringify(valid));
62
        }
63
      }
64
    } catch (error) {
65
      console.error("Failed to load last used logins:", error);
66
    }
67
  }, []);
...
NEW MODULEfeatures/auth/storage.ts
Separated Storage Logic
45
export function loadLastUsedLogins(): LastUsedLogin[] {
46
  const stored = safeGetJson<LastUsedLogin[]>(
47
    localStorage,
48
    LAST_USED_STORAGE_KEY,
49
  );
...
  // Filter expired, update storage...
62
}
AFTERUI HOOK ONLY
Clean separation
...
40
export const useLastUsedLogin = () => {
41
  const [logins, setLogins] = useState<LastUsedLogin[]>([]);
43
  // Load from localStorage on mount
44
  useEffect(() => {
45
    const loaded = loadLastUsedLogins();
46
    setLogins(loaded);
47
  }, []);
...