Documentation Index
Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
Use this file to discover all available pages before exploring further.
Version: 1.2.0
Last Updated: 2026-02-09
Status: Active
Changelog:
- 1.2.0 (2026-02-09): Added normative section “Tabbed Sub-Modules (Single Route + In-Page Tabs)” (§2) and “Hub and Tab UX” (§2a) with rules for sidebar behavior, breadcrumbs, quick actions, deep-link persistence, mobile tab bars, and accessibility for tabbed hubs. See §2 and §2a for details.
Navigation Documentation Index: For an overview of all navigation documentation, see NAVIGATION_GUIDE_INDEX.md
Quick Reference: For implementation tasks and quick lookup, see navigation-quick-reference.md
Table of Contents
- Module Navigation Standards
- Improvement History
- Implementation Guidelines
- Related Documentation
1. Module Navigation Standards
This section defines the standard navigation patterns for all domain cores (hr, rh, fa, fw, fm, gr, lo) using Platform Navigation (PF).
System Overview
This platform uses a centralized registry + platform navigation renderer:
- Module + sidebar structure (source of truth):
src/platform/modules/module-registry.ts
- Defines modules, top-level nav, grouped nav, and “sub-modules” (mini-apps).
- Desktop primary navigation is user-selectable: Dock (macOS-style), Sidebar (accordion + drill-down), or Taskbar (Windows-style); state and sidebar open/collapse are persisted via
NavModeContext.
- Route components (actual pages):
src/App.tsx
- Route components must be lazy-loaded.
- Breadcrumb labels:
src/platform/navigation/route-labels.ts
- Central map used by desktop + mobile breadcrumbs.
- Mobile shortcuts catalog:
src/platform/navigation/mobile-nav-config.ts
- Defines which shortcuts can be pinned to the bottom bar / quick access.
- Permission filtering:
src/platform/navigation/hooks/useNavItemPermission.ts
- Uses PF-30 permissions when enabled, falls back to
minRole.
- Route integrity tests:
tests/integration/route-integrity.test.ts
- Validates route consistency across registry, labels, and app routes.
Standard Definitions
Module
A “module” is a top-level domain core accessible via module switching (e.g., HR, Finance).
Required fields (standard):
id: hr | rh | fa | fw | fm | gr | lo
route: default landing route (usually /{core}/dashboard)
settingsRoute: /{core}/settings when applicable
minRole + optional permission for PF-30
Nav Items (Top-Level)
Top-level items are module-wide anchors and should be small in number:
- Overview / Dashboard (always)
- Forms (only if the module has module-scoped forms)
- Settings (admin-only)
Nav Groups (Section Navigation)
Groups represent the module’s information architecture. Keep them meaningful and bounded (4–8 groups).
Group fields:
id, label, icon
defaultOpen (only for 1–2 groups)
overviewRoute (optional but recommended for groups that act like “sections”)
minRole / permission (optional, for gating entire groups)
Sub-Modules (Mini-Apps)
A group may be a “sub-module” if it qualifies as a mini-application.
Sub-module rule (recommended): set isSubModule: true only if all are true:
- Has a stable route prefix
/{core}/{sub}/*
- Has its own “overview” route (e.g.,
/{core}/{sub}/dashboard)
- Has at least ~5 dedicated routes/pages
- Has its own quick actions that are meaningful within that context
- Users will benefit from “in-sub-module” sidebar mode
Route Conventions
These conventions ensure modules feel consistent.
- Module landing:
/{core}/dashboard
- Module root:
/{core} may exist but should redirect to landing (or be a label-only breadcrumb root)
- Settings:
/{core}/settings
- Forms:
/{core}/forms (only if module-scoped)
- Sub-modules:
/{core}/{sub}/... (stable {sub} tokens)
- Create:
.../new
- Edit:
.../:id/edit (preferred) or .../:id + edit mode, but be consistent within a module
Platform-level routes:
/forms → Platform admin forms view (alias for /fw/forms)
/picklists → Platform picklist management (PF-15)
/settings → Platform settings
Permissions + Visibility Contract (PF-30)
Navigation visibility must be deterministic and aligned with authorization.
Standard gating rule:
- If PF-30 V2 is enabled and an item has
permission, visibility is controlled by permission.
- Otherwise, visibility falls back to
minRole when present.
- If neither is present, item is visible by default.
Recommendation: permission key coverage
- Use
permission for: admin/settings routes, approval flows, anything that mutates critical data (manage, approve, admin)
- Use
minRole primarily as a fallback for: coarse “admin-only” visibility when V2 is not enabled
Breadcrumb Contract
Breadcrumb labels are part of the user’s navigation comprehension and must not drift.
What must have labels (recommended minimum):
For each core:
/{core} (module root label)
/{core}/dashboard (landing)
- every route referenced by
MODULE_REGISTRY.navItems[*].route
- every route referenced by
MODULE_REGISTRY.navGroups[*].items[*].route
- every sub-module
overviewRoute
Dynamic routes:
For .../:id style routes:
- rely on common segment labels (
details, edit) where possible, OR
- add explicit labels for the static parent route(s), and consider page-level breadcrumbs for entity names when needed
Mobile Shortcuts Contract
Mobile shortcuts are curated entry points, not a second navigation system.
Recommendations:
- Shortcuts should point to stable routes (dashboards, main lists, key workflows).
- Shortcut gating (
minRole / permission) should not contradict the module registry’s gating.
- Sub-module shortcuts should only exist if the sub-module qualifies under the rule above.
Policy Decisions
1. Sub-Module Qualification Criteria
A nav group qualifies as a sub-module (with isSubModule: true) when it meets ALL of the following criteria:
| Criterion | Requirement | Rationale |
|---|
| Route count | 5+ distinct routes under a stable prefix | Justifies separate treatment |
| Own overview | Has dedicated overview/dashboard route | Entry point for users |
| Stable prefix | Routes share a consistent path prefix (e.g., /hr/ats/*) | Clear boundary |
| Quick actions | Has at least 2 meaningful quick actions | Sufficient utility |
2. Tabbed Sub-Modules (Single Route + In-Page Tabs)
When a sub-module uses a single overview route with in-page tabs (e.g. ?tab=) for 4–8 sections that share the same context and permission:
- Sidebar: Do not list those tab targets as separate nav items. Show one entry for the hub (Overview link to the overview route) and any separate routes (e.g. Onboarding, Offboarding) as additional items.
- Overview route is the canonical entry; tab state is encoded in the query string for shareability (e.g.
/hr/ats?tab=applications).
- Quick actions may still link to specific tabs (e.g. “Job Postings” →
/hr/ats?tab=postings) for power users.
When to use tabs vs sidebar-only:
| Use case | Prefer |
|---|
| 4–8 sections, same workflow/context | One route + in-page tabs |
| Different permissions per section | Sidebar (separate routes) |
| Many sections (>8) | Sidebar or grouped tabs |
| Deep drill-down (detail pages) | Keep as routes; tabs for list views |
Reference: HR Navigation UX Review (not yet authored).
2a. Hub and Tab UX (Tabbed Sub-Modules)
When a sub-module uses a tabbed hub (single overview route + ?tab=), the following rules apply:
Breadcrumbs for tabbed hubs: When the current route is a hub overview (e.g. /hr/credentialing, /hr/ats) and ?tab= is present, the breadcrumb trail MUST include the active tab as the final segment (e.g. “Credentialing > Renewals”) so orientation matches the URL. Implemented in src/platform/navigation/Breadcrumbs.tsx and src/platform/navigation/MobileBreadcrumbs.tsx by reading location.search and a shared tab-label map (e.g. HUB_TAB_LABELS in hub-tab-labels.ts).
Quick actions vs hub tabs: If a sub-module uses a tabbed hub, quick actions that only open a tab (e.g. “My Credentials”, “Credentialing Report”) SHOULD either: (a) use explicit copy (e.g. “Open Report tab”) and link to ?tab=..., or (b) be removed from the card and rely on hub tabs. Prefer (a) for power users; avoid duplicate links without clarity.
Deep-link persistence: Hub pages MUST initialize tab state from the URL (?tab=) on mount (e.g. via useQueryState). No client-only state for the active tab so that refresh and post-login redirect preserve the tab.
Mobile tab bars: Tab bars in hubs MUST use touch targets of at least 44px height (see src/shared/ui/tabs.tsx); MUST wrap or scroll horizontally on narrow viewports; the active tab SHOULD remain visible (e.g. scroll-into-view). Minimum tested viewport for hub tabs: 390px width.
Accessibility for tabbed hubs: Tab panels MUST have correct ARIA (e.g. aria-labelledby linking to the trigger, role="tabpanel"). Focus MUST move to the active panel on tab change when appropriate. Keyboard navigation (arrow keys) MUST work per Radix/shadcn. See UI/UX Standards for a11y and the tabbed hub accessibility checklist.
3. Breadcrumb Label Coverage
100% coverage is required for all routes that appear in:
navItems array
navGroups[].items array
- Routes reachable from module navigation
Enforcement:
- Phase 1: 80% coverage threshold (warning)
- Phase 2: 90% coverage threshold (warning)
- Phase 3: 100% coverage threshold (error, blocks merge)
4. Shortcut Gating Alignment
Mobile shortcuts must never expose modules or features that the user cannot access.
Implementation Rules:
minRole on shortcut must be ≥ module’s minRole
permission field must match V2 permission key
- Sub-module shortcuts inherit parent module restrictions
5. Route Naming Conventions
Standard Patterns:
- Module root:
/{core}/dashboard (preferred) or /{core} (redirect only)
- Settings:
/{core}/settings
- Forms:
/{core}/forms (module-owned forms)
- Entity list:
/{core}/{entity-plural}
- Entity new:
/{core}/{entity-plural}/new
- Entity detail:
/{core}/{entity-plural}/:id
- Entity edit:
/{core}/{entity-plural}/:id/edit
6. NavGroup Guidelines
Required Limits (Enforced):
- navGroups per module: 4-8 groups (modules exceeding 8 must consolidate)
- Items per navGroup: 3-7 items (single-item groups must be merged)
- navItems (root level): 3-5 items
Consolidation Rules:
- Single-item groups: MUST be merged with related groups
- 2-item groups: SHOULD be merged unless functionally distinct
- Groups exceeding 8 items: SHOULD be split or promoted to sub-module
Naming Conventions:
- Use noun-phrase style (e.g., “Accounts Receivable”, not “Managing Receivables”)
- Use ”&” for combined groups (e.g., “Banking & Treasury”, “Compliance & Accreditations”)
- Avoid verb-first patterns (e.g., “Close Management” → “Period Close”)
Required navItems: Every module SHOULD have:
- Overview →
/{core}/dashboard
- Forms →
/{core}/forms
- Settings →
/{core}/settings (with minRole: "org_admin")
Icon Consistency Guidelines
Icons are a critical visual element in navigation that help users quickly identify and distinguish features. Consistent icon usage improves usability and reduces cognitive load.
📚 Complete Reference: For comprehensive icon usage rules, decision trees, and anti-patterns, see:
Icon Usage Guide
Quick Reference
Universal Icons (DO NOT CHANGE):
| Icon | Meaning | Usage |
|---|
LayoutDashboard | Overview/Dashboard | Module landing pages |
Settings | Settings/Configuration | Module settings |
FileText | Forms/Documents | Forms, documents |
BarChart3 | Reports/Analytics | Reports pages |
Users | People List | Employee lists |
UsersRound | Teams/Groups | Team pages |
Plus | Create/New | Quick actions |
Calendar | Date-related | Scheduling, calendars |
Clock | Time-related | Time tracking, history |
Alert & Status Icons (Differentiate by context):
| Icon | Meaning | Use For |
|---|
CircleAlert | Issues/Problems | Issues list, workflow alerts, findings, budget alerts |
ShieldAlert | Risk/Security Risk | Risk registers, security risks, safety compliance |
Siren | Incidents/Emergency | Incidents, emergencies, employee relations |
AlertOctagon | Serious/Disciplinary | PIPs, disciplinary actions |
Flag | Events/Flags | Significant events |
Bug | Vulnerabilities | Security vulnerabilities |
Icon Selection Rules
- Semantic Meaning: Icons should semantically represent the feature or action
- Visual Distinction: Icons should be visually distinct from other icons in the same navigation group
- Consistency Across Modules: Similar features across modules should use similar icons
Anti-Patterns
- ❌ Do NOT use
AlertTriangle for everything (issues, incidents, PIPs, risk)
- ❌ Do NOT use the same icon for 5+ different concepts
- ❌ Do NOT use icons without labels in navigation
- ❌ Do NOT create custom icons (use lucide-react only)
- ✅ DO check the Icon Usage Guide before adding new icons
Icon Audit Checklist
When adding or modifying navigation items:
Step-by-Step Standardization Plan
This is the rollout sequence to align modules to the HR-derived standard.
Step 0: Choose the baseline policy decisions (one-time)
Make and record decisions for:
- sub-module criteria (use rule above as default)
- breadcrumb label enforcement level (recommended: 100% for main nav routes)
- how shortcut gating must align with module gating
- route naming conventions (module-wide taxonomy)
Step 1: Inventory current module routes
For the module being aligned:
- list all
/{core}/* routes from src/App.tsx
- group them into 4–8 navigation groups
- identify any “legacy”/duplicate route families to deprecate
Output: a one-page IA map (groups → routes)
Step 2: Normalize the module’s route taxonomy (no new features)
- rename routes only if needed to match conventions
- ensure sub-module prefixes are stable if sub-modules exist
Output: a stable route taxonomy for the module
Step 3: Update module registry definition
In src/platform/modules/module-registry.ts:
- ensure module
route is correct
- define top-level
navItems (small + consistent)
- define
navGroups from the IA map
- mark sub-modules only when the criteria is met
- add
settingsRoute when applicable
- add/confirm
minRole and permission values
Output: registry entry matches the intended IA and access rules
Step 4: Align breadcrumbs
In src/platform/navigation/route-labels.ts:
- add missing labels for all main nav routes
- remove stale labels for routes that no longer exist (or rename them)
Output: breadcrumb contract matches registry + routes
Step 5: Align mobile shortcuts (optional, based on usage)
In src/platform/navigation/mobile-nav-config.ts:
- add module/sub-module shortcuts only if they are high-traffic or high-value
- ensure gating matches the registry contract
Output: mobile shortcuts are curated and consistent
Step 6: Add/strengthen guardrails
Update or extend tests/integration/route-integrity.test.ts policies (as decided in Step 0):
- enforce label coverage targets for
navItems and navGroups.items
- (optional) validate registry routes exist in the app route table
- CRITICAL: Update
KNOWN_ROUTES constant when adding new routes to ensure test coverage
Output: future drift is caught early
Step 7: Rollout sequencing
Recommended order:
- Pilot one module closest to HR structure (often
fa or rh)
- Apply to remaining modules one-by-one
- Final pass: ensure module switcher, breadcrumbs, and mobile all match the same contract
Backlog — Future hub consistency: When refactoring other HR sub-modules (Time, Payroll, Employee Relations, Talent Development) or similar multi-section areas in other cores, apply the same hub pattern (single overview route + ?tab=), redirect legacy paths to ?tab=..., and follow the hub UX rules in §2a (breadcrumbs, quick actions, empty states, a11y, mobile).
2. Improvement History
Consolidation History (2026-01-27)
Navigation consolidation project aligned all modules to standard group limits (4-8 groups per module).
Phase Summary:
- Phase 1 (Quick Wins): Merged FM Vendors → Operations, CE Contacts + Leads → Contacts & Leads
- Phase 2 (FA Consolidation): Merged Collections → AR, Bank Recon + Treasury → Banking & Treasury
- Phase 3 (GR Cleanup): Merged Accreditations → Compliance & Accreditations
- Phase 4 (Documentation): Created navigation audit checklist (live stub: reviews/NAVIGATION_AUDIT.md; detailed historical tables archived under docs/archive/architecture/NAVIGATION_AUDIT_CHECKLIST_full_2026-01-27.md), updated standards
Consolidation Examples:
| Module | Before | After | Action Taken |
|---|
| FM | 5 groups (1 single-item) | 4 groups | Merged “Vendors” (1) into “Operations” (5) |
| CE | 6 groups (2x 2-item) | 4 groups | Merged “Contacts” + “Leads” → “Contacts & Leads” (4) |
| FA | 12 groups | 10 groups | Merged “Collections” (2) → “Accounts Receivable” (8); “Bank Recon” (3) + “Treasury” (4) → “Banking & Treasury” (7) |
| GR | 7 groups (1x 2-item) | 6 groups | Merged “Accreditations” (2) → “Compliance & Accreditations” (7) |
Current Module Status:
| Module | Groups | Status |
|---|
| FW | 4 | ✅ Good |
| RH | 7 | ✅ Good |
| FA | 10 | ⚠️ Target 8 (create Reports sub-module) |
| HR | 11 | ⚠️ Acceptable (8 sub-modules) |
| LO | 3 | ✅ Good |
| FM | 4 | ✅ Good |
| GR | 6 | ✅ Good |
| IT | 8 | ✅ At limit |
| CE | 4 | ✅ Good |
Standardization History (2025-12-21)
The Module Navigation Standardization project aligned all 7 core modules (HR, RH, FA, FM, LO, GR, FW) to a consistent navigation pattern derived from HR as the reference implementation.
Phase Summary:
- Phase 0: Policy & Documentation ✅ Complete
- Phase 1: Pilot & Infrastructure (FA) ✅ Complete
- Phase 2: Core Module Alignment (RH, FM, LO) ✅ Complete
- Phase 3: Complex Module Alignment (HR, GR) ✅ Complete
- Phase 4: Mobile Shortcuts & Permissions ✅ Complete
- Phase 5: Final Polish & 100% Enforcement ✅ Complete
Key Deliverables:
- All modules aligned to standard navigation pattern
- 100% breadcrumb label coverage for registry routes
- Route integrity tests enforce 100% coverage threshold
- Mobile shortcuts configured with permission keys
Current Improvement Recommendations
As modules grow larger and more nested, the current flat navigation structure becomes overwhelming. Recommendations include implementing a hierarchical navigation system with overview pages and adaptive sidebars for larger sub-modules, covering both desktop and mobile experiences.
Key Goals:
- Reduce cognitive load through progressive disclosure
- Improve discoverability of features within large modules
- Maintain mobile-first design principles
- Integrate with permission system for access control
- Align with constitution standards for performance and accessibility
Key Findings:
- Desktop sidebar module flyouts can be overwhelming for large modules (HR has 7 navGroups)
- Mobile sheet structure is good but could better surface sub-areas
- Overview pages not consistently linked in navigation
- Large modules (HR) need sub-area overview pages with dedicated navigation
- Collapsible sections needed in flyouts for better scanning (modules with 5+ navGroups)
Status: Planning (Phase 1 Partially Implemented)
For detailed improvement recommendations and implementation guidance, see:
- Navigation Improvements:
docs/architecture/NAVIGATION_IMPROVEMENTS.md - Comprehensive recommendations for hierarchical navigation, mobile integration, and UX enhancements
- Implementation Plan:
docs/NAVIGATION_IMPROVEMENT_PLAN.md - Detailed step-by-step implementation plan
3. Implementation Guidelines
Standardization Checklist
When aligning a module to the navigation standard:
Common Patterns
Module Definition Template
{
id: '{core}',
name: '{Module Name}',
route: '/{core}/dashboard',
settingsRoute: '/{core}/settings',
icon: ModuleIcon,
minRole: 'staff',
permission: '{core}.view', // Optional, PF-30 V2
navItems: [
{
label: 'Overview',
route: '/{core}/dashboard',
icon: LayoutDashboard,
},
{
label: 'Forms',
route: '/{core}/forms',
icon: FileText,
permission: 'fw.forms.view', // Module-scoped forms
},
{
label: 'Settings',
route: '/{core}/settings',
icon: Settings,
minRole: 'org_admin',
},
],
navGroups: [
{
id: '{group-id}',
label: '{Group Label}',
icon: GroupIcon,
defaultOpen: false,
overviewRoute: '/{core}/{group}/dashboard', // Optional
isSubModule: false, // Only if meets criteria
items: [
{
label: '{Item Label}',
route: '/{core}/{group}/{item}',
icon: ItemIcon,
permission: '{core}.{entity}.view', // PF-30 V2
},
],
},
],
}
Sub-Module Definition Template
{
id: '{sub-module-id}',
label: '{Sub-Module Name}',
icon: SubModuleIcon,
defaultOpen: false,
overviewRoute: '/{core}/{sub}/dashboard', // Required for sub-modules
isSubModule: true, // Must meet all criteria
quickActions: [ // Required for sub-modules
{
label: '{Action Label}',
route: '/{core}/{sub}/{action}',
icon: ActionIcon,
permission: '{core}.{sub}.{action}',
},
],
items: [
// 5+ routes required
],
}
Anti-Patterns
❌ Don’t:
- Create sub-modules for groups with < 5 routes
- Use inconsistent route naming within a module
- Skip breadcrumb labels for main nav routes
- Create mobile shortcuts that contradict module permissions
- Add routes to registry without updating
KNOWN_ROUTES in tests
✅ Do:
- Follow route naming conventions consistently
- Ensure 100% breadcrumb label coverage
- Use PF-30 permission keys when available
- Test navigation on both desktop and mobile
- Update route integrity tests with new routes
Architecture Standards
Development Guides
Core References
- Platform navigation docs:
src/platform/navigation/README.md
- Permissions (PF-30) patterns:
src/platform/permissions/*
- Route integrity test:
tests/integration/route-integrity.test.ts
- Constitution breadcrumb standards:
constitution.md §6.3.1
Implementation Guides
- Navigation Improvements:
docs/architecture/NAVIGATION_IMPROVEMENTS.md - Comprehensive recommendations
- Implementation Plan:
docs/NAVIGATION_IMPROVEMENT_PLAN.md - Detailed step-by-step plan
Implementation Files (Source of Truth)
- Module Permissions Matrix:
docs/module-permissions-matrix.md - Granular permissions
- Picklist system (PF-15):
specs/pf/PF-15-picklist-system.md
Changelog
| Version | Date | Changes |
|---|
| 1.2.0 | 2026-01-27 | Added consolidation history (Phases 1-4); enhanced NavGroup guidelines with enforcement rules; added naming conventions; linked NAVIGATION_AUDIT.md |
| 1.1.0 | 2026-01-12 | Enhanced icon section with quick reference tables; added link to Icon Usage Guide; updated related documentation links |
| 1.0.0 | 2025-01-25 | Initial version with complete navigation standardization |
Status: Active Documentation