Component Flattening Analysis
This skill identifies component hierarchy issues and ensures components exist only as leaf nodes in directory/namespace structures, removing orphaned classes from root namespaces.
How to Use
Quick Start
Request analysis of your codebase:
- "Find orphaned classes in root namespaces"
- "Flatten component hierarchies"
- "Identify components that need flattening"
- "Analyze component structure for hierarchy issues"
Usage Examples
Example 1: Find Orphaned Classes
Example 2: Flatten Components
Example 3: Component Structure Analysis
Step-by-Step Process
- Scan Structure: Map component namespace hierarchies
- Identify Issues: Find orphaned classes and component nesting
- Analyze Options: Determine flattening strategy (consolidate vs split)
- Create Plan: Generate refactoring plan with steps
- Execute: Refactor components to remove hierarchy
When to Use
Apply this skill when:
- After gathering common domain components (Pattern 2)
- Before determining component dependencies (Pattern 4)
- When components have nested structures
- Finding orphaned classes in root namespaces
- Preparing for domain grouping
- Cleaning up component structure
- Ensuring components are leaf nodes only
Core Concepts
Component Definition
A component is identified by a leaf node in directory/namespace structure:
- Leaf Node: The deepest directory containing source files
- Component: Source code files in leaf node namespace
- Subdomain: Parent namespace that has been extended
Key Rule: Components exist only as leaf nodes. If a namespace is extended, the parent becomes a subdomain, not a component.
Root Namespace
A root namespace is a namespace node that has been extended:
- Extended: Another namespace node added below it
- Example:
ss.surveyextended toss.survey.templates - Result:
ss.surveybecomes a root namespace (subdomain)
Orphaned Classes
Orphaned classes are source files in root namespaces:
- Location: Root namespace (non-leaf node)
- Problem: No definable component associated with them
- Solution: Move to leaf node namespace (component)
Example:
Flattening Strategies
Strategy 1: Consolidate Down
- Move code from leaf nodes into root namespace
- Makes root namespace the component
- Example: Move
ss.survey.templates→ss.survey
Strategy 2: Split Up
- Move code from root namespace into new leaf nodes
- Creates new components from root namespace
- Example: Split
ss.survey→ss.survey.create+ss.survey.process
Strategy 3: Move Shared Code
- Move shared code to dedicated component
- Creates
.sharedcomponent - Example:
ss.surveyshared code →ss.survey.shared
Analysis Process
Phase 1: Map Component Structure
Scan directory/namespace structure to identify hierarchy:
-
Map Namespace Tree
- Build tree of all namespaces
- Identify parent-child relationships
- Mark leaf nodes (components)
-
Identify Root Namespaces
- Find namespaces that have been extended
- Mark as root namespaces (subdomains)
- Note which namespaces extend them
-
Locate Source Files
- Find all source files in each namespace
- Map files to their namespace location
- Identify files in root namespaces
Example Structure Mapping:
ss.survey/ ← Root namespace (extended) ├── Survey.js ← Orphaned class ├── SurveyProcessor.js ← Orphaned class └── templates/ ← Component (leaf node) ├── EmailTemplate.js └── SMSTemplate.js
ss.ticket/ ← Root namespace (extended) ├── Ticket.js ← Orphaned class ├── assign/ ← Component (leaf node) │ └── TicketAssign.js └── route/ ← Component (leaf node) └── TicketRoute.js
Phase 2: Identify Orphaned Classes
Find source files in root namespaces:
-
Scan Root Namespaces
- Check each root namespace for source files
- Identify files that are orphaned
- Count orphaned files per root namespace
-
Classify Orphaned Classes
- Shared Code: Common utilities, interfaces, abstract classes
- Domain Code: Business logic that should be in component
- Mixed: Combination of shared and domain code
-
Assess Impact
- How many files are orphaned?
- What functionality do they contain?
- What components depend on them?
Example Orphaned Class Detection:
Phase 3: Analyze Flattening Options
Determine best flattening strategy for each root namespace:
-
Option 1: Consolidate Down
- Move leaf node code into root namespace
- Makes root namespace the component
- Use when: Leaf nodes are small, related functionality
-
Option 2: Split Up
- Move root namespace code into new leaf nodes
- Creates multiple components from root
- Use when: Root namespace has distinct functional areas
-
Option 3: Move Shared Code
- Extract shared code to
.sharedcomponent - Keep domain code in root or split
- Use when: Root namespace has shared utilities
- Extract shared code to
Example Flattening Analysis:
Phase 4: Create Flattening Plan
Generate refactoring plan for each root namespace:
-
Select Strategy
- Choose best flattening option
- Consider effort, complexity, maintainability
-
Plan Refactoring Steps
- List files to move
- Identify target namespaces
- Note dependencies to update
-
Estimate Effort
- Time to refactor
- Risk assessment
- Testing requirements
Example Flattening Plan:
Phase 5: Execute Flattening
Perform the refactoring:
-
Move Files
- Move source files to target namespace
- Update file paths and imports
-
Update References
- Update imports in dependent components
- Update namespace declarations
- Update directory structure
-
Verify Changes
- Run tests
- Check for broken references
- Validate component structure
Output Format
Orphaned Classes Report
Component Hierarchy Issues
Flattening Plan
Analysis Checklist
Structure Mapping:
- Mapped all namespace hierarchies
- Identified root namespaces
- Located all source files
- Marked leaf nodes (components)
Orphaned Class Detection:
- Scanned root namespaces for source files
- Identified orphaned classes
- Classified orphaned classes (shared/domain/mixed)
- Assessed impact and dependencies
Flattening Analysis:
- Analyzed consolidation option
- Analyzed splitting option
- Analyzed shared code extraction option
- Selected best strategy for each root namespace
Plan Creation:
- Selected flattening strategy
- Created refactoring steps
- Estimated effort and risk
- Prioritized work
Execution:
- Moved files to target namespaces
- Updated imports and references
- Updated namespace declarations
- Verified changes with tests
Implementation Notes
For Node.js/Express Applications
Components typically in services/ directory:
Flattening:
- Consolidate: Move
templates/files tosurvey/ - Split: Create
survey/create/andsurvey/process/ - Shared: Create
survey/shared/for utilities
For Java Applications
Components identified by package structure:
Flattening:
- Consolidate: Move
templatesclasses tosurveypackage - Split: Create
survey.createandsurvey.processpackages - Shared: Create
survey.sharedpackage
Detection Strategies
Find Root Namespaces with Code:
Find Orphaned Classes:
Fitness Functions
After flattening components, create automated checks:
No Source Code in Root Namespaces
Components Only as Leaf Nodes
Best Practices
Do's ✅
- Ensure components exist only as leaf nodes
- Remove orphaned classes from root namespaces
- Choose flattening strategy based on functionality
- Consolidate when functionality is related
- Split when functionality is distinct
- Extract shared code to
.sharedcomponents - Update all references after flattening
- Verify changes with tests
Don'ts ❌
- Don't leave orphaned classes in root namespaces
- Don't create components on top of other components
- Don't skip updating imports after moving files
- Don't flatten without analyzing impact
- Don't mix flattening strategies inconsistently
- Don't ignore shared code when flattening
- Don't skip testing after refactoring
Common Patterns
Pattern 1: Simple Consolidation
Before:
After:
Pattern 2: Functional Split
Before:
After:
Pattern 3: Shared Code Extraction
Before:
After:
Next Steps
After flattening components:
- Apply Determine Component Dependencies Pattern - Analyze coupling
- Create Component Domains - Group components into domains
- Create Domain Services - Extract domains to services
Notes
- Components must exist only as leaf nodes
- Root namespaces with code are problematic
- Flattening improves component clarity
- Choose flattening strategy based on functionality
- Shared code should be in dedicated components
- Always update references after moving files
- Test thoroughly after flattening


