Skip to content

Unify connection acceptance synchronization - #3

Closed
TheGuyWithoutH wants to merge 2 commits into
mainfrom
codex/connection-acceptance-sync
Closed

TheGuyWithoutH wants to merge 2 commits into
mainfrom
codex/connection-acceptance-sync

Conversation

@TheGuyWithoutH

@TheGuyWithoutH TheGuyWithoutH commented Sep 20, 2026

Copy link
Copy Markdown

Integrated into Pilae/main through PR #7, which resolves the overlap with #2 while preserving localized connection counts. This PR is closed as superseded. Its source branch remains unchanged for upstream PR #19.

Summary

Makes manual and scheduled connection checks use the same positive evidence: the person must appear in the selected account's LinkedIn connections list before Linki marks them as connected.

What it fixes

  • False acceptances from the manual check: an invitation disappearing from the pending list was treated as accepted, even if it had expired or been withdrawn. Absence now leaves the contact unchanged.
  • Missed connections on later pages: the scheduled detector could stop at an older connection date before reaching a matching profile. It now scans without assuming that pages are globally sorted by date.
  • Matching outside the selected account's enrollments: candidates are selected through that account's campaign runs instead of searching all requested contacts. Profile matching handles case, trailing slashes, and query parameters.
  • Misleading success after an incomplete check: API failures and the page limit now raise an error without advancing the successful-sync timestamp. The manual endpoint returns HTTP 502 with retry guidance.

For example: Alice's invitation expires and disappears from the pending list. Previously, a manual check could mark her as connected. Now she remains unconfirmed. If Bob appears on a later page of the actual connections list, Linki can find him and record LinkedIn's connection date.

How it works

The manual endpoint delegates to the detector already called by the scheduled runner. It matches connections to enrolled targets by normalized LinkedIn profile identifier and stores positive matches as they are found.

Newly recorded connection dates come from LinkedIn; existing dates are preserved. Scanning stops when all candidate targets are already marked connected or have been found, when the returned list ends, or with an error at the 60-page limit. Positive matches saved before a later failure remain saved.

Scope and limits

  • The normal 8-hour interval and runner scheduling conditions are unchanged. Automatic checks still require an authenticated account with a running campaign; this does not add independent background polling.
  • Missing profiles are neither marked accepted nor cleared as disconnected. The previous full-pass cleanup is removed, so existing incorrect connection flags are not automatically repaired.
  • A historical connection proves connection state, not that the current campaign caused an acceptance. Campaign attribution is handled separately in PR #4.
  • Connection fields remain stored on shared target records; this does not introduce account-specific relationship storage.
  • The manual success response now contains newly_accepted and source: "connections-list"; the previous pending-count and accepted-name fields are removed.
  • Pending follow-up: the published branch does not yet throttle failed scheduled attempts. A 15-minute retry cooldown has been implemented and tested locally but is not included in the current PR commit.

Related PR

PR #2 also edits this detector to read localized connection counts and tighten stale-connection cleanup. The branches currently conflict in that file. Suggested integration order: #2, then #3, retaining #2's localized count reader and #3's positive-evidence detector. Under #3, the cleanup is removed rather than retained with a stricter threshold.

Validation

  • Independently reran the published commit c5d0cd8: 13 assertions passed using real in-memory SQLite and a stubbed LinkedIn session.
  • Coverage includes account-filtered enrollment, profile URL normalization, an older match on a later page, absent contacts left unchanged, historical dates, idempotency, and API failure without advancing the successful-sync timestamp.
  • The original implementation validation reported a passing full TypeScript check and a combined synthetic check with the analytics branch. Those checks were not rerun in this description update.

The regression fixture uses synthetic contacts and makes no network requests. It does not exercise LinkedIn's live API response parser or real account behavior.

Run after installing dependencies:

node tests/accepted-sync.cjs

@TheGuyWithoutH

Copy link
Copy Markdown
Author

Merged in #7 along the adaptations from PR #2.

The upstream PR stays intact and tracking codex/connection-acceptance-sync

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant