mirror of
https://github.com/chatwoot/chatwoot.git
synced 2026-07-04 21:06:27 +08:00
The system determines a user’s active account by checking the
`active_at` field in the `account_users` table and selecting the most
recently active account:
```ruby
def active_account_user
account_users.order(active_at: :desc)&.first
end
```
This works fine when all accounts have a valid active_at timestamp.
**Problem**
When a user is added to a new account, the `active_at` value is NULL
(because the account has never been explicitly activated). Ordering by
active_at DESC produces inconsistent results across databases, since
handling of NULL values differs (sometimes treated as high, sometimes
low).
As a result:
- Mobile apps (critical impact): `/profile` returns the wrong account.
The UI keeps showing the old account even after switching, and
restarting does not fix it.
- Web app (accidentally works): Appears correct because the active
account is inferred from the browser URL, but the backend API is still
wrong.
**Root Cause**
- The ordering logic did not account for NULL `active_at`.
- New accounts without active_at sometimes get incorrectly prioritized
as the “active” account.
**Solution**
Explicitly ensure that accounts with NULL active_at are sorted after
accounts with real timestamps by using NULLS LAST:
```ruby
def active_account_user
account_users.order(Arel.sql('active_at DESC NULLS LAST, id DESC'))&.first
end
```
- Accounts with actual `active_at` values will always be prioritized.
- New accounts (with NULL active_at) will be placed at the bottom until
the user explicitly activates them.
- Adding id DESC as a secondary ordering ensures consistent tie-breaking
when multiple accounts have the same `active_at`.
|
||
|---|---|---|
| .. | ||
| channel | ||
| concerns | ||
| integrations | ||
| access_token.rb | ||
| account_user.rb | ||
| account.rb | ||
| agent_bot_inbox.rb | ||
| agent_bot.rb | ||
| application_record.rb | ||
| article.rb | ||
| assignment_policy.rb | ||
| attachment.rb | ||
| automation_rule.rb | ||
| campaign.rb | ||
| canned_response.rb | ||
| category.rb | ||
| contact_inbox.rb | ||
| contact.rb | ||
| conversation_participant.rb | ||
| conversation.rb | ||
| csat_survey_response.rb | ||
| custom_attribute_definition.rb | ||
| custom_filter.rb | ||
| dashboard_app.rb | ||
| data_import.rb | ||
| email_template.rb | ||
| folder.rb | ||
| inbox_assignment_policy.rb | ||
| inbox_member.rb | ||
| inbox.rb | ||
| installation_config.rb | ||
| integrations.rb | ||
| jsonb_attributes_length_validator.rb | ||
| kbase.rb | ||
| label.rb | ||
| macro.rb | ||
| mention.rb | ||
| message.rb | ||
| note.rb | ||
| notification_setting.rb | ||
| notification_subscription.rb | ||
| notification.rb | ||
| platform_app_permissible.rb | ||
| platform_app.rb | ||
| portal.rb | ||
| related_category.rb | ||
| reporting_event.rb | ||
| super_admin.rb | ||
| team_member.rb | ||
| team.rb | ||
| telegram_bot.rb | ||
| user.rb | ||
| webhook.rb | ||
| working_hour.rb | ||