Skip to main content

[Employer Sync 5.1] Extract a shared Identities::User upsert service

TL;DR: Pull the single-user Identities::User upsert into one service (JodGig::Users::UpsertIdentitiesUserService) so four callers — talent batch, talent JIT, employer batch, and the new employer JIT (5.2) — stop drifting apart.

Context​

The talent batch sync, the talent JIT, and the employer batch sync (after issue 4.2) all write Identities::User rows from a JodGig::User. Issue 5.2 adds a fourth caller — a single-employer JIT triggered from the login flow.

Problem​

Each existing caller has its own hand-rolled upsert logic. They drift apart over time. The next bug fix has to be remembered four times, and forgetting once breaks one of the four paths silently.

Direction​

Pull the single-user upsert into one service:

app/domains/jod_gig/users/upsert_identities_user_service.rb

JodGig::Users::UpsertIdentitiesUserService.execute(jodgig_user:, kind:) — kind is :talent or :employer. The service:

  • Calls the right mapper for the kind (the shared talent mapper for :talent; the employer-specific path from 4.2 for :employer).
  • Runs a single-row upsert keyed on remote_gig_user_id.
  • Returns the Identities::User.
  • Is transaction-agnostic (per jodapp-api app/domains/AGENTS.md — the caller owns the transaction).

Migrate the existing callers:

  • JodGig::Users::SyncService (talent batch) — replace its inline single-record upsert in Phase A with a call.
  • JodGig::Users::JitMigrationService (talent JIT) — replace its inline upsert with a call.
  • JodGig::Users::EmployersSyncService (employer batch) — already calls into it via the skeleton from 3.1; wire upsert_identities_users to call the shared service per row.

This is a refactor — there must be no behaviour change.

Acceptance​

  • Shared service exists at the path above.
  • Three existing callers all route through it.
  • All existing talent-sync and JIT tests pass without change.

Depends on​

  • 4.2 (the employer-specific mapping must exist for the shared service to dispatch on kind)