Initial commit: Эфир мессенджер
This commit is contained in:
31
internal/models/attachment.go
Normal file
31
internal/models/attachment.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Attachment struct {
|
||||
ID int64 `json:"id"`
|
||||
MessageID *int64 `json:"message_id,omitempty"`
|
||||
FileName string `json:"file_name"`
|
||||
FileSize int64 `json:"file_size"`
|
||||
StoragePath string `json:"-"` // never send to client
|
||||
MimeType string `json:"mime_type"`
|
||||
UploadedAt time.Time `json:"uploaded_at"`
|
||||
}
|
||||
|
||||
// AttachmentResponse используется для отправки информации о файле клиенту
|
||||
type AttachmentResponse struct {
|
||||
ID int64 `json:"id"`
|
||||
FileName string `json:"file_name"`
|
||||
FileSize int64 `json:"file_size"`
|
||||
MimeType string `json:"mime_type"`
|
||||
UploadURL string `json:"upload_url"` // URL для скачивания
|
||||
UploadedAt time.Time `json:"uploaded_at"`
|
||||
}
|
||||
|
||||
// UploadFileRequest DTO для загрузки файла
|
||||
type UploadFileRequest struct {
|
||||
ChatID int64 `json:"chat_id"`
|
||||
// файл будет в multipart form
|
||||
}
|
||||
70
internal/models/chat.go
Normal file
70
internal/models/chat.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type ChatType string
|
||||
|
||||
const (
|
||||
ChatTypePrivate ChatType = "private"
|
||||
ChatTypeGroup ChatType = "group"
|
||||
)
|
||||
|
||||
type MemberRole string
|
||||
|
||||
const (
|
||||
MemberRoleMember MemberRole = "member"
|
||||
MemberRoleAdmin MemberRole = "admin"
|
||||
)
|
||||
|
||||
type Chat struct {
|
||||
ID int64 `json:"id"`
|
||||
Type ChatType `json:"type"`
|
||||
Title *string `json:"title,omitempty"` // только для групп
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
type ChatMember struct {
|
||||
ChatID int64 `json:"chat_id"`
|
||||
UserID int64 `json:"user_id"`
|
||||
Role MemberRole `json:"role"`
|
||||
JoinedAt time.Time `json:"joined_at"`
|
||||
}
|
||||
|
||||
// ChatWithDetails используется для возврата чата с дополнительной информацией
|
||||
type ChatWithDetails struct {
|
||||
ID int64 `json:"id"`
|
||||
Type ChatType `json:"type"`
|
||||
Title *string `json:"title,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
LastMessage *Message `json:"last_message,omitempty"`
|
||||
UnreadCount int `json:"unread_count,omitempty"`
|
||||
ParticipantIDs []int64 `json:"participant_ids,omitempty"`
|
||||
}
|
||||
|
||||
// CreatePrivateChatRequest DTO для создания личного чата
|
||||
type CreatePrivateChatRequest struct {
|
||||
TargetLogin string `json:"target_login"`
|
||||
}
|
||||
|
||||
// CreateGroupChatRequest DTO для создания группового чата
|
||||
type CreateGroupChatRequest struct {
|
||||
Title string `json:"title"`
|
||||
MemberLogins []string `json:"member_logins"`
|
||||
}
|
||||
|
||||
// AddMembersRequest DTO для добавления участников в группу
|
||||
type AddMembersRequest struct {
|
||||
UserLogins []string `json:"user_logins"`
|
||||
}
|
||||
|
||||
// UpdateMemberRoleRequest DTO для обновления роли участника
|
||||
type UpdateMemberRoleRequest struct {
|
||||
Role MemberRole `json:"role"`
|
||||
}
|
||||
|
||||
// UpdateChatTitleRequest DTO для обновления названия чата
|
||||
type UpdateChatTitleRequest struct {
|
||||
Title string `json:"title"`
|
||||
}
|
||||
45
internal/models/message.go
Normal file
45
internal/models/message.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
ID int64 `json:"id"`
|
||||
ChatID int64 `json:"chat_id"`
|
||||
SenderID int64 `json:"sender_id"`
|
||||
EncryptedBody []byte `json:"-"` // never send raw encrypted body
|
||||
Plaintext string `json:"plaintext,omitempty"` // используется только после расшифровки
|
||||
AttachmentID *int64 `json:"attachment_id,omitempty"`
|
||||
IsRead bool `json:"is_read"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// MessageResponse используется для отправки сообщений клиенту
|
||||
type MessageResponse struct {
|
||||
ID int64 `json:"id"`
|
||||
ChatID int64 `json:"chat_id"`
|
||||
SenderID int64 `json:"sender_id"`
|
||||
Plaintext string `json:"plaintext"` // расшифрованный текст
|
||||
Attachment *Attachment `json:"attachment,omitempty"`
|
||||
IsRead bool `json:"is_read"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// SendMessageRequest DTO для отправки сообщения
|
||||
type SendMessageRequest struct {
|
||||
ChatID int64 `json:"chat_id"`
|
||||
Plaintext string `json:"plaintext"`
|
||||
AttachmentID *int64 `json:"attachment_id,omitempty"`
|
||||
}
|
||||
|
||||
// EditMessageRequest DTO для редактирования сообщения
|
||||
type EditMessageRequest struct {
|
||||
Plaintext string `json:"plaintext"`
|
||||
}
|
||||
|
||||
// GetMessagesRequest DTO для запроса истории
|
||||
type GetMessagesRequest struct {
|
||||
Limit int `json:"limit"` // количество сообщений
|
||||
Before string `json:"before"` // timestamp (RFC3339)
|
||||
}
|
||||
16
internal/models/profile.go
Normal file
16
internal/models/profile.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package models
|
||||
|
||||
type Profile struct {
|
||||
UserID int64 `json:"user_id"`
|
||||
DisplayName *string `json:"display_name,omitempty"`
|
||||
Bio *string `json:"bio,omitempty"`
|
||||
AvatarURL *string `json:"avatar_url,omitempty"`
|
||||
}
|
||||
|
||||
// ProfileWithUser объединяет профиль с безопасными данными пользователя
|
||||
type ProfileWithUser struct {
|
||||
User *SafeUser `json:"user"`
|
||||
DisplayName *string `json:"display_name,omitempty"`
|
||||
Bio *string `json:"bio,omitempty"`
|
||||
AvatarURL *string `json:"avatar_url,omitempty"`
|
||||
}
|
||||
45
internal/models/user.go
Normal file
45
internal/models/user.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserRole string
|
||||
|
||||
const (
|
||||
RoleUser UserRole = "user"
|
||||
RoleGlobalAdmin UserRole = "global_admin"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID int64 `json:"id"`
|
||||
Login string `json:"login"`
|
||||
PasswordHash string `json:"-"` // never send to client
|
||||
Role UserRole `json:"role"`
|
||||
LastSeen *time.Time `json:"last_seen,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// SafeUser возвращает пользователя без чувствительных данных
|
||||
type SafeUser struct {
|
||||
ID int64 `json:"id"`
|
||||
Login string `json:"login"`
|
||||
Role UserRole `json:"role"`
|
||||
LastSeen *time.Time `json:"last_seen,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (u *User) ToSafe() *SafeUser {
|
||||
return &SafeUser{
|
||||
ID: u.ID,
|
||||
Login: u.Login,
|
||||
Role: u.Role,
|
||||
LastSeen: u.LastSeen,
|
||||
CreatedAt: u.CreatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
// IsGlobalAdmin проверяет, является ли пользователь глобальным админом
|
||||
func (u *User) IsGlobalAdmin() bool {
|
||||
return u.Role == RoleGlobalAdmin
|
||||
}
|
||||
Reference in New Issue
Block a user