Skip to content

feat(users): create users via the v1 API when --use-v1-user-api is set#636

Closed
michael-richey wants to merge 2 commits into
users-handle-mapping-keyfrom
users-v1-fallback-on-409
Closed

feat(users): create users via the v1 API when --use-v1-user-api is set#636
michael-richey wants to merge 2 commits into
users-handle-mapping-keyfrom
users-v1-fallback-on-409

Conversation

@michael-richey

@michael-richey michael-richey commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

What

When --use-v1-user-api is set, create users via POST /api/v1/user (which accepts an explicit handle) instead of v2.

Why

The destination derives a user's handle from its email on v2 create. When two source users share an email but have distinct handles, v2 create collapses them: the first create silently takes a handle that may belong to another user, and the second create 409s and can never succeed. v1 accepts an explicit handle, so each user is created with its own handle and no create collides.

Changes

  • With the flag set, create_resource posts to /api/v1/user with the source handle; with the flag off, user creation is unchanged (v2).
  • The v1 response is the legacy user shape, so re-resolve the v2 UUID by exact-case handle (small, sleep-free re-query loop for read-after-write visibility) and return that record — state and downstream references (roles, team memberships) key on the v2 UUID.
  • Any failure re-raises so the apply loop records it and continues with the other resources (disaster-recovery behavior preserved).

Tests

tests/unit/test_users.py: flag off → v2 path only; flag on → v1 POST with the handle, v2 never called, UUID reconciled; two shared-email/distinct-handle users are both created via v1 with their own handles (the core fix); empty-handle guard; v1-POST failure re-raises; reconcile re-queries on an empty first page and selects the exact-case handle among candidates; existing-handle update path takes no create.

Stacked on #635 (part 2 of 3).

🤖 Generated with Claude Code

@michael-richey
michael-richey marked this pull request as ready for review July 17, 2026 16:22
@michael-richey
michael-richey requested a review from a team as a code owner July 17, 2026 16:22
@michael-richey
michael-richey force-pushed the users-handle-mapping-key branch from 0e914af to 29e2d90 Compare July 17, 2026 17:51
@michael-richey
michael-richey force-pushed the users-v1-fallback-on-409 branch from 985bbf7 to ecb8cd7 Compare July 17, 2026 17:51
michael-richey and others added 2 commits July 17, 2026 14:05
Users were identified and linked by email, but the destination enforces
user uniqueness on the handle (email is not unique). Two users that share
an email but have distinct handles collapsed onto one derived handle.

Switch resource_mapping_key to attributes.handle (exact case) so distinct
handles stay distinct. Keep handle out of the read-only v2 create/update
payload (pop before POST/PATCH) and out of update diffs (via
exclude_regex_paths), while retaining it for mapping and v1 user creation.

Also wire the opt-in --use-v1-user-api flag (default off; env
DD_USE_V1_USER_API) through the CLI options and Configuration; the v1
create path lands in a follow-up. Add pytest-cov to test extras.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The destination derives a user's handle from its email on v2 create, so
two source users that share an email collapse onto one handle: the first
create silently takes a handle that may belong to another user, and the
second create 409s and can never succeed.

When --use-v1-user-api is set, create users via POST /api/v1/user, which
accepts an explicit handle, so every user keeps its own handle and no
create collides. The v1 response is the legacy user shape, so re-resolve
the v2 UUID by exact-case handle (with a small, sleep-free re-query loop
for read-after-write visibility) and return that record, since state and
downstream references (roles, team memberships) key on the v2 UUID. Any
failure re-raises so the apply loop records it and continues (DR-safe).
With the flag off, user creation is unchanged (v2).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@michael-richey
michael-richey force-pushed the users-handle-mapping-key branch from 29e2d90 to 8523e02 Compare July 17, 2026 18:12
@michael-richey
michael-richey force-pushed the users-v1-fallback-on-409 branch from ecb8cd7 to dcd41dd Compare July 17, 2026 18:12
@michael-richey michael-richey changed the title feat(users): fall back to the v1 create API on a 409 handle conflict feat(users): create users via the v1 API when --use-v1-user-api is set Jul 17, 2026
@michael-richey
michael-richey force-pushed the users-handle-mapping-key branch from 8523e02 to f54b846 Compare July 17, 2026 18:20
@michael-richey

Copy link
Copy Markdown
Collaborator Author

Consolidated into #635 — the stack was collapsed into a single PR.

@michael-richey
michael-richey deleted the users-v1-fallback-on-409 branch July 17, 2026 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant