Skip to content

refactor(onboarding): readability + maintainability sweep#66

Merged
jmgilman merged 3 commits into
masterfrom
session-039/onboarding-sweep
May 28, 2026
Merged

refactor(onboarding): readability + maintainability sweep#66
jmgilman merged 3 commits into
masterfrom
session-039/onboarding-sweep

Conversation

@jmgilman
Copy link
Copy Markdown
Contributor

Summary

Sixth slice of the multi-session readability sweep (after access/ #61, authz/ #62, exchange/ #63, http/ #64, management/ #65). Lifts onboarding/ to the same 10-criteria bar.

The central change: replace the single Service (sparse Options + runtime nil-port checks) with two purpose-built types, each with a required-args constructor.

  • Attacher (find principal → link identity) takes PrincipalFinder + IdentityLinker.
  • Provisioner (delegate to atomic create-and-link) takes IdentityProvisioner.

Compile-time port enforcement replaces the runtime nil-check pattern. The redundant ProvisionPrincipalRequest/ProvisionPrincipalResult wrapper types (field-identical to authkit.ProvisionIdentityRequest/Result) are dropped; Provisioner.ProvisionIdentity uses the root types directly.

Attacher's request/result types stay package-local because they carry shapes (PrincipalID input, Principal+Link output) absent from any root type.

Production split into per-domain files mirroring exchange/ (PR #63): attach.go, provision.go, validation.go. Tests split to match: attach_test.go, provision_test.go, helpers_test.go.

Mockery picks up IdentityProvisioner (the only missing root port — PrincipalFinder and IdentityLinker were already configured). .mockery.yaml grows to 19 root-port entries. All three hand-rolled fakes are deleted; .requests/.findIDs slice assertions subsume into EXPECT() deep-equality matching.

Commits

  1. refactor(onboarding): split Service into Attacher and Provisioner — production-only restructure.
  2. test(onboarding): split tests per workflow — mechanical lift into per-domain test files; fakes intact.
  3. test(onboarding): migrate hand-rolled fakes to mockery — generated mocks replace the three fakes.

Test plan

  • moon run root:check --summary minimal — format, lint, build, unit, Testcontainers integration all green.
  • go doc ./onboarding shows the intended public surface: NewAttacher, NewProvisioner, Attacher, Provisioner, AttachIdentityRequest, AttachIdentityResult. Nothing else.
  • No external consumers (grep confirms onboarding is library-facade like management/).

🤖 Generated with Claude Code

jmgilman and others added 3 commits May 27, 2026 17:04
Service today carries two heterogeneous workflows behind one type:
identity attachment (find principal, then link) and principal provisioning
(delegate to IdentityProvisioner). The sparse Options struct and runtime
nil-port checks are the symptom of two contracts squashed into one — apps
doing only attachment never set IdentityProvisioner and vice versa.

Split into Attacher and Provisioner, each with a required-args
constructor. Compile-time port enforcement replaces runtime nil checks.
Drop the ProvisionPrincipalRequest/Result wrapper types — they were
field-identical to authkit.ProvisionIdentityRequest/Result and added no
value. Provisioner.ProvisionIdentity now takes and returns the root types
directly. Attacher's request/result types stay package-local because they
carry shapes (PrincipalID input, Principal+Link output) absent from any
root type.

Reorganize into per-domain files (attach.go, provision.go, validation.go)
mirroring the exchange/ split from PR #63. Tests are intentionally broken
at this commit and restored in the next commits.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lift the existing tests into per-domain files mirroring the production
layout: attach_test.go for the Attacher tests, provision_test.go for the
Provisioner tests, helpers_test.go for the shared fixtures, consts, and
hand-rolled fakes.

Drop TestNewServiceAllowsSparseOptions and TestServiceMethodsRequirePorts
— required-args constructors make those scenarios uncompilable.
TestServicePropagatesContextCancellation splits into a per-type
cancellation test per workflow. provisionRequest() now returns the root
authkit.ProvisionIdentityRequest directly.

Fakes are intact at this commit; mockery migration follows.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add an IdentityProvisioner entry to .mockery.yaml (PrincipalFinder and
IdentityLinker were already configured), regenerate, and swap the three
hand-rolled fakes for the generated authkitmocks types.

Tracked-requests slice assertions subsume into EXPECT() deep-equality
arg matching. Tests that short-circuit before a port call pass an
unconfigured mock so a stray call would panic. Cancellation tests
configure the mock to return context.Canceled explicitly since mockery
mocks do not respect ctx.Err() the way the hand-rolled fakes did.

.mockery.yaml grows to 19 root-port entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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