Guard customer-owned profile and membership transactions
verify / verify (push) Successful in 4m25s

Signed-off-by: Cole Speelman <crspeelman@gmail.com>
This commit is contained in:
2026-09-05 00:33:24 -04:00
parent f142ac23a9
commit d476179148
12 changed files with 369 additions and 10 deletions
+8
View File
@@ -8,6 +8,14 @@ application concern belongs in the shared module.
## Gamertan accounts and commerce
- Customer profile and membership editing requires current ownership for every
write, not just changes involving another owner. The existing generic methods
intentionally permit application-authorized delegated administrators, so an
application preflight alone would leave a demotion race. Explicit owner-managed
methods now share their transactional cores while rechecking current direct
ownership before any write. Tests cover stale authority and optimistic state,
last-owner protection, concurrent winners, and audit-failure rollback. No extra
passkey ceremony or database migration is needed for this invariant.
- A customer may need both purchasing and billing access. Replacing one role at
a time would create partial permission states and misleading audit history.
The role-set extension commits all direct roles together with optimistic
+1 -1
View File
@@ -26,7 +26,7 @@ The packages are ordinary Go imports. Pin the current preview and verify its
module checksum:
```bash
go get gamertan.com/web/requestmeta@v0.1.0-preview.23
go get gamertan.com/web/requestmeta@v0.1.0-preview.24
go mod verify
```
+1 -1
View File
@@ -18,7 +18,7 @@ import "gamertan.com/web/requestmeta"
and request the containing module at an exact version:
```bash
go get gamertan.com/web/requestmeta@v0.1.0-preview.23
go get gamertan.com/web/requestmeta@v0.1.0-preview.24
```
Only imported packages are compiled and linked. The packages nevertheless
+11
View File
@@ -75,6 +75,17 @@ owns atomic public signup, including personal organization and credentials.
## Membership and access lifecycle
For customer-owned businesses where only owners manage profiles and members,
use `UpdateOwnedOrganization`, `ChangeOwnedMembershipStatus`, and
`RemoveOwnedMembershipIfCurrent`. They recheck the service's configured direct
owner after acquiring the write lock, including when the target is a non-owner.
The actor must remain active and fully registered, their membership must remain
active, and the organization must be active and non-personal. Profile changes
only update name and slug; archiving and personal-account lifecycle are separate.
Custom adapters must implement `OwnerManagedRepository`, with no fallback to an
application preflight followed by an unguarded write. These additions retain
schema 10 and do not change the existing delegated-administration methods below.
Organizations and teams use optimistic revisions and reversible
`active`/`archived` states. Archived objects keep their history but contribute
no effective authority. Memberships may be suspended, reactivated, or removed;