Handoff: CreatorTrack Personal Contacts <-> Google Contacts two-way sync¶
For: an Opus remote worker. Repo: ~/creatortrack (~/forge-suite is a symlink to it).
Base: main. This is LARGE: run /feature-plan first, get Justin's spec approval, THEN build.
Work isolation (MANDATORY)¶
git -C ~/creatortrack worktree add ~/creatortrack-wt/contacts-gsync -b feat/contacts-google-sync mainthencp -al ~/creatortrack/node_modules ~/creatortrack-wt/contacts-gsync/node_modules. Worktree dev usesnext dev --webpack. Commit OFTEN; merge to main ONCE (--no-ff).
What/where¶
- App = id "crm" (renamed Personal Contacts this session),
components/apps/crm/. People live in thecrm.peoplesystem collection (lib/system-apps.ts);createPersonself-provisions the app. Fields to map: name, birthday, anniversary, addresses, emails, phones, "how you know them", notes. - Two-way sync (Justin confirmed): import Google Contacts →
crm.people; write app edits back to Google via the People API (people.createContact/people.updateContact). Conflict handling viaupdateTime/etag(last-writer-wins is acceptable v1 if you log skips).
Reuse, do NOT hand-roll (doctrine)¶
- Google OAuth: CT's own GCP project creatortrack-499820
(oauth project).
Publish to Production (Testing = 7d token expiry); ENABLE the People API; add scope
https://www.googleapis.com/auth/contacts. - Account-connection plumbing already exists for Calendar two-way sync
(calendar,
gcal sync handoff):
per-workspace connected Google accounts,
select_account=1add-account flow, token storage/refresh. MIRROR that pattern for contacts; do not build a second OAuth path. See agent integrations HUB. - Auth single-host: Google login only on
app.creatortrack.ai(auth single-host).
Schema + sync¶
- A mapping table linking
crm.peoplerows <-> GoogleresourceName+etagfor idempotent upsert and write-back (never double-create). Migration indb/migrations/*.sql. - Background sync on a systemd timer, cadence like
forge-creatortrack-sales-gmail-sync.timer(every 30 min) orcampaigns-sync. Idempotent (upsert keys). Fail loud + notify on auth/quota errors.
Verify before merge¶
npx tsc --noEmit0 errors; eslint clean. In the dev app: connect a Google account, run an import, confirm contacts land in Personal Contacts; edit a person, confirm it writes back to Google; re-run sync, confirm no duplicates.- Register:
MEMORY.mdindex line +memory/general/reference_creatortrack_contacts_google_sync.md. - Merge to main --no-ff, notify Justin's origin chat.