Representative Login
Overview Description
The Representative Login feature enables administrators to temporarily assume the identity of a group member for support and troubleshooting purposes. This capability allows administrators to view the application exactly as a specific user would see it, facilitating more effective support and issue resolution. When an administrator uses this feature, they maintain their administrative context while interacting with the system as if they were the selected user.
Activity Diagram
---
config:
theme: base
layout: dagre
flowchart:
curve: linear
htmlLabels: true
themeVariables:
edgeLabelBackground: "transparent"
---
flowchart TB
%% Main components
AdminUser[Admin User]
AdminDashboard[Admin Dashboard]
Database[(Database)]
%% Process steps with numbering
AdminUser --- Step1[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>1</span>
<p style='margin-top: 8px'>Select Group/User</p>
</div>
]
Step1 --> SelectGroup[Select Group/User]
SelectGroup --- Step2[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>2</span>
<p style='margin-top: 8px'>Send Request</p>
</div>
]
Step2 --> SendRequest[Send Representative Login Request]
SendRequest --- Step3[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3</span>
<p style='margin-top: 8px'>Validate Group</p>
</div>
]
Step3 --> GroupIDCheck{Valid Group ID?}
GroupIDCheck -->|No| Step4A[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4A</span>
<p style='margin-top: 8px'>Return Error</p>
</div>
]
Step4A --> ReturnError[Return Error]
GroupIDCheck -->|Yes| Step4B[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4B</span>
<p style='margin-top: 8px'>Check Status</p>
</div>
]
Step4B --> CheckStatus[Check Group Status]
CheckStatus --> Database
CheckStatus --- Step5[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5</span>
<p style='margin-top: 8px'>Verify Active</p>
</div>
]
Step5 --> GroupActiveCheck{Group Active?}
GroupActiveCheck -->|No| Step6A[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6A</span>
<p style='margin-top: 8px'>Return Error</p>
</div>
]
Step6A --> ReturnError
GroupActiveCheck -->|Yes| Step6B[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6B</span>
<p style='margin-top: 8px'>Find Creator</p>
</div>
]
Step6B --> FindCreator[Find Group Creator]
FindCreator --> Database
FindCreator --- Step7[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>7</span>
<p style='margin-top: 8px'>Verify Creator</p>
</div>
]
Step7 --> CreatorCheck{Creator Found?}
CreatorCheck -->|No| Step8A[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>8A</span>
<p style='margin-top: 8px'>Return Error</p>
</div>
]
Step8A --> ReturnError
CreatorCheck -->|Yes| Step8B[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>8B</span>
<p style='margin-top: 8px'>Create Session</p>
</div>
]
Step8B --> CreateSession[Create Representative Session]
CreateSession --- Step9[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>9</span>
<p style='margin-top: 8px'>Set Cookie</p>
</div>
]
Step9 --> SetCookie[Set Representative Cookie]
SetCookie --- Step10[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>10</span>
<p style='margin-top: 8px'>Return Data</p>
</div>
]
Step10 --> ReturnData[Return User Data with Creator Context]
ReturnData --- Step11[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>11</span>
<p style='margin-top: 8px'>View as User</p>
</div>
]
Step11 --> UserView[View Application as User]
UserView --- Step12[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>12</span>
<p style='margin-top: 8px'>Return Check</p>
</div>
]
Step12 --> ReturnCheck{Return to Admin?}
ReturnCheck -->|Yes, ID=0| Step13A[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>13A</span>
<p style='margin-top: 8px'>Clear Session</p>
</div>
]
Step13A --> ClearSession[Clear Representative Session]
ClearSession --- Step14[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>14</span>
<p style='margin-top: 8px'>Return Admin</p>
</div>
]
Step14 --> ReturnAdmin[Return to Admin Context]
ReturnAdmin --- Step15[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>15</span>
<p style='margin-top: 8px'>Return Dashboard</p>
</div>
]
Step15 --> AdminDashboard
ReturnCheck -->|No, Continue| Step13B[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>13B</span>
<p style='margin-top: 8px'>Continue Session</p>
</div>
]
Step13B --> UserView
%% Styling
style AdminUser fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
style AdminDashboard fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
style SelectGroup fill:#f0f8e6,stroke:#339933,stroke-width:2px
style SendRequest fill:#f0f8e6,stroke:#339933,stroke-width:2px
style GroupIDCheck fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
style CheckStatus fill:#f0f8e6,stroke:#339933,stroke-width:2px
style GroupActiveCheck fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
style FindCreator fill:#f0f8e6,stroke:#339933,stroke-width:2px
style CreatorCheck fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
style CreateSession fill:#f0f8e6,stroke:#339933,stroke-width:2px
style SetCookie fill:#f0f8e6,stroke:#339933,stroke-width:2px
style ReturnData fill:#f0f8e6,stroke:#339933,stroke-width:2px
style UserView fill:#f0f8e6,stroke:#339933,stroke-width:2px
style ReturnCheck fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
style ClearSession fill:#f0f8e6,stroke:#339933,stroke-width:2px
style ReturnAdmin fill:#f0f8e6,stroke:#339933,stroke-width:2px
style ReturnError fill:#fcd9d9,stroke:#cc3333,stroke-width:2px
style Database fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
style Step1 fill:transparent,stroke:transparent,stroke-width:1px
style Step2 fill:transparent,stroke:transparent,stroke-width:1px
style Step3 fill:transparent,stroke:transparent,stroke-width:1px
style Step4A fill:transparent,stroke:transparent,stroke-width:1px
style Step4B fill:transparent,stroke:transparent,stroke-width:1px
style Step5 fill:transparent,stroke:transparent,stroke-width:1px
style Step6A fill:transparent,stroke:transparent,stroke-width:1px
style Step6B fill:transparent,stroke:transparent,stroke-width:1px
style Step7 fill:transparent,stroke:transparent,stroke-width:1px
style Step8A fill:transparent,stroke:transparent,stroke-width:1px
style Step8B fill:transparent,stroke:transparent,stroke-width:1px
style Step9 fill:transparent,stroke:transparent,stroke-width:1px
style Step10 fill:transparent,stroke:transparent,stroke-width:1px
style Step11 fill:transparent,stroke:transparent,stroke-width:1px
style Step12 fill:transparent,stroke:transparent,stroke-width:1px
style Step13A fill:transparent,stroke:transparent,stroke-width:1px
style Step13B fill:transparent,stroke:transparent,stroke-width:1px
style Step14 fill:transparent,stroke:transparent,stroke-width:1px
style Step15 fill:transparent,stroke:transparent,stroke-width:1px
API: Representative Login API
Case Documentation
Case 1: Successful Representative Login
Description
Administrator successfully logs in as a representative of a group member.
Sequence Diagram
sequenceDiagram
participant Admin
participant API as RepresentativeLoginController
participant Service as AuthService
participant GroupService
participant DB as Database
Note over Admin,API: Step 1: Submit Representative Request
Admin->>API: PATCH /api/v1/admin/auth/representative/{id}
Note over API,API: Step 2: Verify Admin Authentication
API->>API: Check Admin is Authenticated
Note over API,GroupService: Step 3: Load Group
API->>GroupService: getById(id)
GroupService->>DB: Find Group
DB-->>GroupService: Return Group Data
Note over API,API: Step 4: Check Group Status
API->>API: Verify Group is Active
Note over API,Service: Step 5: Create Representative Session
API->>Service: createRepresentative(group.creator)
Service->>Service: Generate Auth Cookie
Note over API,Admin: Step 6: Return Response
API-->>Admin: 200 OK with creator data and representative cookie
Steps
Step 1: Submit Representative Request
- Description: Admin requests to act as a representative for a group
- Request:
PATCH /api/v1/admin/auth/representative/{id} - URL Parameters:
- id: The ID of the group to represent (required)
- Authentication:
- Admin must be already authenticated
Step 2: Verify Admin Authentication
- Description: System confirms admin is authenticated
- Action:
- Check if user is logged in
- Verify authentication status
- Potential errors:
- Authentication check failure (403 Forbidden)
Step 3: Load Group
- Description: System retrieves the requested group
- Action:
- Call group service to get group by ID
- Load group with creator relationship
- Potential errors:
- Group not found
Step 4: Check Group Status
- Description: Verify group is active and can be represented
- Action:
- Check group status is Active
- Ensure group has creator assigned
- Potential errors:
- Group is inactive (403 Forbidden)
Step 5: Create Representative Session
- Description: Create session for acting as the group creator
- Action:
- Call auth service to create representative session
- Generate authentication cookie for representative context
- Set representative flag to true
Step 6: Return Response
- Description: Send successful response with representative session
- Response:
- Success:
200 OKwith creator user data - Set representative cookie
- Include necessary relationships (roles, group)
- Success:
Database Related Tables & Fields
erDiagram
users {
id bigint "Primary key"
name string "User's full name"
email string "User's email address (unique)"
uid string "Firebase UID (unique)"
payment_provider_customer_id string "Payment provider customer ID (nullable)"
status int "Account status (0: Inactive, 1: Active)"
is_first_login int "First login flag (0: not yet, 1: logged in)"
remember_token string "Remember token"
created_at timestamp "Record creation timestamp"
updated_at timestamp "Record last update timestamp"
deleted_at timestamp "Soft delete timestamp"
}
groups {
id bigint "Primary key"
name string "Group name"
created_by bigint "Reference to users table"
status int "Group status (0: Inactive, 1: Active)"
created_at timestamp "Record creation timestamp"
updated_at timestamp "Record last update timestamp"
}
group_members {
id bigint "Primary key"
user_id bigint "Reference to users table"
group_id bigint "Reference to groups table"
group_role_id bigint "Reference to group_roles table"
is_creator boolean "Is group creator flag"
joined_at timestamp "Member joined timestamp"
created_at timestamp "Record creation timestamp"
updated_at timestamp "Record last update timestamp"
}
group_roles {
id bigint "Primary key"
name string "Role name"
slug string "Role slug"
created_at timestamp "Record creation timestamp"
updated_at timestamp "Record last update timestamp"
}
users ||--o{ group_members : has
groups ||--o{ group_members : has
group_roles ||--o{ group_members : has
Error Handling
-
Log
- Representative login failures logged
- Group status issues recorded
-
Error Detail:
Code Message Description 401 "ログイン情報が正しくありません。" When user is not found in admin role 401 "認証情報と一致するレコードがありません。" When login fails 401 "問題が発生しました。申し訳ございませんが、もう一度お試しください。" When unexpected errors occur
Case 2: Return to Admin Account
Description
Representative admin returns to their original admin account.
Sequence Diagram
sequenceDiagram
participant Admin
participant API as RepresentativeLoginController
participant Auth
participant Cookie
Admin->>API: PATCH /api/v1/admin/auth/representative/0
API->>Auth: Get current user
Auth-->>API: Return admin user
API->>Cookie: forget(representative)
API-->>Admin: 200 OK with admin user data
Steps
Step 1: Submit Return Request
- Description: Admin requests to return to admin account
- Request:
PATCH /api/v1/admin/auth/representative/0 - URL Parameters:
- id: 0 (special value to indicate return to admin)
Step 2: Reset Representative Flag
- Description: System clears representative status
- Action:
- Set representative flag to false
- Use current admin user without changes
Step 3: Clear Representative Cookie
- Description: Remove representative context cookie
- Action:
- Create "forget" cookie for representative cookie
- Set cookie with past expiration
Step 4: Return Response
- Description: Restore admin context
- Response:
- Success:
200 OKwith admin user data - Include cookie clearing instruction
- Success:
Additional Notes
- The representative login feature maintains a clear distinction between the admin's actual identity and the represented user
- The system uses cookies to track the representative state
- When acting as a representative, certain administrative functions may be limited
- Returning to admin mode is a simple process that fully restores admin capabilities
- Only the group creator can be represented, not arbitrary group members