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"` Bio *string `gorm:"size:300" json:"bio,omitempty"` // -------- گیمیفیکیشن: استریک روزانه (چند روز پشت‌سرهم اپ باز شده) -------- StreakCount int `gorm:"default:0;not null" json:"streak_count"` LastActiveDate *time.Time `json:"last_active_date,omitempty"` // -------- ترجیحات اعلان -------- // فعلاً فقط ذخیره می‌شن (زیرساخت ارسال واقعی اعلان هنوز پیاده نشده)؛ وقتی // اون سیستم اضافه شد، همین مقادیر رو برای تصمیم به ارسال یا نه می‌خونه. NotifyMatches bool `gorm:"default:true;not null" json:"notify_matches"` NotifyMessages bool `gorm:"default:true;not null" json:"notify_messages"` NotifyLikes bool `gorm:"default:true;not null" json:"notify_likes"` // -------- موقعیت مکانی (برای محاسبه‌ی فاصله‌ی تقریبی در دوستیابی) -------- Latitude *float64 `json:"-"` Longitude *float64 `json:"-"` // -------- کلید عمومی رمزنگاری سرتاسری پیام‌ها (E2EE) -------- // کلید خصوصی هیچ‌وقت به سرور نمی‌رسه و فقط روی دستگاه کاربر (localStorage) // ذخیره می‌شه؛ سرور فقط این کلید عمومی رو نگه می‌داره تا طرف مقابل بتونه // باهاش پیام رمزنگاری کنه. کلید X25519 هست، base64-encoded (۳۲ بایت خام). PublicKey *string `gorm:"size:64" json:"public_key,omitempty"` // -------- وضعیت آنبوردینگ -------- 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" }