4.1 KiB
Dealer User Architecture
Overview
Dealers and regular users are stored in the SAME users table. This is the correct approach because dealers ARE users in the system - they login via SSO, participate in workflows, receive notifications, etc.
Why Single Table?
✅ Advantages:
- Unified Authentication: Dealers login via the same Okta SSO as regular users
- Shared Functionality: Dealers need all user features (notifications, workflow participation, etc.)
- Simpler Architecture: No need for joins or complex queries
- Data Consistency: Single source of truth for all users
- Workflow Integration: Dealers can be approvers, participants, or action takers seamlessly
❌ Why NOT Separate Table:
- Would require complex joins for every query
- Data duplication (email, name, etc. in both tables)
- Dealers still need user authentication and permissions
- More complex to maintain
How Dealers Are Identified
Dealers are identified using three criteria (any one matches):
-
employeeIdfield starts with'RE-'(e.g.,RE-MH-001,RE-DL-002)- This is the primary identifier for dealers
- Dealer code is stored in
employeeIdfield
-
designationcontains'dealer'(case-insensitive)- Example:
"Dealer","Senior Dealer", etc.
- Example:
-
departmentcontains'dealer'(case-insensitive)- Example:
"Dealer Operations","Dealer Management", etc.
- Example:
Database Schema
users {
user_id UUID PK
email VARCHAR(255) UNIQUE
okta_sub VARCHAR(100) UNIQUE -- From Okta SSO
employee_id VARCHAR(50) -- For dealers: stores dealer code (RE-MH-001)
display_name VARCHAR(255)
designation VARCHAR(255) -- For dealers: "Dealer"
department VARCHAR(255) -- For dealers: "Dealer Operations"
role ENUM('USER', 'MANAGEMENT', 'ADMIN')
is_active BOOLEAN
-- ... other user fields
}
Example Data
Regular User:
{
"userId": "uuid-1",
"email": "john.doe@royalenfield.com",
"employeeId": "E12345", // Regular employee ID
"designation": "Software Engineer",
"department": "IT",
"role": "USER"
}
Dealer User:
{
"userId": "uuid-2",
"email": "test.2@royalenfield.com",
"employeeId": "RE-MH-001", // Dealer code stored here
"designation": "Dealer",
"department": "Dealer Operations",
"role": "USER"
}
Querying Dealers
The dealer.service.ts uses these filters to find dealers:
User.findAll({
where: {
[Op.or]: [
{ designation: { [Op.iLike]: '%dealer%' } },
{ employeeId: { [Op.like]: 'RE-%' } },
{ department: { [Op.iLike]: '%dealer%' } },
],
isActive: true,
}
});
Seed Script Behavior
When running npm run seed:dealers:
-
If user exists (from Okta SSO):
- ✅ Preserves
oktaSub(real Okta subject ID) - ✅ Preserves
role(from Okta) - ✅ Updates
employeeIdwith dealer code - ✅ Updates
designationto "Dealer" (if not already) - ✅ Updates
departmentto "Dealer Operations" (if not already)
- ✅ Preserves
-
If user doesn't exist:
- Creates placeholder user
- Sets
oktaSubtodealer-{code}-pending-sso - When dealer logs in via SSO,
oktaSubgets updated automatically
Workflow Integration
Dealers participate in workflows just like regular users:
- As Approvers: In Steps 1 & 5 of claim management workflow
- As Participants: Can be added to any workflow
- As Action Takers: Can submit proposals, completion documents, etc.
The system identifies them as dealers by checking employeeId starting with 'RE-' or designation containing 'dealer'.
API Endpoints
GET /api/v1/dealers- Get all dealers (filters users table)GET /api/v1/dealers/code/:dealerCode- Get dealer by codeGET /api/v1/dealers/email/:email- Get dealer by emailGET /api/v1/dealers/search?q=term- Search dealers
All endpoints query the same users table with dealer-specific filters.
Conclusion
✅ Single users table is the correct approach. No separate dealer table needed. Dealers are users with special identification markers (dealer code in employeeId, dealer designation, etc.).