VDK Docs
Configuration

Pattern Detection

Documentation for pattern detection

Pattern Detection

VDK's pattern detection system is one of its most powerful features, automatically identifying architectural patterns, design patterns, and coding conventions in your codebase to generate intelligent AI assistant rules.

Overview

Pattern detection analyzes your project to identify:

  • Architectural Patterns: High-level system organization (MVC, MVVM, microservices)
  • Design Patterns: Common programming patterns (Singleton, Factory, Observer)
  • Framework Patterns: Framework-specific patterns (React hooks, Django models)
  • Organizational Patterns: Code organization and structure patterns
  • Custom Patterns: Project-specific patterns and conventions

How Pattern Detection Works

1. File Structure Analysis

VDK examines your directory structure to identify organizational patterns:

src/
├── components/          # Component-based architecture
│   ├── ui/             # Atomic design pattern
│   ├── layout/         # Layout components
│   └── features/       # Feature-based organization
├── hooks/              # Custom hooks pattern
├── services/           # Service layer pattern
├── stores/             # State management pattern
└── utils/              # Utility pattern

Detected Patterns:

  • Component-based architecture
  • Atomic design system
  • Feature-based organization
  • Custom hooks pattern
  • Service layer separation

2. Code Analysis

Static analysis of code files to identify programming patterns:

// Singleton pattern detection
class DatabaseConnection {
  private static instance: DatabaseConnection;

  static getInstance(): DatabaseConnection {
    if (!DatabaseConnection.instance) {
      DatabaseConnection.instance = new DatabaseConnection();
    }
    return DatabaseConnection.instance;
  }
}

// Factory pattern detection
class ComponentFactory {
  createComponent(type: string): Component {
    switch (type) {
      case 'button': return new ButtonComponent();
      case 'input': return new InputComponent();
      default: throw new Error('Unknown component type');
    }
  }
}

// Observer pattern detection
class EventEmitter {
  private listeners: Map<string, Function[]> = new Map();

  on(event: string, callback: Function): void {
    // Observer pattern implementation
  }
}

3. Framework-Specific Analysis

Recognition of framework-specific patterns and conventions:

React Patterns

// Custom hooks pattern
function useUserData(userId: string) {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetchUser(userId).then(setUser).finally(() => setLoading(false));
  }, [userId]);

  return { user, loading };
}

// Higher-Order Component pattern
function withAuth<T extends object>(Component: React.ComponentType<T>) {
  return function AuthenticatedComponent(props: T) {
    const { isAuthenticated } = useAuth();

    if (!isAuthenticated) {
      return <LoginForm />;
    }

    return <Component {...props} />;
  };
}

// Render props pattern
function DataProvider({ children }: { children: (data: Data) => ReactNode }) {
  const [data, setData] = useState<Data>();

  return children(data);
}

Next.js Patterns

// App Router patterns
export default async function UserPage({ params }: { params: { id: string } }) {
  const user = await getUser(params.id); // Server component data fetching
  return <UserProfile user={user} />;
}

// Server actions pattern
'use server'
export async function createUser(formData: FormData) {
  const name = formData.get('name') as string;
  const user = await prisma.user.create({ data: { name } });
  revalidatePath('/users');
  return user;
}

// Route handlers pattern
export async function GET(request: NextRequest) {
  const users = await prisma.user.findMany();
  return NextResponse.json(users);
}

Detected Pattern Categories

Architectural Patterns

MVC (Model-View-Controller)

Detection Criteria:
- Separate model, view, controller directories
- Clear separation of concerns
- Data flow from model through controller to view

Example Structure:
├── models/         # Data models
├── views/          # View components
├── controllers/    # Business logic
└── routes/         # Route definitions

MVVM (Model-View-ViewModel)

Detection Criteria:
- ViewModel layer between model and view
- Data binding patterns
- Reactive state management

Example Structure:
├── models/         # Data models
├── views/          # UI components
├── viewmodels/     # View models
└── services/       # Data services

Component-Based Architecture

Detection Criteria:
- Component-centric organization
- Reusable component patterns
- Component composition

Example Structure:
├── components/
│   ├── ui/         # Base components
│   ├── layout/     # Layout components
│   └── features/   # Feature components

Microservices

Detection Criteria:
- Service-oriented directory structure
- Independent service modules
- API gateway patterns

Example Structure:
├── services/
│   ├── auth/       # Authentication service
│   ├── users/      # User service
│   └── orders/     # Order service
└── gateway/        # API gateway

Design Patterns

Repository Pattern

// Pattern detection criteria
interface UserRepository {
  findById(id: string): Promise<User | null>;
  findAll(): Promise<User[]>;
  create(user: CreateUserInput): Promise<User>;
  update(id: string, user: UpdateUserInput): Promise<User>;
  delete(id: string): Promise<void>;
}

class DatabaseUserRepository implements UserRepository {
  // Implementation
}

Factory Pattern

// Pattern detection criteria
abstract class ComponentFactory {
  abstract createComponent(type: string): Component;
}

class UIComponentFactory extends ComponentFactory {
  createComponent(type: string): Component {
    // Factory implementation
  }
}

Dependency Injection

// Pattern detection criteria
class UserService {
  constructor(
    private userRepository: UserRepository,
    private emailService: EmailService
  ) {}
}

// Container or IoC patterns
const container = new Container();
container.bind(UserRepository).to(DatabaseUserRepository);

Framework-Specific Patterns

React Patterns

Custom Hooks Pattern:

// Detection: Functions starting with 'use' that use React hooks
function useApi<T>(url: string): { data: T | null; loading: boolean; error: Error | null } {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    fetch(url)
      .then(response => response.json())
      .then(setData)
      .catch(setError)
      .finally(() => setLoading(false));
  }, [url]);

  return { data, loading, error };
}

Context Pattern:

// Detection: createContext usage with Provider components
const UserContext = createContext<User | null>(null);

export function UserProvider({ children }: { children: ReactNode }) {
  const [user, setUser] = useState<User | null>(null);

  return (
    <UserContext.Provider value={user}>
      {children}
    </UserContext.Provider>
  );
}

Compound Components:

// Detection: Components with sub-components as static properties
function Accordion({ children }: { children: ReactNode }) {
  return <div className="accordion">{children}</div>;
}

Accordion.Item = function AccordionItem({ children }: { children: ReactNode }) {
  return <div className="accordion-item">{children}</div>;
};

Accordion.Header = function AccordionHeader({ children }: { children: ReactNode }) {
  return <div className="accordion-header">{children}</div>;
};

Next.js Patterns

App Router Pattern:

// Detection: app/ directory with page.tsx, layout.tsx files
app/
├── layout.tsx          # Root layout
├── page.tsx            # Home page
├── users/
│   ├── page.tsx        # Users page
│   └── [id]/
│       └── page.tsx    # Dynamic user page
└── api/
    └── users/
        └── route.ts    # API route

Server Components Pattern:

// Detection: Async components without 'use client'
export default async function UsersList() {
  const users = await getUsers(); // Server-side data fetching
  return (
    <div>
      {users.map(user => (
        <UserCard key={user.id} user={user} />
      ))}
    </div>
  );
}

Server Actions Pattern:

// Detection: 'use server' directive with form actions
'use server'

export async function createUser(formData: FormData) {
  const name = formData.get('name') as string;
  const email = formData.get('email') as string;

  const user = await prisma.user.create({
    data: { name, email }
  });

  revalidatePath('/users');
  redirect(`/users/${user.id}`);
}

State Management Patterns

Redux Pattern

// Detection: Actions, reducers, store structure
// Actions
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';

// Action creators
const increment = () => ({ type: INCREMENT });
const decrement = () => ({ type: DECREMENT });

// Reducer
function counterReducer(state = { count: 0 }, action) {
  switch (action.type) {
    case INCREMENT:
      return { count: state.count + 1 };
    case DECREMENT:
      return { count: state.count - 1 };
    default:
      return state;
  }
}

Zustand Pattern

// Detection: create() function with store definition
import { create } from 'zustand';

interface UserState {
  users: User[];
  addUser: (user: User) => void;
  removeUser: (id: string) => void;
}

const useUserStore = create<UserState>((set) => ({
  users: [],
  addUser: (user) => set((state) => ({ users: [...state.users, user] })),
  removeUser: (id) => set((state) => ({ users: state.users.filter(u => u.id !== id) })),
}));

Pattern Detection Configuration

Enable/Disable Pattern Categories

Configure which patterns to detect in vdk.config.json:

{
  "scanner": {
    "patternDetection": {
      "architectural": {
        "enabled": true,
        "patterns": ["mvc", "mvvm", "component-based", "microservices", "layered"]
      },
      "design": {
        "enabled": true,
        "patterns": ["singleton", "factory", "observer", "repository", "strategy"]
      },
      "framework": {
        "enabled": true,
        "react": ["hooks", "context", "hoc", "render-props"],
        "nextjs": ["app-router", "server-components", "server-actions"],
        "express": ["middleware", "routing", "controllers"]
      },
      "organizational": {
        "enabled": true,
        "patterns": ["feature-based", "atomic-design", "domain-driven"]
      }
    }
  }
}

Custom Pattern Detection

Define custom patterns for your project:

{
  "scanner": {
    "customPatterns": [
      {
        "name": "API Response Pattern",
        "description": "Standardized API response structure",
        "criteria": {
          "filePattern": "**/*api*.ts",
          "codePattern": "interface.*Response.*{.*data:.*message:.*success:",
          "examples": ["ApiResponse", "DataResponse", "ErrorResponse"]
        }
      },
      {
        "name": "Error Handling Pattern",
        "description": "Custom error handling utilities",
        "criteria": {
          "filePattern": "**/error*.ts",
          "codePattern": "class.*Error.*extends.*Error",
          "examples": ["ValidationError", "NotFoundError", "UnauthorizedError"]
        }
      }
    ]
  }
}

Pattern Analysis Output

Pattern Report

VDK generates detailed pattern analysis:

{
  "patternAnalysis": {
    "architectural": {
      "primary": "Component-based",
      "secondary": ["Feature-based organization"],
      "confidence": 0.95
    },
    "design": {
      "detected": [
        {
          "pattern": "Repository Pattern",
          "files": ["lib/repositories/user.ts", "lib/repositories/post.ts"],
          "confidence": 0.9
        },
        {
          "pattern": "Factory Pattern",
          "files": ["lib/factories/component-factory.ts"],
          "confidence": 0.85
        }
      ]
    },
    "framework": {
      "react": {
        "hooks": {
          "custom": ["useUser", "useAuth", "useApi"],
          "usage": "extensive"
        },
        "context": {
          "providers": ["UserProvider", "ThemeProvider"],
          "usage": "moderate"
        }
      },
      "nextjs": {
        "appRouter": true,
        "serverComponents": "primary",
        "serverActions": "moderate"
      }
    },
    "organizational": {
      "structure": "Feature-based",
      "consistency": 0.92,
      "adherence": "high"
    }
  }
}

Generated Rules Based on Patterns

VDK creates specific rules based on detected patterns:

Repository Pattern Rules

# Repository Pattern

## Pattern Usage
This project uses the Repository pattern for data access abstraction.

## Implementation Guidelines
- Create repository interfaces for each entity
- Implement concrete repositories for different data sources
- Use dependency injection for repository instances

## Example Implementation
```typescript
interface UserRepository {
  findById(id: string): Promise<User | null>;
  findAll(): Promise<User[]>;
  create(user: CreateUserInput): Promise<User>;
}

class PrismaUserRepository implements UserRepository {
  constructor(private prisma: PrismaClient) {}

  async findById(id: string): Promise<User | null> {
    return this.prisma.user.findUnique({ where: { id } });
  }
}

#### Custom Hooks Rules
```markdown
# Custom Hooks Pattern

## Hook Conventions
- Prefix all custom hooks with 'use'
- Return objects for multiple values
- Handle cleanup in useEffect

## Example Custom Hook
```typescript
function useUserData(userId: string) {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    let cancelled = false;

    fetchUser(userId)
      .then(user => {
        if (!cancelled) {
          setUser(user);
          setError(null);
        }
      })
      .catch(error => {
        if (!cancelled) {
          setError(error);
        }
      })
      .finally(() => {
        if (!cancelled) {
          setLoading(false);
        }
      });

    return () => {
      cancelled = true;
    };
  }, [userId]);

  return { user, loading, error };
}

## Advanced Pattern Detection

### Cross-File Pattern Analysis

VDK analyzes relationships between files to detect complex patterns:

```typescript
// File: services/user-service.ts
export class UserService {
  constructor(private userRepo: UserRepository) {}

  async createUser(data: CreateUserInput): Promise<User> {
    return this.userRepo.create(data);
  }
}

// File: repositories/user-repository.ts
export interface UserRepository {
  create(data: CreateUserInput): Promise<User>;
}

// File: repositories/prisma-user-repository.ts
export class PrismaUserRepository implements UserRepository {
  // Implementation
}

// Detected Pattern: Service + Repository + Dependency Injection

Temporal Pattern Analysis

Detecting patterns that evolve over time:

// Version 1: Simple component
function UserCard({ user }) {
  return <div>{user.name}</div>;
}

// Version 2: Enhanced with props interface
interface UserCardProps {
  user: User;
}

function UserCard({ user }: UserCardProps) {
  return <div>{user.name}</div>;
}

// Version 3: Added error handling
function UserCard({ user }: UserCardProps) {
  if (!user) return <div>User not found</div>;
  return <div>{user.name}</div>;
}

// Detected Evolution: Progressive enhancement pattern

Anti-Pattern Detection

VDK can also identify anti-patterns to avoid:

// Anti-pattern: Prop drilling
function App() {
  const user = useUser();
  return <Dashboard user={user} />;
}

function Dashboard({ user }: { user: User }) {
  return <Sidebar user={user} />;
}

function Sidebar({ user }: { user: User }) {
  return <UserMenu user={user} />;
}

// Suggestion: Use Context or state management

Pattern-Based Rule Generation

Intelligent Rule Creation

VDK generates rules that match your detected patterns:

  1. Pattern Recognition: Identifies specific patterns in use
  2. Context Analysis: Understands how patterns are implemented
  3. Rule Generation: Creates guidelines that match your style
  4. Example Creation: Provides examples based on your actual code

Dynamic Rule Updates

As patterns evolve, VDK updates rules accordingly:

# After adding new patterns
vdk init --overwrite

# Update AI memory with new patterns
vdk claude-code --update-memory

# Check pattern analysis
vdk analyze --patterns

Best Practices for Pattern Detection

1. Maintain Consistent Patterns

// ✅ Consistent repository pattern
interface UserRepository {
  findById(id: string): Promise<User | null>;
}

interface PostRepository {
  findById(id: string): Promise<Post | null>;
}

// ❌ Inconsistent naming
interface UserRepo {
  getUser(id: string): Promise<User | null>;
}

interface PostService {
  findPost(id: string): Promise<Post | null>;
}

2. Document Pattern Decisions

/**
 * Repository Pattern Implementation
 *
 * We use the Repository pattern to abstract data access logic.
 * Each entity has its own repository interface and implementation.
 * This allows for easier testing and data source switching.
 */
export interface UserRepository {
  // Interface definition
}

3. Use TypeScript for Better Detection

TypeScript provides better pattern detection through type information:

// Better pattern detection with TypeScript
interface ApiResponse<T> {
  data: T;
  message: string;
  success: boolean;
}

// Vs. JavaScript (harder to detect patterns)
function createResponse(data, message, success) {
  return { data, message, success };
}

Next Steps