Skip to content

refactor(store/postgres): split adapter by domain and extract shared helpers#58

Merged
jmgilman merged 1 commit into
masterfrom
session-034/postgres-split
May 26, 2026
Merged

refactor(store/postgres): split adapter by domain and extract shared helpers#58
jmgilman merged 1 commit into
masterfrom
session-034/postgres-split

Conversation

@jmgilman
Copy link
Copy Markdown
Contributor

Summary

  • Splits store/postgres/store.go (1584 lines, 6 fused domains) into per-domain files: principal.go, role.go, provisioning.go, identity.go, oidc.go, token.go, plus shared helpers tx.go (generic withTx), errors.go (isPostgresCode), codec.go (JSONB encode/decode), clone.go (defensive copies), validation.go (string validators / dedup).
  • withTx[T any] collapses four repeated Begin/defer Rollback/Commit blocks (CreateProvisioningRule, UpdateProvisioningRule, ProvisionIdentity, passkey CreateRegistration). ProvisionIdentity uses a package-private sentinel errProvisionIdentityConflict so the post-rollback read for race recovery happens after withTx unwinds.
  • Consolidates the duplicate findIdentityLink (was a method on *Store and a free function in passkey.go) into one free function shared by LinkIdentity, resolveIdentityLinkConflict, and linkPasskeyIdentity.
  • Test files mirror the new layout with per-domain TestStoreSatisfiesXContracts compile-time port-assertion bundles; store_integration_test.go is untouched.
  • Adds godocs on every previously-undocumented unexported helper. Adds inline comments for: the migration advisory lock, transaction scopes, the credential-binding-pinned WHERE clause in UpdateCredentialAfterLogin as a security invariant, the malformed-hash rejection in findToken, the cross-principal rebind rejection, and the race-recovery path in ProvisionIdentity.
  • Public surface unchanged: go doc ./store/postgres shows exactly func Migrate(...), type Store struct{ ... }, func NewStore(...). Behavior unchanged.

This is PR C of a three-PR storage-package refactor; PR A (internal/storetest, #56) and PR B (store/memory, #57) have both landed.

Test plan

  • moon run root:check --summary minimal (vet, lint, build, format, unit tests)
  • moon run root:integration (Testcontainers Postgres suite)
  • go doc ./store/postgres matches master
  • git diff --check (no whitespace damage)
  • store.go dropped from 1584 → 68 lines; heaviest production file is now passkey.go at 499 lines (was 486; +13 from added godocs and withTx adoption)

🤖 Generated with Claude Code

…helpers

Break the 1584-line store.go into per-domain files (principal, role,
provisioning, identity, oidc, token) plus shared helpers tx.go, errors.go,
codec.go, clone.go, validation.go. CreateProvisioningRule,
UpdateProvisioningRule, ProvisionIdentity, and CreateRegistration now use a
generic withTx helper instead of duplicated Begin/Rollback/Commit blocks.
ProvisionIdentity's unique-violation race recovery uses a package-private
sentinel so the post-rollback read happens after withTx unwinds; LinkIdentity
and the passkey-registration link path share a single findIdentityLink. The
public surface stays exactly NewStore/*Store/Migrate.

Test files mirror the new layout with per-domain TestStoreSatisfiesXContracts
assertion bundles; store_integration_test.go is untouched. Every unexported
helper gains a one-line godoc; inline comments name the migration advisory
lock, transaction scopes, the credential-binding-pinned WHERE clause as a
security invariant, the malformed-hash rejection in findToken, and the
race-recovery path in ProvisionIdentity.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jmgilman jmgilman merged commit b75793a into master May 26, 2026
2 checks passed
@jmgilman jmgilman deleted the session-034/postgres-split branch May 26, 2026 21:57
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