On branch main
modified: main_dc/yalarba/api_yal/go.sum modified: main_dc/yalarba/api_yal/internal/domain/account/dto.go modified: main_dc/yalarba/api_yal/internal/models/account.go modified: main_dc/yalarba/api_yal/internal/models/appeal.go modified: main_dc/yalarba/api_yal/internal/models/comment.go modified: main_dc/yalarba/api_yal/internal/models/feedback.go modified: main_dc/yalarba/api_yal/internal/models/password_reset.go modified: main_dc/yalarba/api_yal/internal/models/rating.go modified: "main_dc/yalarba/api_yal/internal/models/\320\276bject.go" set embedded base model anonimus as realy embedded struct without set name for field base
This commit is contained in:
@@ -44,20 +44,12 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
|||||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
|
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
|
||||||
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
|
||||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
|
||||||
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
|
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
|
||||||
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
|
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
|
||||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
|
||||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
|
||||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
|
||||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
|
||||||
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
||||||
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
|
||||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
|
||||||
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
|
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
|
||||||
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
|
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|||||||
@@ -1 +1,220 @@
|
|||||||
package account
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
"api_yal/internal/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ==================== Request DTOs ====================
|
||||||
|
|
||||||
|
// CreateAccountRequest - DTO для создания нового аккаунта
|
||||||
|
type CreateAccountRequest struct {
|
||||||
|
Email string `json:"email" binding:"required,email"`
|
||||||
|
Password string `json:"password" binding:"required,min=6"`
|
||||||
|
FullName string `json:"full_name" binding:"required"`
|
||||||
|
FirstName string `json:"first_name" binding:"required"`
|
||||||
|
LastName string `json:"last_name" binding:"required"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
City string `json:"city"`
|
||||||
|
|
||||||
|
// Бизнес информация
|
||||||
|
OrganizationForm string `json:"organization_form"`
|
||||||
|
OrganizationName string `json:"organization_name"`
|
||||||
|
OrganizationShort string `json:"organization_short"`
|
||||||
|
INN string `json:"inn"`
|
||||||
|
PersonalINN string `json:"personal_inn"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateAccountRequest - DTO для обновления аккаунта
|
||||||
|
type UpdateAccountRequest struct {
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
FirstName string `json:"first_name"`
|
||||||
|
LastName string `json:"last_name"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
City string `json:"city"`
|
||||||
|
|
||||||
|
// Бизнес информация
|
||||||
|
OrganizationForm string `json:"organization_form"`
|
||||||
|
OrganizationName string `json:"organization_name"`
|
||||||
|
OrganizationShort string `json:"organization_short"`
|
||||||
|
INN string `json:"inn"`
|
||||||
|
PersonalINN string `json:"personal_inn"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChangePasswordRequest - DTO для смены пароля
|
||||||
|
type ChangePasswordRequest struct {
|
||||||
|
CurrentPassword string `json:"current_password" binding:"required"`
|
||||||
|
NewPassword string `json:"new_password" binding:"required,min=6"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ForgotPasswordRequest - DTO для запроса сброса пароля
|
||||||
|
type ForgotPasswordRequest struct {
|
||||||
|
Email string `json:"email" binding:"required,email"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetPasswordRequest - DTO для сброса пароля по токену
|
||||||
|
type ResetPasswordRequest struct {
|
||||||
|
Token string `json:"token" binding:"required"`
|
||||||
|
NewPassword string `json:"new_password" binding:"required,min=6"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyAccountRequest - DTO для верификации аккаунта (админ)
|
||||||
|
type VerifyAccountRequest struct {
|
||||||
|
IsVerified bool `json:"is_verified"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateAccountStatusRequest - DTO для изменения статуса аккаунта (админ)
|
||||||
|
type UpdateAccountStatusRequest struct {
|
||||||
|
IsActive bool `json:"is_active"`
|
||||||
|
Role string `json:"role" binding:"omitempty,oneof=user admin moderator"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAccountsRequest - DTO для фильтрации списка аккаунтов
|
||||||
|
type ListAccountsRequest struct {
|
||||||
|
Page int `form:"page" binding:"min=1"`
|
||||||
|
PageSize int `form:"page_size" binding:"min=1,max=100"`
|
||||||
|
Search string `form:"search"`
|
||||||
|
Role string `form:"role" binding:"omitempty,oneof=user admin moderator"`
|
||||||
|
IsActive *bool `form:"is_active"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== Response DTOs ====================
|
||||||
|
|
||||||
|
// AccountResponse - базовый DTO для ответа с данными аккаунта (без чувствительной информации)
|
||||||
|
type AccountResponse struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
|
||||||
|
// Основная информация
|
||||||
|
Email string `json:"email"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
FirstName string `json:"first_name"`
|
||||||
|
LastName string `json:"last_name"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
City string `json:"city"`
|
||||||
|
|
||||||
|
// Бизнес информация
|
||||||
|
OrganizationForm string `json:"organization_form,omitempty"`
|
||||||
|
OrganizationName string `json:"organization_name,omitempty"`
|
||||||
|
OrganizationShort string `json:"organization_short,omitempty"`
|
||||||
|
INN string `json:"inn,omitempty"`
|
||||||
|
PersonalINN string `json:"personal_inn,omitempty"`
|
||||||
|
|
||||||
|
// Статус
|
||||||
|
IsActive bool `json:"is_active"`
|
||||||
|
IsVerified bool `json:"is_verified"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AccountWithObjectsResponse - DTO с объектами аккаунта
|
||||||
|
type AccountWithObjectsResponse struct {
|
||||||
|
AccountResponse
|
||||||
|
Objects []ObjectBriefResponse `json:"objects,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ObjectBriefResponse - краткая информация об объекте для вложенных ответов
|
||||||
|
type ObjectBriefResponse struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
ShortName string `json:"short_name"`
|
||||||
|
LongName string `json:"long_name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
IsActive bool `json:"is_active"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AccountListResponse - DTO для списка аккаунтов с пагинацией
|
||||||
|
type AccountListResponse struct {
|
||||||
|
Items []AccountResponse `json:"items"`
|
||||||
|
Total int64 `json:"total"`
|
||||||
|
Page int `json:"page"`
|
||||||
|
PageSize int `json:"page_size"`
|
||||||
|
TotalPages int `json:"total_pages"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AccountProfileResponse - DTO для личного кабинета (более детальная информация)
|
||||||
|
type AccountProfileResponse struct {
|
||||||
|
AccountResponse
|
||||||
|
Stats AccountStats `json:"stats"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AccountStats - статистика аккаунта
|
||||||
|
type AccountStats struct {
|
||||||
|
ObjectsCount int `json:"objects_count"`
|
||||||
|
FeedbacksCount int `json:"feedbacks_count"`
|
||||||
|
CommentsCount int `json:"comments_count"`
|
||||||
|
RatingsCount int `json:"ratings_count"`
|
||||||
|
AppealsCount int `json:"appeals_count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthResponse - DTO для ответа при авторизации
|
||||||
|
type AuthResponse struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
TokenType string `json:"token_type"`
|
||||||
|
ExpiresAt int64 `json:"expires_at"`
|
||||||
|
Account AccountResponse `json:"account"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PasswordResetResponse - DTO для ответа о сбросе пароля
|
||||||
|
type PasswordResetResponse struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
Token string `json:"token,omitempty"` // только при создании, не для продакшена
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== Helper functions ====================
|
||||||
|
|
||||||
|
// ToAccountResponse преобразует модель Account в AccountResponse
|
||||||
|
func ToAccountResponse(account *models.Account) AccountResponse {
|
||||||
|
return AccountResponse{
|
||||||
|
ID: account.ID,
|
||||||
|
CreatedAt: account.CreatedAt,
|
||||||
|
UpdatedAt: account.UpdatedAt,
|
||||||
|
Email: account.Email,
|
||||||
|
FullName: account.FullName,
|
||||||
|
FirstName: account.FirstName,
|
||||||
|
LastName: account.LastName,
|
||||||
|
Phone: account.Phone,
|
||||||
|
City: account.City,
|
||||||
|
OrganizationForm: account.OrganizationForm,
|
||||||
|
OrganizationName: account.OrganizationName,
|
||||||
|
OrganizationShort: account.OrganizationShort,
|
||||||
|
INN: account.INN,
|
||||||
|
PersonalINN: account.PersonalINN,
|
||||||
|
IsActive: account.IsActive,
|
||||||
|
IsVerified: account.IsVerified,
|
||||||
|
Role: account.Role,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToAccountWithObjectsResponse преобразует модель Account в AccountWithObjectsResponse
|
||||||
|
func ToAccountWithObjectsResponse(account *models.Account) AccountWithObjectsResponse {
|
||||||
|
resp := AccountWithObjectsResponse{
|
||||||
|
AccountResponse: ToAccountResponse(account),
|
||||||
|
Objects: make([]ObjectBriefResponse, 0, len(account.Objects)),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, obj := range account.Objects {
|
||||||
|
resp.Objects = append(resp.Objects, ObjectBriefResponse{
|
||||||
|
ID: obj.ID,
|
||||||
|
ShortName: obj.ShortName,
|
||||||
|
LongName: obj.LongName,
|
||||||
|
Type: obj.Type,
|
||||||
|
IsActive: obj.IsActive,
|
||||||
|
Address: obj.Address,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToObjectBriefResponse преобразует модель Object в ObjectBriefResponse
|
||||||
|
func ToObjectBriefResponse(object *models.Object) ObjectBriefResponse {
|
||||||
|
return ObjectBriefResponse{
|
||||||
|
ID: object.ID,
|
||||||
|
ShortName: object.ShortName,
|
||||||
|
LongName: object.LongName,
|
||||||
|
Type: object.Type,
|
||||||
|
IsActive: object.IsActive,
|
||||||
|
Address: object.Address,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ import ()
|
|||||||
|
|
||||||
type Account struct {
|
type Account struct {
|
||||||
/*ID, CreatedAt, UpdatedAt, DeletedAt (Update's history)*/
|
/*ID, CreatedAt, UpdatedAt, DeletedAt (Update's history)*/
|
||||||
Base Base `gorm:"embedded"`
|
Base `gorm:"embedded"`
|
||||||
|
|
||||||
// Основная информация
|
// Основная информация
|
||||||
Email string `gorm:"uniqueIndex;not null" json:"email"`
|
Email string `gorm:"uniqueIndex;not null" json:"email"`
|
||||||
@@ -27,9 +27,6 @@ type Account struct {
|
|||||||
IsVerified bool `gorm:"default:false" json:"is_verified"`
|
IsVerified bool `gorm:"default:false" json:"is_verified"`
|
||||||
Role string `gorm:"default:user" json:"role"` // user, admin, moderator
|
Role string `gorm:"default:user" json:"role"` // user, admin, moderator
|
||||||
|
|
||||||
|
|
||||||
// Связь: один Account имеет много Objects
|
// Связь: один Account имеет много Objects
|
||||||
Objects []Object `gorm:"foreignKey:OwnerID" json:"objects"`
|
Objects []Object `gorm:"foreignKey:OwnerID" json:"objects"`
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ const (
|
|||||||
// Appeal представляет обращение пользователя (жалоба, предложение, пожелание)
|
// Appeal представляет обращение пользователя (жалоба, предложение, пожелание)
|
||||||
type Appeal struct {
|
type Appeal struct {
|
||||||
/*ID, CreatedAt, UpdatedAt, DeletedAt (Update's history)*/
|
/*ID, CreatedAt, UpdatedAt, DeletedAt (Update's history)*/
|
||||||
Base Base `gorm:"embedded"`
|
Base `gorm:"embedded"`
|
||||||
|
|
||||||
// Автор обращения (может быть анонимным)
|
// Автор обращения (может быть анонимным)
|
||||||
AuthorID *uint `gorm:"index" json:"author_id,omitempty"` // NULL для анонимных обращений
|
AuthorID *uint `gorm:"index" json:"author_id,omitempty"` // NULL для анонимных обращений
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import ()
|
|||||||
// Comment представляет комментарий к отзыву (Feedback)
|
// Comment представляет комментарий к отзыву (Feedback)
|
||||||
type Comment struct {
|
type Comment struct {
|
||||||
/*ID, CreatedAt, UpdatedAt, DeletedAt (Update's history)*/
|
/*ID, CreatedAt, UpdatedAt, DeletedAt (Update's history)*/
|
||||||
Base Base `gorm:"embedded"`
|
Base `gorm:"embedded"`
|
||||||
|
|
||||||
// Автор комментария
|
// Автор комментария
|
||||||
AuthorID uint `gorm:"not null;index" json:"author_id"`
|
AuthorID uint `gorm:"not null;index" json:"author_id"`
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import ()
|
|||||||
|
|
||||||
type Feedback struct {
|
type Feedback struct {
|
||||||
/*ID, CreatedAt, UpdatedAt, DeletedAt (Update's history)*/
|
/*ID, CreatedAt, UpdatedAt, DeletedAt (Update's history)*/
|
||||||
Base Base `gorm:"embedded"`
|
Base `gorm:"embedded"`
|
||||||
|
|
||||||
// owner account ID
|
// owner account ID
|
||||||
OwnerID uint `gorm:"not null;index" json:"owner_id"`
|
OwnerID uint `gorm:"not null;index" json:"owner_id"`
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
// PasswordReset модель для хранения токенов сброса пароля
|
// PasswordReset модель для хранения токенов сброса пароля
|
||||||
type PasswordReset struct {
|
type PasswordReset struct {
|
||||||
Base
|
Base `gorm:"embedded"`
|
||||||
AccountID uint `gorm:"not null;index" json:"account_id"`
|
AccountID uint `gorm:"not null;index" json:"account_id"`
|
||||||
Token string `gorm:"type:varchar(255);uniqueIndex;not null" json:"token"`
|
Token string `gorm:"type:varchar(255);uniqueIndex;not null" json:"token"`
|
||||||
ExpiresAt time.Time `gorm:"not null" json:"expires_at"`
|
ExpiresAt time.Time `gorm:"not null" json:"expires_at"`
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const (
|
|||||||
type Rating struct {
|
type Rating struct {
|
||||||
// Base содержит общие поля для всех моделей:
|
// Base содержит общие поля для всех моделей:
|
||||||
// ID, CreatedAt, UpdatedAt, DeletedAt (история обновлений)
|
// ID, CreatedAt, UpdatedAt, DeletedAt (история обновлений)
|
||||||
Base Base `gorm:"embedded"`
|
Base `gorm:"embedded"`
|
||||||
|
|
||||||
// OwnerID - идентификатор владельца рейтинга (аккаунта)
|
// OwnerID - идентификатор владельца рейтинга (аккаунта)
|
||||||
OwnerID uint `json:"owner_id"`
|
OwnerID uint `json:"owner_id"`
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import ()
|
|||||||
|
|
||||||
type Object struct {
|
type Object struct {
|
||||||
/*ID, CreatedAt, UpdatedAt, DeletedAt (Update's history)*/
|
/*ID, CreatedAt, UpdatedAt, DeletedAt (Update's history)*/
|
||||||
Base Base `gorm:"embedded"`
|
Base `gorm:"embedded"`
|
||||||
|
|
||||||
// owner account ID
|
// owner account ID
|
||||||
OwnerID uint `json:"owner_id"`
|
OwnerID uint `json:"owner_id"`
|
||||||
|
|||||||
Reference in New Issue
Block a user