I find actual lock on edit or last-save-wins to work best of what I have seen for structured data. You can add nice visual tools that show who is editing (so you can wait for them) and pass the object lock to someone else etc, but this way at least there is no merge mechanism (that generally knows very little about the ins/outs of the data) which will merge two semantically incompatible fields into one record.
For offline-first, the user would be alerted that someone changed the record(s) while you changed them as well and ask what to do. In attempts to make these things for an offline first healthcare app which is mostly structured records based, I found that it is very rare for 2 (or more) to work on the same data, but I guess it really depends on the use case and with unstructured data it's not a nice way of working.