Add atomic account registration and local media
verify / verify (push) Successful in 3m35s

This commit is contained in:
2026-09-03 11:51:53 -04:00
parent 337b56ec1b
commit 92ef63ba00
23 changed files with 1816 additions and 62 deletions
+36
View File
@@ -0,0 +1,36 @@
<!-- SPDX-License-Identifier: MPL-2.0 -->
# Web Foundations dogfood notes
This living note records concrete pressure discovered while Gamertan services
adopt Web Foundations. It is implementation evidence, not a promise that every
application concern belongs in the shared module.
## Gamertan accounts and commerce
- The account email remains required and unique. Gamertan uses normalized
email as the canonical login identifier and keeps username as a stable public
identity. Until a mail package exists, the application must not describe an
address as verified merely because it was entered during registration.
- Password authentication is sufficient for an ordinary customer base
session. Privileged application actions use an exact operation binding with
`authwebauthn.BeginApproval` and `FinishApproval`; that is safer than a broad
long-lived "elevated" session. A user without a passkey can use ordinary
features but must enroll one before performing protected work.
- `auth.Service.VerifyPassword` remains available for flows that truly require
password plus passkey before session issuance.
- Public registration exposed a cross-package transaction boundary. The
`account` package now keeps an unusable bounded registration draft and makes
recovery-code digests, personal organization, membership, owner binding,
activation, audits, and an optional initial passkey one repository commit.
A failed WebAuthn ceremony can be restarted, or an ordinary password account
can finish without it, without persisting a partly privileged account.
- Media belongs behind a storage-neutral interface with a hardened local
adapter. Content workflow, references, and authorization remain application
policy.
- Historical `authsqlite.Open` still migrates for compatibility. Applications
with reviewed deployment gates use `OpenWithOptions` with migration disabled,
require the current schema at startup, and invoke `Migrate` only from an
explicit operator command.
- Commerce remains a separately versioned nested module so payment-provider
policy and catalog evolution do not enlarge the authentication core.
+1 -1
View File
@@ -25,7 +25,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.9
go get gamertan.com/web/requestmeta@v0.1.0-preview.10
go mod verify
```
+7 -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.9
go get gamertan.com/web/requestmeta@v0.1.0-preview.10
```
Only imported packages are compiled and linked. The packages nevertheless
@@ -52,6 +52,12 @@ Do not split merely to make an architecture diagram look modular. Package
interfaces provide source-level modularity today; modules are introduced only
for an independent dependency and release lifecycle.
The `media` package and `medialocal` adapter deliberately remain in the root
module: they use only the standard library, and applications can adopt the core
interface without importing the local adapter. Commerce is different. Its
provider SDK and independently evolving catalog/payment contract justify a
future nested `gamertan.com/web/commerce` module after application dogfood.
## Session boundaries
Authenticated sessions currently belong to three deliberate packages: