Files
chat_room/internal/models/user.go
T
mobiniqow 1dc96e86fc Add admin user moderation: block/unblock, reports, matches list, photo review
- User blocking (with reason) now closes the auth gap immediately — a
  blocked user's still-valid access token stops working on the next
  request, not just on their next OTP/refresh.
- Admin-created reports (moderation notes) per user, viewable in a history
  list independent of block status.
- GET /admin/users: full paginated, searchable user list with report counts.
- GET /admin/matches: all matches across the app ("friends" who mutually
  liked each other), for admin visibility.
- GET/DELETE /admin/photos: paginated feed of every uploaded photo with
  uploader info, so admins can review and remove content without going
  user-by-user.
- Per-user activity: monitoring requests can now be filtered by user_id, so
  a user's detail page can show their recent API activity.
- Batched the profile-selections query in fullProfilePayload (was 6 queries
  per view, now 1) for consistency with the earlier N+1 fixes.
2026-09-20 05:30:14 +03:30

117 lines
4.1 KiB
Go

package models
import "time"
// Gender جنسیت کاربر
type Gender string
const (
GenderMale Gender = "male"
GenderFemale Gender = "female"
)
// UserState وضعیت کلی کاربر
type UserState string
const (
UserStateInactive UserState = "inactive"
UserStateActive UserState = "active"
UserStateBlocked UserState = "blocked"
)
// OnboardingStep مرحله‌ی فعلی کاربر در فرآیند تکمیل پروفایل.
// هر مقدار یعنی «این مرحله هنوز باید تکمیل بشه». وقتی به StepCompleted
// می‌رسه یعنی کاربر تمام مراحل رو طی کرده.
type OnboardingStep int
const (
StepBasicInfo OnboardingStep = iota + 1
StepPhotos
StepBodyInfo
StepProfileQuestions
StepEducation
StepOccupations
StepRelationshipImportance
StepInterests
StepLookingFor
StepCompleted
)
// ApprovalStatus وضعیت بررسی پروفایل توسط ادمین (بعد از تکمیل آنبوردینگ)
type ApprovalStatus string
const (
ApprovalPending ApprovalStatus = "pending"
ApprovalApproved ApprovalStatus = "approved"
ApprovalRejected ApprovalStatus = "rejected"
)
// StepInfo برای پاسخ‌های API که وضعیت هر مرحله رو توضیح می‌ده
type StepInfo struct {
Step OnboardingStep `json:"step"`
Key string `json:"key"`
Done bool `json:"done"`
}
// ordered لیست ترتیب مراحل آنبوردینگ (برای ساخت وضعیت کامل)
var OnboardingStepOrder = []struct {
Step OnboardingStep
Key string
}{
{StepBasicInfo, "basic_info"},
{StepPhotos, "photos"},
{StepBodyInfo, "body_info"},
{StepProfileQuestions, "profile_questions"},
{StepEducation, "education"},
{StepOccupations, "occupations"},
{StepRelationshipImportance, "relationship_importance"},
{StepInterests, "interests"},
{StepLookingFor, "looking_for"},
}
// User کاربر اصلی سیستم. احراز هویت فقط با شماره موبایل + OTP انجام می‌شود.
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
Phone string `gorm:"size:11;uniqueIndex;not null" json:"phone"`
State UserState `gorm:"size:10;default:inactive;not null" json:"state"`
IsAdmin bool `gorm:"default:false;not null" json:"is_admin"`
IsActive bool `gorm:"default:true;not null" json:"is_active"`
// -------- بلاک شدن توسط ادمین --------
BlockedReason *string `json:"blocked_reason,omitempty"`
BlockedAt *time.Time `json:"blocked_at,omitempty"`
// فیلدهای OTP - هش می‌شوند و هرگز در پاسخ API برنمی‌گردند
OTPCode *string `gorm:"size:128" json:"-"`
OTPExpiry *time.Time `json:"-"`
// -------- اطلاعات پروفایل (پر می‌شوند طی فرآیند آنبوردینگ) --------
Gender *Gender `gorm:"size:10" json:"gender,omitempty"`
FirstName string `gorm:"size:100" json:"first_name,omitempty"`
BirthDate *time.Time `json:"birth_date,omitempty"`
HeightCM *int `json:"height_cm,omitempty"`
WeightKG *int `json:"weight_kg,omitempty"`
// -------- موقعیت مکانی (برای محاسبه‌ی فاصله‌ی تقریبی در دوستیابی) --------
Latitude *float64 `json:"-"`
Longitude *float64 `json:"-"`
// -------- وضعیت آنبوردینگ --------
CurrentStep OnboardingStep `gorm:"default:1;not null" json:"current_step"`
IsOnboarded bool `gorm:"default:false;not null" json:"is_onboarded"`
// -------- بررسی ادمین (بعد از تکمیل آنبوردینگ) --------
// تا وقتی approved نشه، کاربر اجازه‌ی ورود به صفحه‌ی دوستیابی رو نداره.
ApprovalStatus ApprovalStatus `gorm:"size:10;default:pending;not null" json:"approval_status"`
RejectionReason *string `json:"rejection_reason,omitempty"`
ReviewedAt *time.Time `json:"reviewed_at,omitempty"`
LastLogin *time.Time `json:"last_login,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
func (User) TableName() string {
return "users"
}