chore: merge backend repo history into monorepo at backend/

git-subtree-dir: backend
git-subtree-mainline: dc11190527
git-subtree-split: acae976622
This commit is contained in:
2026-09-27 10:30:16 +03:30
67 changed files with 6835 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
package models
import "time"
// Photo یکی از عکس‌های پروفایل کاربر
type Photo struct {
ID uint `gorm:"primaryKey" json:"id"`
UserID uint `gorm:"not null;index" json:"user_id"`
URL string `gorm:"size:500;not null" json:"url"`
SortOrder int `gorm:"default:0;not null" json:"sort_order"`
CreatedAt time.Time `json:"created_at"`
}
func (Photo) TableName() string {
return "photos"
}
// SwipeAction نوع تصمیمی که کاربر روی یک پروفایل دیگه گرفته
type SwipeAction string
const (
SwipeLike SwipeAction = "like"
SwipeSuperlike SwipeAction = "superlike"
SwipePass SwipeAction = "pass"
)
// Swipe ثبت تصمیم یک کاربر (لایک/ردّ) روی یک کاربر دیگه.
// هر جفت (SwiperID, SwipedID) فقط یک بار می‌تونه ثبت بشه؛ توی discovery feed
// کسایی که قبلاً روشون تصمیم گرفته شده دیگه نشون داده نمی‌شن.
type Swipe struct {
ID uint `gorm:"primaryKey" json:"id"`
SwiperID uint `gorm:"not null;uniqueIndex:idx_swiper_swiped" json:"swiper_id"`
SwipedID uint `gorm:"not null;uniqueIndex:idx_swiper_swiped;index" json:"swiped_id"`
Action SwipeAction `gorm:"size:10;not null" json:"action"`
CreatedAt time.Time `json:"created_at"`
}
func (Swipe) TableName() string {
return "swipes"
}
// Match وقتی ساخته می‌شه که دو کاربر متقابلاً همدیگه رو لایک کرده باشن.
// UserOneID همیشه شناسه‌ی کوچیک‌تره (برای جلوگیری از رکورد تکراری در دو جهت).
type Match struct {
ID uint `gorm:"primaryKey" json:"id"`
UserOneID uint `gorm:"not null;uniqueIndex:idx_match_pair" json:"user_one_id"`
UserTwoID uint `gorm:"not null;uniqueIndex:idx_match_pair" json:"user_two_id"`
CreatedAt time.Time `json:"created_at"`
UserOne *User `gorm:"foreignKey:UserOneID" json:"-"`
UserTwo *User `gorm:"foreignKey:UserTwoID" json:"-"`
}
func (Match) TableName() string {
return "matches"
}
// Message یک پیام داخل یک مچ. از رمزنگاری سرتاسری (E2EE) استفاده می‌شه:
// سرور فقط CipherText+Nonce (خروجی رمزنگاری‌شده‌ی سمت کلاینت با NaCl box،
// X25519-XSalsa20-Poly1305) رو ذخیره می‌کنه و هیچ‌وقت متن خام پیام رو نمی‌بینه.
// Text قدیمی (قبل از اضافه شدن E2EE) برای نمایش پیام‌های تاریخی نگه داشته می‌شه؛
// پیام‌های جدید Text خالی دارن و به‌جاش CipherText/Nonce پر می‌شه.
type Message struct {
ID uint `gorm:"primaryKey" json:"id"`
MatchID uint `gorm:"not null;index" json:"match_id"`
SenderID uint `gorm:"not null" json:"sender_id"`
Text string `gorm:"size:2000;not null" json:"text"`
CipherText *string `gorm:"size:12000" json:"cipher_text,omitempty"`
Nonce *string `gorm:"size:64" json:"nonce,omitempty"`
ReadAt *time.Time `json:"read_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
func (Message) TableName() string {
return "messages"
}