Work Router - Quick Start Guide
What We Built
A complete Work Router system that creates role-specific workspaces for IntegrateWise users. After onboarding (collecting Role, Department, Industry), users see a customized dashboard tailored to their role.
Key Features
✅ 5-Step Onboarding - Collect user profile info + role selection
✅ 10 Role Views - Founder, Sales Rep, Manager, CS, Marketing, Finance, Ops, Product, Engineering, Admin
✅ Dynamic Routing - Views resolve at runtime based on profile + permissions
✅ Industry Presets - SaaS, Healthcare, Fintech vocab/KPI overrides
✅ Admin Preview - Test any role/dept/industry combo
✅ Zero Disruption - Completely isolated from existing UI
How to Test
1. Start Dev Server
cd /vercel/share/v0-project/apps/web
npm run dev
Server starts at http://localhost:3000
2. Visit Onboarding
http://localhost:3000/onboarding
Complete the 5-step form:
- Step 1: Enter name, email, company name
- Step 2: Select your role (see all 10 roles)
- Step 3: Select your department
- Step 4: Select your industry (SaaS, Healthcare, Fintech)
- Step 5: Review and confirm
Continue button is enabled once each step is valid.
3. Auto-Redirect to Work View
After completing onboarding, you're automatically redirected to:
http://localhost:3000/work
Your personalized workspace displays sections relevant to your role.
4. Preview Different Roles
Edit the demo user in /app/work/page.tsx to test different profiles:
// Change userId to test different profiles
function getDemoUser() {
return {
userId: "user-demo-001", // Change this
tenantId: "saas-demo", // Or change this
};
}
Then refresh to see a different workspace.
File Structure
apps/web/
├── lib/
│ ├── data/ # Data persistence layer
│ │ ├── types.ts # Domain types
│ │ ├── in-memory-provider.ts # InMemory data store + seed
│ │ └── index.ts # Factory function
│ └── work/ # Work router logic
│ ├── router.ts # resolveWorkView + 10 role definitions
│ ├── industry-presets.ts # Vocabulary/KPI overrides
│ └── admin-preview.ts # Admin impersonation mode
├── components/
│ ├── onboarding/ # Onboarding flow
│ │ ├── layout.tsx # Stepper + container
│ │ ├── steps.tsx # 5 step components
│ │ └── onboarding-container.tsx # Form state
│ └── work/ # Work view
│ └── work-view-scaffold.tsx # Shared layout
└── app/
├── onboarding/page.tsx # Route: /onboarding
└── work/page.tsx # Route: /work
Data Flow
User starts at /onboarding
↓
OnboardingContainer collects profile
↓
DataProvider.profiles.create(UserProfile)
↓
Redirect to /work
↓
Load profile from DataProvider
↓
resolveWorkView(context)
↓
Filter sections by role/permissions/capabilities
↓
Display WorkViewScaffold with sections
Customization
Add a New Role View
- Add role to
ROLE_DEFINITIONSinlib/work/router.ts - Define sections, descriptions, icons
- Role automatically appears in onboarding step 2
Change Industry Presets
Edit lib/work/industry-presets.ts:
- Add vocabulary translations
- Change KPI definitions
- Add default filters
Modify Onboarding Steps
Edit step components in components/onboarding/steps.tsx:
- Add/remove fields
- Change validation rules
- Update UI styling
Customize Work View Layout
Edit components/work/work-view-scaffold.tsx:
- Change grid columns
- Add sections header
- Modify card styling
API
getDataProvider()
const provider = getDataProvider();
// Access data
const profile = await provider.profiles.get(userId);
const permissions = await provider.permissions.listAll();
const capabilities = await provider.capabilities.listByTenant(tenantId);
resolveWorkView()
const context: WorkContext = {
profile,
permissions,
installedPlugins: [],
availableCapabilities: [],
environment: "development",
};
const view = await resolveWorkView(context);
// Returns: { role, title, description, sections, capabilities }
Admin Preview
const preview = await createAdminPreviewProfile(
{
role: "founder",
department: "engineering",
industry: "healthcare",
adminUserId: "admin-123",
},
"tenant-123"
);
const view = await resolveWorkView({
profile: preview,
// ... other context
});
Next Steps
- Integrate Descope Auth - Replace mock auth in
/onboarding/page.tsxand/work/page.tsx - Build Real Sections - Create actual components for each section (currently placeholders)
- Connect Platform API - Wire in real capabilities/agents from IntegrateWise registry
- Add Drizzle ORM - Replace InMemoryDataProvider with DrizzleDataProvider for production
- Test Permissions - Add real role-permission mappings and verify gating
- Deploy to Staging - Gather user feedback on role views
Troubleshooting
Onboarding not persisting?
- Check browser console for errors
- Verify DataProvider is initialized
- Make sure onboarding steps are all valid before submit
Work view not loading?
- Check that profile exists in DataProvider
- Verify tenant and role are valid
- Check console for resolveWorkView errors
Missing sections?
- Sections are hidden if you lack permissions
- Check the role definition in
lib/work/router.ts - Admin role shows all sections
Descope Integration (TODO)
Replace mock auth functions with real Descope calls:
// Before (current mock)
function getDemoUser() {
return { userId: "user-demo-001", tenantId: "saas-demo" };
}
// After (Descope)
async function getAuthenticatedUser() {
const user = await getSessionUser();
return {
userId: user.userId,
tenantId: user.tenantId || "default-tenant",
};
}
Then call getAuthenticatedUser() instead of getDemoUser() in pages.
Support
See WORK_ROUTER_IMPLEMENTATION.md for full technical documentation.