Re_Backend/docs/DEALER_USER_ARCHITECTURE.md

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:

  1. Unified Authentication: Dealers login via the same Okta SSO as regular users
  2. Shared Functionality: Dealers need all user features (notifications, workflow participation, etc.)
  3. Simpler Architecture: No need for joins or complex queries
  4. Data Consistency: Single source of truth for all users
  5. 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):

  1. employeeId field starts with 'RE-' (e.g., RE-MH-001, RE-DL-002)

    • This is the primary identifier for dealers
    • Dealer code is stored in employeeId field
  2. designation contains 'dealer' (case-insensitive)

    • Example: "Dealer", "Senior Dealer", etc.
  3. department contains 'dealer' (case-insensitive)

    • Example: "Dealer Operations", "Dealer Management", etc.

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:

  1. If user exists (from Okta SSO):

    • Preserves oktaSub (real Okta subject ID)
    • Preserves role (from Okta)
    • Updates employeeId with dealer code
    • Updates designation to "Dealer" (if not already)
    • Updates department to "Dealer Operations" (if not already)
  2. If user doesn't exist:

    • Creates placeholder user
    • Sets oktaSub to dealer-{code}-pending-sso
    • When dealer logs in via SSO, oktaSub gets 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 code
  • GET /api/v1/dealers/email/:email - Get dealer by email
  • GET /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.).