feat: fire user.Deactivating from the admin deactivate action

- DeactivatingEvent and DeactivatingEventName in classes
- FireDeactivatingEvent modelled on FireDeletingEvent
- the deactivate bulk action runs DeactivateUsers unchanged, then fires
  the event per newly deactivated user in the action's transaction
This commit is contained in:
2026-10-19 19:06:20 +02:00
parent ee474401cb
commit 80b436d3d9
4 changed files with 48 additions and 2 deletions

View File

@@ -594,13 +594,35 @@ func (c usersAdminController) AdminBulkActions() []pact.AdminBulkAction {
}
return []pact.AdminBulkAction{
bulk("activate", classes.ActivateUsers),
bulk("deactivate", classes.DeactivateUsers),
bulk("deactivate", c.deactivateUsers),
bulk("restore", classes.RestoreUsers),
bulk("ban", classes.BanUsers),
bulk("unban", classes.UnbanUsers),
}
}
// deactivateUsers runs classes.DeactivateUsers unchanged and then fires
// user.Deactivating, in the action's transaction, for every selected user
// that was not deactivated before. A listener error rolls the action back.
func (c usersAdminController) deactivateUsers(ctx context.Context, tx *gorm.DB, users []*models.User) (int, error) {
pending := make([]*models.User, 0, len(users))
for _, user := range users {
if user != nil && user.ID != 0 && !user.DeletedAt.Valid {
pending = append(pending, user)
}
}
changed, err := classes.DeactivateUsers(ctx, tx, users)
if err != nil {
return 0, err
}
for _, user := range pending {
if err := FireDeactivatingEvent(ctx, c.application(), user, tx); err != nil {
return 0, err
}
}
return changed, nil
}
// throttleState reads whether one user is banned and whether they are
// suspended, through the write's transaction when there is one.
func (c usersAdminController) throttleState(ctx context.Context, userID uint) (banned, suspended bool, err error) {