feat: admin endpoints to reset username sync flags
Add POST /v1/admin/users/{pubkey}/reset-username and
POST /v1/admin/users/reset-usernames to clear manual_username
and last_synced_at so nostr profile sync re-evaluates users.
Includes OpenAPI docs, audit actions, and tests.
This commit is contained in:
@@ -133,6 +133,20 @@ func (r *Repo) Delete(ctx context.Context, pubkey string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// ResetAllSyncFlags clears manual_username and last_synced_at for every active
|
||||
// user so the profile sync worker re-evaluates them on its next tick. Returns
|
||||
// the number of affected rows.
|
||||
func (r *Repo) ResetAllSyncFlags(ctx context.Context) (int64, error) {
|
||||
res, err := r.db.ExecContext(ctx, `UPDATE users SET
|
||||
manual_username = 0,
|
||||
last_synced_at = NULL
|
||||
WHERE is_active = 1`)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return res.RowsAffected()
|
||||
}
|
||||
|
||||
// SetActiveExpiry sets a user's expires_at to an absolute value and reactivates
|
||||
// them. Idempotent: applying the same input twice produces the same end state.
|
||||
func (r *Repo) SetActiveExpiry(ctx context.Context, pubkey string, sub SubscriptionType, expiresAt *time.Time) error {
|
||||
|
||||
@@ -100,6 +100,29 @@ func (s *Service) Delete(ctx context.Context, pubkey string) error {
|
||||
return s.repo.Delete(ctx, pubkey)
|
||||
}
|
||||
|
||||
// ResetUsername clears the manual_username pin and last_synced_at cooldown for
|
||||
// a single user so the next profile sync cycle re-evaluates their kind:0
|
||||
// metadata. The stored username is left untouched until the worker overwrites
|
||||
// it. Returns the updated user.
|
||||
func (s *Service) ResetUsername(ctx context.Context, pubkey string) (*User, error) {
|
||||
u, err := s.repo.GetByPubkey(ctx, pubkey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u.ManualUsername = false
|
||||
u.LastSyncedAt = nil
|
||||
if err := s.repo.Update(ctx, u); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// ResetAllUsernames clears manual_username and last_synced_at for every active
|
||||
// user. Returns the number of affected rows.
|
||||
func (s *Service) ResetAllUsernames(ctx context.Context) (int64, error) {
|
||||
return s.repo.ResetAllSyncFlags(ctx)
|
||||
}
|
||||
|
||||
// computeExpiry returns *time.Time (nil for lifetime).
|
||||
func computeExpiry(sub SubscriptionType, years int, current time.Time, now time.Time) *time.Time {
|
||||
if sub == SubLifetime {
|
||||
|
||||
Reference in New Issue
Block a user