tech-leads-club/component-common-domain-detection
Finds duplicate business logic spread across multiple components and suggests consolidation. Use when asking "where is this logic duplicated?", "find common code between services", "what can be consolidated?", "detect shared domain logic", or analyzing component overlap before refactoring. Do NOT use for code-level duplication detection (use linters) or dependency analysis (use coupling-analysis).
This is a copy. The original lives at christophacham/component-common-domain-detection.
npx skills add https://github.com/tech-leads-club/agent-skills --skill component-common-domain-detection
This skill identifies common domain functionality that is duplicated across multiple components and suggests consolidation opportunities to reduce duplication and improve maintainability.
Request analysis of your codebase:
Example 1: Find Common Functionality
User: "Find common domain functionality across components"
The skill will:
1. Scan component namespaces for common patterns
2. Detect shared classes used across components
3. Identify duplicate domain logic
4. Analyze coupling impact of consolidation
5. Suggest consolidation opportunities
Example 2: Detect Duplicate Notification Logic
User: "Are there multiple notification components that should be consolidated?"
The skill will:
1. Find all components with notification-related names
2. Analyze their functionality and dependencies
3. Calculate coupling impact if consolidated
4. Recommend consolidation approach
Example 3: Analyze Shared Classes
User: "Find classes that are shared across multiple components"
The skill will:
1. Identify classes imported/used by multiple components
2. Classify as domain vs infrastructure functionality
3. Suggest consolidation or shared library approach
4. Assess impact on coupling
Apply this skill when:
Domain Functionality (candidates for consolidation):
Infrastructure Functionality (usually not consolidated here):
Common domain functionality often appears as:
*.notification, *.audit, *.validation, *.formattingTicketNotification, BillingNotification, SurveyNotificationSMTPConnection used by 5 different componentsAuditLogger used by multiple domain componentsShared Service:
Shared Library:
Component Consolidation:
Scan component namespaces for common leaf node names:
services/billing/notification → notificationservices/ticket/notification → notification.notification.util, .helper, .common (usually infrastructure).notification, .audit, .validation, .formattingExample Output:
## Common Namespace Patterns Found
**Notification Components**:
- services/customer/notification
- services/ticket/notification
- services/survey/notification
**Audit Components**:
- services/billing/audit
- services/ticket/audit
- services/survey/audit
Find classes/files used across multiple components:
Example Output:
## Shared Classes Found
**Domain Classes**:
- `SMTPConnection` - Used by 5 components (notification-related)
- `AuditLogger` - Used by 8 components (audit-related)
- `DataFormatter` - Used by 3 components (formatting-related)
**Infrastructure Classes** (exclude from consolidation):
- `Logger` - Used by all components (infrastructure)
- `Config` - Used by all components (infrastructure)
For each group of common components:
Example Analysis:
## Functionality Analysis
**Notification Components**:
- CustomerNotification: Sends billing notifications
- TicketNotification: Sends ticket assignment notifications
- SurveyNotification: Sends survey emails
**Similarities**: All send emails to customers
**Differences**: Email content/templates, triggers
**Consolidation Feasibility**: ✅ High
- Differences are in content, not mechanism
- Can be abstracted with templates/context
Before recommending consolidation, analyze coupling:
Example Coupling Analysis:
## Coupling Impact Analysis
**Before Consolidation**:
- CustomerNotification: Used by 2 components (CA = 2)
- TicketNotification: Used by 2 components (CA = 2)
- SurveyNotification: Used by 1 component (CA = 1)
- **Total CA**: 5
**After Consolidation**:
- Notification: Used by 5 components (CA = 5)
- **Total CA**: 5 (same!)
**Verdict**: ✅ No coupling increase, safe to consolidate
Based on analysis, recommend approach:
Shared Service (if):
Shared Library (if):
Component Consolidation (if):
## Common Domain Components Found
### Notification Functionality
**Components**:
- services/customer/notification (2% - 1,433 statements)
- services/ticket/notification (2% - 1,765 statements)
- services/survey/notification (2% - 1,299 statements)
**Shared Classes**: SMTPConnection (used by all 3)
**Functionality Analysis**:
- All send emails to customers
- Differences: Content/templates, triggers
- Consolidation Feasibility: ✅ High
**Coupling Analysis**:
- Before: CA = 2 + 2 + 1 = 5
- After: CA = 5 (no increase)
- Verdict: ✅ Safe to consolidate
**Recommendation**: Consolidate into `services/notification`
- Approach: Shared Service
- Expected Size: ~4,500 statements (5% of codebase)
- Benefits: Reduced duplication, easier maintenance
## Consolidation Opportunities
| Common Functionality | Components | Current CA | After CA | Feasibility | Recommendation |
| -------------------- | ------------ | ---------- | -------- | ----------- | ----------------------------- |
| Notification | 3 components | 5 | 5 | ✅ High | Consolidate to shared service |
| Audit | 3 components | 8 | 12 | ⚠️ Medium | Consolidate, monitor coupling |
| Validation | 2 components | 3 | 3 | ✅ High | Consolidate to shared library |
## Consolidation Plan
### Priority: High
**Notification Components** → `services/notification`
**Steps**:
1. Create new `services/notification` component
2. Move common functionality from 3 components
3. Create abstraction for content/templates
4. Update dependent components to use new service
5. Remove old notification components
**Expected Impact**:
- Reduced code: ~4,500 statements consolidated
- Reduced duplication: 3 components → 1
- Coupling: No increase (CA stays at 5)
- Maintenance: Easier to maintain single component
### Priority: Medium
**Audit Components** → `services/audit`
**Steps**:
[Similar format]
**Expected Impact**:
- Coupling increase: CA 8 → 12 (monitor)
- Benefits: Reduced duplication
Common Pattern Detection:
Shared Class Detection:
Functionality Analysis:
Coupling Assessment:
Recommendations:
Common patterns to look for:
services/
├── CustomerService/
│ └── notification.js ← Common pattern
├── TicketService/
│ └── notification.js ← Common pattern
└── SurveyService/
└── notification.js ← Common pattern
Shared Classes:
require() statementsconst SMTPConnection = require('../shared/SMTPConnection')Common patterns:
com.company.billing.audit ← Common pattern
com.company.ticket.audit ← Common pattern
com.company.survey.audit ← Common pattern
Shared Classes:
import statementsimport com.company.shared.AuditLoggerNamespace Pattern Detection:
// Extract leaf nodes from namespaces
function extractLeafNode(namespace) {
const parts = namespace.split('/')
return parts[parts.length - 1]
}
// Group by common leaf nodes
function groupByLeafNode(components) {
const groups = {}
components.forEach((comp) => {
const leaf = extractLeafNode(comp.namespace)
if (!groups[leaf]) groups[leaf] = []
groups[leaf].push(comp)
})
return groups
}
Shared Class Detection:
// Find classes used by multiple components
function findSharedClasses(components) {
const classUsage = {}
components.forEach((comp) => {
comp.imports.forEach((imp) => {
if (!classUsage[imp]) classUsage[imp] = []
classUsage[imp].push(comp.name)
})
})
return Object.entries(classUsage)
.filter(([cls, users]) => users.length > 1)
.map(([cls, users]) => ({ class: cls, usedBy: users }))
}
After identifying common components, create automated checks:
// Alert if new components with common patterns are created
function checkCommonPatterns(components, exclusionList = []) {
const leafNodes = {}
components.forEach((comp) => {
const leaf = extractLeafNode(comp.namespace)
if (!exclusionList.includes(leaf)) {
if (!leafNodes[leaf]) leafNodes[leaf] = []
leafNodes[leaf].push(comp.name)
}
})
return Object.entries(leafNodes)
.filter(([leaf, comps]) => comps.length > 1)
.map(([leaf, comps]) => ({
pattern: leaf,
components: comps,
suggestion: 'Consider consolidating these components',
}))
}
// Alert if class is used by multiple components
function checkSharedClasses(components, exclusionList = []) {
const classUsage = {}
components.forEach((comp) => {
comp.imports.forEach((imp) => {
if (!exclusionList.includes(imp)) {
if (!classUsage[imp]) classUsage[imp] = []
classUsage[imp].push(comp.name)
}
})
})
return Object.entries(classUsage)
.filter(([cls, users]) => users.length > 1)
.map(([cls, users]) => ({
class: cls,
usedBy: users,
suggestion: 'Consider extracting to shared component or library',
}))
}
*.notification, *.notify, *.email*.audit, *.auditing, *.log*.validation, *.validate, *.validator*.format, *.formatter, *.formatting*.report, *.reporting (if similar functionality)*.util, *.helper, *.common (usually infrastructure)After identifying common domain components:
Take tech-leads-club/component-common-domain-detection from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.