Add an account key field to improve search performance. This field
allows us to filter the records by account directly in the fulltext
index, so we only need to examine rows belonging to the relevant account.
The check-then-act pattern in `register_activity_spike` has been
replaced with `find_or_create_by!` to eliminate the race condition
that could lead to creating multiple activity spikes for a card. To
support this change, the `card_id` index on `cards_activity_spikes`
has been made unique.
ref: https://app.fizzy.do/5986089/cards/3063
We've seen some cases of deadlock when processing notifications, because
locks are gathered on the users in different orders. Let's try sticking
to a consistent order instead, which should cause the jobs to serialize
rather than deadlock.
We set the order in the dedicated column controllers and we don't want this in place when using composable filters.
Also, this raises an error with the MySQL move when combined with assignees. Because we inject a .distinct there,
that messes up with the query select, resulting in having to add a redundant select to the closed sorting scope, so that
the closure.created_at is not lost.
Primarily this is in tests (which were caught by temporarily
introducing acts_as_tenant and enabling safety checks), but notably
action cable connections were not working properly, and that's now
fixed.
Lean on ActiveRecord models for searching and strip out the raw SQL.
Replaces the search_index_* tables with sharded search_records_* tables
as that allows us to use a Search::Record model name.
A Class is dynamically created for each record table shard so that we
and we can access it via the Search::Record.for_account(account_id)
method.
Schema:
- add account_id to tables it was missing from
- make account_id a required column everywhere
- add [account_id] indexes, or add `account_id` to existing indices
Models:
- add `belongs_to :account` to all models (default to using a domain
model's account whenever possible)
- add account_id in all the necessary fixtures
- add account_id to insert_all hashes
- pass account_id to a few initialize calls
Miscellaneous:
- update the import script to set account_id
Note that I'm not adding account_id to the join tables primarily
because I couldn't think of an easy way to populate it without making
it a full Join model, and that was more work than I have time to take
on right now.