Skip to content

refactor(arch): move the 7 login records into Access's public contract - #1104

Merged
mforce merged 1 commit into
mainfrom
refactor/1103-login-records-access-contract
Oct 6, 2026
Merged

mforce merged 1 commit into
mainfrom
refactor/1103-login-records-access-contract

Conversation

@mforce

@mforce mforce commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Moves the 7 login records that #1095 left in shared Platform code into Access's public contract, unchanged. No behavior, wire-format or schema change.

Closes #1103

TL;DR

FarmSignIn, RefreshTokenRevocationOutcome, TokenPair, UserSummary, UserProfile, StepUpGrant and StepUpErrorCodes move from Application/Common to Application/Modules/Access/Contracts/. Access produces all seven. Six appear in IAccessModule signatures, and the HTTP adapters map StepUpErrorCodes.Required to a response. The guards then ask for two declarations, and this PR adds both:

  • Edge symbol: UserProfile keeps Commerce's published EggUnit?. It is declared as one more symbol on the existing Access → Commerce row (CW1001 otherwise), as Farm's FarmSettingsDetails already does.
  • Adapter row: AuthEndpoints.LegacyUpgradeResult already takes a TokenPair. Now that TokenPair is an Access contract type, the reach needs a row; its siblings Login, Refresh, Logout, StepUp and ChangePassword already have identical rows.

Change map (20 files, +31/−22)

Kind Files Review
Move 7 × Application/Common/<T>.cs → Application/Modules/Access/Contracts/<T>.cs Renames. Only the namespace line changes.
Edge declaration src/Cluckwork.Domain/Common/Architecture/Modules/Access.cs Read this one: one symbol plus one reason sentence on the Access → Commerce row.
Adapter declaration tests/.../Architecture/RealModuleLedger.Adapters.cs One row.
Generated tests/.../Architecture/Data/coupling-matrix.md 4 lines: Access→Commerce W (7)→W (8); adapter rows reaching Access A (28)→A (29). Regenerated with CLUCKWORK_REGENERATE_MATRIX=1.
Imports only IIdentityProvider, IStepUpGrantService, IdentityProvider, JwtTokenService, StepUpGrantService, 3 integration test files +using …Access.Contracts (8), -using …Application.Common where now unused (5). No body changes.
Qualifier Api/Modules/Access/Users/UserEndpoints.cs 5 × Cluckwork.Application.Common.StepUpErrorCodes.Required → StepUpErrorCodes.Required (the file's other 2 references were already short).
Docs docs/decisions/857-access-contract.md Amendment: the current contract root and these 7 additions. The contract goes from 29 to 36 top-level declarations (21 → 28 files).

Not changed: UserSummary and AccessUserSummary are not renamed. The existing reason text on the Access → Commerce row still says Domain.Catalog.EggUnit, as the Farm row does. Only the new sentence uses the current Cluckwork.Domain.Modules.Commerce.Contracts.EggUnit name, so fixing those older names stays out of this move.

Decision

Spike: owner-approved and reviewed by Astra. Rejected alternatives:

  • Leaving the records in Platform keeps Access's API in the free hub, where the UserProfile → Commerce coupling and the adapter reach go untracked.
  • Changing PreferredStepperUnit to string? drops the compile-time dependency but loses type safety, and it still exposes Commerce's names.
  • Moving the stepper preference out of Access is a product change, and it would still leave the edge, because AccountProvisioner inserts EggUnitConversion.Defaults.

Proofs

Base: origin/main 23bb1921. Head: aa02aedd. I measured every row on this machine; the logs are in the coordinator workspace under reviews/1103-proofs/.

Proof How Result
Build Cluckwork.sln (warnings are errors) dotnet build 0 warnings, 0 errors
Architecture + tenant-bypass guards Application.Tests ~Architecture|~TenantBypass 438/438
7 declarations unchanged apart from namespace For each type: main's file with the namespace line swapped vs head's file, sha256 all 7 identical; each raw diff is exactly the 2 namespace lines
None left in Application/Common git cat-file -e HEAD:…/Common/<T>.cs absent for all 7
OpenAPI identical to main Throwaway Development-host test dumps /openapi/v1.json on base and head byte-identical, 111,368 B, sha256 b3ca54f0…
DI registrations identical to main Same throwaway test captures the final IServiceCollection (service type, lifetime, key, implementation type/factory/instance) byte-identical, 466 registrations, sha256 90925ea9…
Tenant-bypass registries identical to main sha256 of BypassAllowList.cs and FilterFreeSetSites.cs; git diff of TenantBypass/ identical; 0 diff lines, and the real-tree guard is green against them
Coupling matrix changes only by the declared additions git diff of coupling-matrix.md 4 lines: Access→Commerce W (7)→W (8) (×2 views), Access adapter rows A (28)→A (29) (×2 views)
Auth/me/users integration (real Postgres) 34 classes, one dotnet test each, DOTNET_USE_POLLING_FILE_WATCHER=1, under sg docker 34/34 classes, 372/372 tests
CI — all checks green at aa02aedd

The OpenAPI document holds request schemas only, so it cannot show a response change by itself. Response shapes are covered by the mapping instead: no endpoint serializes any of the 7. Each is copied into an unchanged API type (AccessTokenResponse, StepUpResponse, UserResponse, MeResponse), and MeEndpointsTests, AuthCookieContractTests and StepUpAuthTests assert those bodies.

Mutations

# Mutation Expected Observed
M1 Delete the "…Access.Contracts.UserProfile" symbol from the Access → Commerce row build fails with CW1001 UserProfile.cs(7,5): error CW1001: undeclared cross-owner edge Access -> Commerce from Cluckwork.Application.Modules.Access.Contracts.UserProfile — 1 error
M2 Delete the AuthEndpoints.LegacyUpgradeResult adapter row adapter reach fails AdapterReachRealTreeTests.RealSourceTree_EveryAdapterReachIsDeclared red: undeclared adapter reach …AuthEndpoints.LegacyUpgradeResult -> Access through …Access.Contracts.TokenPair

I restored the tree after each mutation (git status clean).

FarmSignIn, RefreshTokenRevocationOutcome, TokenPair, UserSummary,
UserProfile, StepUpGrant and StepUpErrorCodes move unchanged from
Application/Common to Application/Modules/Access/Contracts. Access
produces all seven; six appear in IAccessModule signatures and the HTTP
adapters map StepUpErrorCodes.Required to a response.

UserProfile keeps Commerce's published EggUnit and is declared on the
existing Access -> Commerce edge. AuthEndpoints.LegacyUpgradeResult gets
an adapter row for its existing TokenPair parameter. The coupling matrix
is regenerated and decision record 857 is amended.

Closes #1103
@mforce
mforce merged commit 91263f4 into main Oct 6, 2026
19 checks passed
@mforce
mforce deleted the refactor/1103-login-records-access-contract branch October 6, 2026 05:07
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.

refactor(arch): move the 7 login records into Access's public contract

1 participant