package dto // DiscoverCandidate یک پروفایل پیشنهادی توی صفحه‌ی دوستیابی type DiscoverCandidate struct { ID uint `json:"id"` FirstName string `json:"first_name"` Age int `json:"age"` Bio string `json:"bio,omitempty"` Photos []string `json:"photos"` DistanceKM *float64 `json:"distance_km,omitempty"` Interests []string `json:"interests,omitempty"` } // SwipeRequest بدنه‌ی درخواست ثبت لایک/ردّ type SwipeRequest struct { Action string `json:"action" binding:"required,oneof=like pass superlike"` } // SwipeResponse نتیجه‌ی یک سواپ؛ اگه Matched=true باشه یعنی مچ تازه (یا از قبل) ساخته شده type SwipeResponse struct { Matched bool `json:"matched"` Match *MatchView `json:"match,omitempty"` } // MatchView خلاصه‌ی یک مچ برای نمایش در لیست مچ‌ها/گفتگوها. برای پیش‌نمایش // آخرین پیام، سرور رمزگشایی نمی‌کنه (نمی‌تونه) — CipherText/Nonce خودِ آخرین // پیام رو برمی‌گردونه تا کلاینت خودش رمزگشایی کنه؛ LastMessage فقط برای // پیام‌های قدیمیِ قبل از E2EE پر می‌شه. type MatchView struct { ID uint `json:"id"` UserID uint `json:"user_id"` FirstName string `json:"first_name"` Photos []string `json:"photos"` CreatedAt string `json:"created_at"` LastMessage *string `json:"last_message,omitempty"` LastMessageCipherText *string `json:"last_message_cipher_text,omitempty"` LastMessageNonce *string `json:"last_message_nonce,omitempty"` LastAt *string `json:"last_at,omitempty"` // PartnerPublicKey کلید عمومی X25519 طرف مقابل (base64) برای رمزنگاری // سرتاسری؛ اگه طرف مقابل هنوز کلیدی ثبت نکرده باشه خالیه. PartnerPublicKey *string `json:"partner_public_key,omitempty"` } // MessageView یک پیام در یک گفتگو. یا Text (پیام قدیمیِ قبل از E2EE) پر // می‌شه، یا CipherText+Nonce (پیام رمزنگاری‌شده) — سرور خودش نمی‌دونه محتوای // رمزنگاری‌شده چیه، فقط بین دو طرف مچ ردوبدلش می‌کنه. type MessageView struct { ID uint `json:"id"` MatchID uint `json:"match_id"` SenderID uint `json:"sender_id"` Text string `json:"text,omitempty"` CipherText *string `json:"cipher_text,omitempty"` Nonce *string `json:"nonce,omitempty"` CreatedAt string `json:"created_at"` IsMine bool `json:"is_mine"` } // SendMessageRequest بدنه‌ی درخواست ارسال پیام رمزنگاری‌شده. متن خام پیام // هیچ‌وقت به سرور نمی‌رسه؛ کلاینت قبل از ارسال با کلید عمومی طرف مقابل // رمزنگاریش می‌کنه. type SendMessageRequest struct { CipherText string `json:"cipher_text" binding:"required,min=1,max=12000"` Nonce string `json:"nonce" binding:"required,len=32"` } // CandidateAnswer پاسخ یک سوال پروفایل، برای نمایش عمومی type CandidateAnswer struct { Question string `json:"question"` Answer string `json:"answer"` } // CandidateDetail پروفایل کامل یک کاربر دیگه (برای نمایش صفحه‌ی جزئیات پروفایل) type CandidateDetail struct { ID uint `json:"id"` FirstName string `json:"first_name"` Age int `json:"age"` Bio string `json:"bio,omitempty"` Photos []string `json:"photos"` DistanceKM *float64 `json:"distance_km,omitempty"` HeightCM *int `json:"height_cm,omitempty"` WeightKG *int `json:"weight_kg,omitempty"` Education string `json:"education,omitempty"` FieldOfStudy string `json:"field_of_study,omitempty"` Occupations []string `json:"occupations,omitempty"` Interests []string `json:"interests,omitempty"` ImportantInRelationship []string `json:"important_in_relationship,omitempty"` LookingFor string `json:"looking_for,omitempty"` Answers []CandidateAnswer `json:"profile_answers,omitempty"` }