Add two-way contacts sync (Apple Contacts, HubSpot, Folk) - #2
Draft
davidrose wants to merge 1 commit into
Draft
Conversation
Normalized contact model, email-based identity matching, field-level last-write-wins merge with multi-value union, convergent two-way engine, SQLite state store, and a status/sync CLI. Provider adapters for HubSpot (CRM v3), Folk, and Apple Contacts via iCloud CardDAV. 13 tests passing (models, matching, full sync round-trip via in-memory provider). https://claude.ai/code/session_011tTG82Uxsg2nfE8yxsXfR7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
A new
contacts-sync/project that keeps the same contact consistent across Apple Contacts (iCloud), HubSpot, and Folk — two-way, with de-duplication and conflict resolution.This was built fresh: no prior sync code was present in this repo or reachable from the session, so this establishes the foundation. If existing local code turns up, we can reconcile against it.
How it works
Convergent by design: a second run with no external edits is a no-op.
--dry-runprints the plan without writing.Layout
contacts_sync/models.py— normalized contact model, normalization, field-level mergecontacts_sync/matching.py— union-find clustering over emailscontacts_sync/engine.py— two-way orchestration + last-write-wins conflict resolutioncontacts_sync/state.py— SQLite state storecontacts_sync/providers/— HubSpot (CRM v3), Folk, Apple/iCloud CardDAV adapterscontacts_sync/cli.py—status/sync/--dry-runtests/— pure-logic + full round-trip tests via an in-memory providerVerification
pytest): normalization, email clustering, prior-link merge, two-way merge, last-write-wins on conflicting fields, no-duplicate merge-by-email, convergence, dry-run-writes-nothing.statussmoke-tested.Status / not-yet-done (intentional — flag before adding)
Open questions
https://claude.ai/code/session_011tTG82Uxsg2nfE8yxsXfR7
Generated by Claude Code