chore: update admin apis

This commit is contained in:
Krispire Admin
2026-06-16 16:25:44 +05:30
parent 04ad94ad3c
commit 1cde0c0544
3 changed files with 18 additions and 8 deletions
+5
View File
@@ -19,6 +19,11 @@ type AdminUser struct {
BannedAt *time.Time `json:"banned_at"`
PostCount int `json:"post_count"`
CreatedAt time.Time `json:"created_at"`
// Connected auth methods. HasPassword means email+password login is set up;
// Providers lists linked OAuth providers (e.g. "google", "facebook").
HasPassword bool `json:"has_password"`
Providers []string `json:"providers"`
}
// AdminPost is a row in the admin posts table.
+9 -5
View File
@@ -37,6 +37,9 @@ func (r *AdminRepo) ListUsers(ctx context.Context, q string, limit, offset int)
u.email_verified_at, u.banned_at,
(SELECT COUNT(*) FROM posts p WHERE p.user_id = u.id AND p.deleted_at IS NULL) AS post_count,
u.created_at,
(u.password_hash IS NOT NULL) AS has_password,
(SELECT COALESCE(array_agg(oa.provider ORDER BY oa.provider), ARRAY[]::text[])
FROM oauth_accounts oa WHERE oa.user_id = u.id) AS providers,
COUNT(*) OVER() AS total
FROM users u
WHERE ($1 = '' OR u.name ILIKE '%'||$1||'%' OR u.handle ILIKE '%'||$1||'%'
@@ -53,7 +56,8 @@ func (r *AdminRepo) ListUsers(ctx context.Context, q string, limit, offset int)
for rows.Next() {
var u model.AdminUser
if err := rows.Scan(&u.ID, &u.Email, &u.Handle, &u.Name, &u.AvatarURL,
&u.Role, &u.Plan, &u.EmailVerifiedAt, &u.BannedAt, &u.PostCount, &u.CreatedAt, &total); err != nil {
&u.Role, &u.Plan, &u.EmailVerifiedAt, &u.BannedAt, &u.PostCount, &u.CreatedAt,
&u.HasPassword, &u.Providers, &total); err != nil {
return nil, 0, fmt.Errorf("scan admin user: %w", err)
}
out = append(out, u)
@@ -178,8 +182,9 @@ func (r *AdminRepo) ListFeedback(ctx context.Context, status string, limit, offs
return out, total, rows.Err()
}
// SaveReply stores an admin reply on a feedback row, stamps replied_at, and
// resolves it (if not already). It returns the recipient's email (the
// SaveReply stores an admin reply on a feedback row and stamps replied_at. It
// does NOT change resolved_at — replying and resolving are independent actions
// (resolve via ResolveFeedback). It returns the recipient's email (the
// submitter's account email, else the anonymous contact_email — may be nil if
// neither is known) and name so the caller can send the reply email. ok is
// false when the id doesn't exist.
@@ -187,8 +192,7 @@ func (r *AdminRepo) SaveReply(ctx context.Context, id, message string) (email *s
err = r.pg.Pool.QueryRow(ctx, `
UPDATE feedback f
SET reply_message = $2,
replied_at = now(),
resolved_at = COALESCE(resolved_at, now())
replied_at = now()
WHERE f.id = $1
RETURNING COALESCE((SELECT email FROM users WHERE id = f.user_id), f.contact_email),
COALESCE((SELECT name FROM users WHERE id = f.user_id), '')`,
+4 -3
View File
@@ -88,9 +88,10 @@ func (s *AdminService) NotifyUser(ctx context.Context, userID, title, body strin
return s.notif.NotifyAdminMessage(ctx, userID, title, body)
}
// ReplyFeedback stores the reply (resolving the row) and emails it to the
// submitter when an address is known. Returns found=false if the id is
// unknown, and emailed=true when a reply email was actually sent.
// ReplyFeedback stores the reply and emails it to the submitter when an
// address is known. It does not resolve the row (resolve is a separate
// action). Returns found=false if the id is unknown, and emailed=true when a
// reply email was actually sent.
func (s *AdminService) ReplyFeedback(ctx context.Context, id, message string) (found, emailed bool, err error) {
email, name, ok, err := s.repo.SaveReply(ctx, id, message)
if err != nil || !ok {