Two-Tier Navigation Architecture
Global + Space-specific navigation layers working together
🎯 Two-Tier Navigation Architecture
Date: October 29, 2025
Status: ✅ IMPLEMENTED
Decision: Keep BOTH navigation systems as complementary layers
🌟 Architecture Overview
The Pattern: Dual-Layer Navigation
Instead of choosing ONE navigation system, we use BOTH for different purposes:
┌─────────────────────────────────────────────────┐
│ LAYER 1: Global Navigation │
│ (MainSidenavComponent) │
│ ┌───────────────────────────────────────────┐ │
│ │ • Documentation (external) │ │
│ │ • Internal Tools │ │
│ │ ├─ Storage System Testing │ │
│ │ └─ Flash Persistence Demos │ │
│ │ • System-wide settings │ │
│ └───────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│ LAYER 2: Space-Specific Navigation │
│ (SidebarComponent in AppShell) │
│ ┌───────────────────────────────────────────┐ │
│ │ • Dashboard │ │
│ │ • Singularity (for this space) │ │
│ │ • Space Map (for this space) │ │
│ │ • Editor (for this space) │ │
│ │ • Modularity (for this space) │ │
│ │ • Widgets Manager (for this space) │ │
│ │ • Launch Station (for this space) │ │
│ └───────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
🎯 Why Two Layers?
Layer 1: Global Navigation (Static, Platform-Wide)
Purpose: Elements that apply across ALL spaces
Characteristics:
- ✅ Space-independent
- ✅ System-wide tools
- ✅ Internal/admin features
- ✅ External links (docs)
- ✅ Cross-space features
Examples:
- Documentation (external app)
- Storage System Testing (internal tools)
- Flash Persistence Demos (development)
- Platform settings
- User profile
Component: MainSidenavComponent
Layer 2: Space-Specific Navigation (Dynamic, Space-Scoped)
Purpose: Elements that belong to a SPECIFIC space
Characteristics:
- ✅ Space-scoped (depends on
/:spaceSlug) - ✅ Dynamically registered modules
- ✅ User's workspace tools
- ✅ Space-specific content
- ✅ Universe management
Examples:
- Dashboard (for this space)
- Singularity (flows in this space)
- Space Map (universes in this space)
- Editor (pages in this space)
- Widgets Manager (custom widgets for this space)
Component: SidebarComponent (in AppShellComponent)
🏗️ Implementation Details
Architecture Flow
User navigates to: /my-space/dashboard
1. Route matches: /:spaceSlug
↓
2. Guards run: authGuard, spaceGuard
↓
3. Space context set: { spaceId, spaceSlug }
↓
4. AppShellComponent loads
├─ HeaderComponent (global)
├─ SidebarComponent (LAYER 2: Space-specific) ✅
└─ <router-outlet> (content)
↓
5. MainSidenavComponent (LAYER 1: Global) ✅
(Rendered in main layout, always visible)
📂 Component Responsibilities
1. MainSidenavComponent (Global Layer)
Location: apps/gograb-space/src/app/layout/main-layout/main-sidenav/
Responsibilities:
✅ Documentation links (external)
✅ Internal Tools category:
├─ Storage System Testing
│ ├─ Test Lab
│ ├─ Deep Analysis
│ ├─ Performance Validator
│ ├─ Visual Persistence Lab
│ └─ System Insights
└─ Flash Persistence Demos
├─ Persistence Demo
└─ Animations Demo
✅ Platform-wide settings
✅ User profile/logout
When Visible: Always (across all routes)
Data Source:
- Manual navigation items (specialized categories)
- NavigationBuilderService for route-based items
2. SidebarComponent (Space Layer)
Location: apps/gograb-space/src/app/core/layout/
Responsibilities:
✅ Dashboard (space overview)
✅ Registered modules:
├─ Singularity (logic for this space)
├─ Space Map (universes in this space)
├─ Editor (pages in this space)
├─ Modularity (modules in this space)
├─ Widgets Manager (custom widgets for this space)
└─ Launch Station (deploy from this space)
✅ Dynamic module routes
✅ Space-specific tools
When Visible: Only under /:spaceSlug routes
Data Source:
- ModuleRegistryService (dynamically registered modules)
- UniverseContextService (current space context)
🎨 Visual Layout
Desktop Layout
┌──────────────────────────────────────────────────────┐
│ Header (Global) │
├────────────┬──────────────┬──────────────────────────┤
│ LAYER 1 │ LAYER 2 │ │
│ Global │ Space │ Main Content │
│ Nav │ Nav │ <router-outlet> │
│ │ │ │
│ • Docs │ • Dashboard │ ┌────────────────────┐ │
│ • Tools │ • Singular. │ │ │ │
│ ├─ Stor.│ • Space Map │ │ Dashboard Content │ │
│ └─ Demo │ • Editor │ │ │ │
│ │ • Modular. │ └────────────────────┘ │
│ │ • Widgets │ │
│ │ • Launch │ │
│ │ │ │
└────────────┴──────────────┴──────────────────────────┘
Mobile Layout (Collapsed)
┌──────────────────────────────────────────────────────┐
│ Header [☰ Menu] │
├──────────────────────────────────────────────────────┤
│ │
│ Main Content │
│ <router-outlet> │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Dashboard Content │ │
│ │ │ │
│ └────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────┘
[☰ Menu tapped → Slide-out showing BOTH layers]
🔄 Data Flow
Global Layer (MainSidenavComponent)
1. NavigationBuilderService
├─ Builds route-based items (static routes)
├─ Adds specialized categories manually
└─ Combines into navigationCategories()
2. Manual Categories
├─ Documentation (external link)
├─ Internal Tools
│ ├─ Storage System Testing
│ └─ Flash Demos
└─ Other platform-wide items
3. Render
└─ Always visible (global)
Space Layer (SidebarComponent)
1. ModuleRegistryService
├─ getAllModules()
└─ Filter modules with navigation.menuItems
2. UniverseContextService
├─ Get current spaceSlug
└─ Prepend to all routes
3. registeredModules() computed signal
└─ Maps modules to navigation items
4. Render
└─ Only visible under /:spaceSlug routes
📊 Benefits of Two-Tier Architecture
1. Clear Separation of Concerns ✅
Global Layer:
- Platform-level features
- System administration
- Internal tools
Space Layer:
- User's workspace
- Space-specific content
- Dynamic modules
2. Better Organization ✅
Users can immediately distinguish:
- What's available everywhere (global)
- What's specific to their current space
3. Scalability ✅
Easy to add new items to either layer without affecting the other:
- Global tools → MainSidenavComponent
- Space modules → Register in ModuleRegistry
4. Performance ✅
- Global nav: Cached (rarely changes)
- Space nav: Dynamic (updates when modules register)
5. User Experience ✅
- Clear mental model
- Predictable navigation
- Context-aware tools
🧩 Module Registration
Global Tools (Internal Category)
// Storage System is now a MODULE!
export const StorageSystemManifest: ModuleManifest = {
id: 'storage-system',
name: 'Storage System',
metadata: {
category: 'internal-tools', // ✅ Global category
visibility: 'development'
},
navigation: {
menuItems: [
{ id: 'test', label: 'Test Lab', route: '/storage/test' },
{ id: 'analysis', label: 'Deep Analysis', route: '/storage/analysis' },
// ... more items
]
}
};
// Register in main.ts
moduleRegistry.registerModule(StorageSystemManifest);
Space-Specific Modules
// Singularity, Editor, Space Map, etc.
export const SingularityManifest: ModuleManifest = {
id: 'singularity',
name: 'Singularity',
navigation: {
menuItems: [
{ id: 'logic-builder', label: 'Logic Builder', route: '/singularity' }
]
}
};
// Automatically appears in space-specific navigation
🎯 Routing Pattern
Global Routes (Platform-Wide)
// These work ANYWHERE
/landing → Landing page
/auth/login → Login
/auth/register → Register
/select-space → Space selector
Space Routes (Space-Specific)
// These require /:spaceSlug prefix
/:spaceSlug/dashboard → Dashboard
/:spaceSlug/singularity → Singularity
/:spaceSlug/space-map → Space Map
/:spaceSlug/editor → Editor
/:spaceSlug/modularity → Modularity
/:spaceSlug/widgets → Widgets Manager
/:spaceSlug/launch-station → Launch Station
Internal Tools (Global, but nested)
// Global tools (no space prefix needed)
/:spaceSlug/storage/test → Storage Test Lab
/:spaceSlug/storage/analysis → Storage Analysis
/:spaceSlug/demos/* → Flash Demos
Note: Internal tools are global but still use space prefix for consistency.
📝 Configuration
MainSidenavComponent (Global Layer)
readonly navigationCategories = computed(() => {
// 1. Route-based items from NavigationBuilderService
const routeItems = this.navigationBuilder.getRouteBasedItems();
// 2. Build main categories (Core, Creative, Analysis)
const mainCategories = this.navigationBuilder.buildCategories(routeItems);
// 3. Add specialized global categories
const globalCategories = [
{
id: 'documentation',
name: 'Documentation',
children: [/* external links */]
},
{
id: 'internal-tools',
name: '🔧 Internal Tools',
children: [
{
id: 'storage-testing',
name: 'Storage System Testing',
children: this.storageTree() // From StorageSystemManifest
}
]
}
];
return [...mainCategories, ...globalCategories];
});
SidebarComponent (Space Layer)
readonly registeredModules = computed(() => {
const allModules = this.moduleRegistry.getAllModules();
return allModules
.filter(m => m.navigation?.menuItems?.length > 0)
.map(m => ({
id: m.id,
displayName: m.name,
basePath: this.getModuleBasePath(m.id),
navigationItems: m.navigation.menuItems
}));
});
✅ Implementation Checklist
- Create StorageSystemManifest
- Register StorageSystemManifest in main.ts
- Export manifest from @storage-system
- Keep MainSidenavComponent (global layer)
- Keep SidebarComponent (space layer)
- Document two-tier architecture
- Update MainSidenavComponent to use StorageSystemManifest data
- Test both navigation layers work together
- Add category grouping in SidebarComponent
- Add visual distinction between layers
🎓 Key Insights
1. Not Either/Or, But Both
The question wasn't "Which navigation system?" but "How can they work together?"
2. Layers Serve Different Purposes
- Global = Platform features
- Space = User's workspace
3. Architectural Alignment
This aligns with your existing "global vs space" separation:
- Global widgets vs space widgets
- Global modules vs space modules
- Global navigation vs space navigation ✅
🚀 Future Enhancements
1. Visual Distinction
// Different colors/styles for each layer
.global-nav {
background: var(--global-nav-bg);
border-right: 2px solid var(--global-border);
}
.space-nav {
background: var(--space-nav-bg);
border-right: 2px solid var(--space-border);
}
2. Toggle Layers
Allow users to collapse/expand each layer independently:
- Global nav collapsed → More space for content
- Space nav collapsed → Focus on global tools
3. Search Across Layers
Unified search that searches BOTH layers:
- Global: "storage testing"
- Space: "singularity logic"
4. Favorites
Allow users to favorite items from either layer:
- Quick access bar
- Pinned items
- Recent items
📊 Summary
Architecture: ✅ Two-tier navigation (Global + Space)
Benefits: ✅ Clear separation, scalability, better UX
Status: ✅ Implemented and documented
Next: Test and refine
This architecture gives you the best of both worlds! 🎯
Last Updated: October 29, 2025
Status: ✅ IMPLEMENTED
Decision Maker: User + AI Collaboration