v0.13.3 account delete api, web client and toolchain update

This commit is contained in:
lixen committed 2026-10-12 21:34:06 -04:00
1 parent cc03dc0294
commit ffbf603bc8
16 files changed
+672 -57

No files matched your search

+47
View File
@@ -1,6 +1,7 @@
package storage
import (
"context"
"database/sql"
"errors"
"fmt"
@@ -124,6 +125,52 @@ func (s *Store) DeleteUser(userID string) error {
return nil
}
// DeleteAccount removes an account at its owner's request. Unlike DeleteUser,
// which keeps the claim IDs and name snapshots for the record, it first clears
// the user's claims and names from every stored game, so nothing in the
// database still names the person, and a game nobody else claimed becomes
// anonymous and falls to the inactivity purge. Sessions cascade.
//
// It runs on the ordered game writer, behind every gameplay write already
// queued, so a queued claim cannot land on a game after it was cleared. It
// returns sql.ErrNoRows when no such user exists.
func (s *Store) DeleteAccount(userID string) error {
if !validUUID(userID) {
return sql.ErrNoRows
}
// Set inside the transaction, read after the writer reports back: the
// barrier channel orders the two. A missing row is an answer, not a
// failed write, so it must not degrade the writer.
var deleted int64
// Behind the queue, then its own transaction.
ctx, cancel := context.WithTimeout(context.Background(), flushTimeout+writeTimeout)
defer cancel()
err := s.enqueueWait(ctx, "delete_account", func(ctx context.Context, tx *sql.Tx) error {
if _, err := tx.ExecContext(ctx, `UPDATE games SET
white_claimed_by = CASE WHEN white_claimed_by = $1 THEN NULL ELSE white_claimed_by END,
white_name = CASE WHEN white_claimed_by = $1 THEN NULL ELSE white_name END,
black_claimed_by = CASE WHEN black_claimed_by = $1 THEN NULL ELSE black_claimed_by END,
black_name = CASE WHEN black_claimed_by = $1 THEN NULL ELSE black_name END
WHERE white_claimed_by = $1 OR black_claimed_by = $1`, userID); err != nil {
return err
}
result, err := tx.ExecContext(ctx, `DELETE FROM users WHERE user_id = $1`, userID)
if err != nil {
return err
}
deleted, err = result.RowsAffected()
return err
})
if err != nil {
return err
}
if deleted == 0 {
return sql.ErrNoRows
}
slog.Debug("storage account deleted", "user_id", userID)
return nil
}
// UpdateUserPassword updates user password hash
func (s *Store) UpdateUserPassword(userID, passwordHash string) error {
return s.execUserUpdate(`UPDATE users SET password_hash = $2 WHERE user_id = $1`,