Instead of trying to keep track of changes as we go and hope that lines
up with reality, now we just write all of our changes and do another
diff at the end to build our insert/delete set. Nice and simple.
It's possible that we could match a local contact that doesn't have a
storageId, which would crash when we tried to make a model from it for
merging. This isn't an impossible case -- it could be that the manifest
has record of a user that is newly registered (or just registered at
some point and never deleted) and so we need to give our local record a
storageId for merging.
We were only reading it once, possibly before the flags were
initialized. This lets us be more responsive to the flag changing within
an application cycle.
TBH this shouldn't affect external users. I believe this bad data was
only experienced internally a long time ago. But we want to make sure we
don't continue to sync that bad data, so we're just stripping the
storageID's from it.
1. I screwed up the comparators in the record processor. Pretty bad, glad this was caught.
2. Previously I was sort of keeping track of which local-only records were accounted for while I was merging, and then hoping everything worked out in the end. Now I just very directly take some set differences and retrieve the appropriate records, so it's clear that we should never fail certain validations.
3. Rev's the feature flag so we don't turn on something broken.
Previously, we would do a full directory/CDS refresh in response to any
change in system contacts. That can be expensive.
This changes the behavior to look at how many new contacts there after
being notified of a contact change.
- If there aren't any, we just sync names and stuff.
- If we just have a few new contacts, we'll sync just those specifically.
- If we have a lot, we'll do a full sync.