package object import ( "api_yal/internal/domain/account" "api_yal/internal/domain/comment" "time" "api_yal/internal/models" ) // ==================== Object DTOs ==================== // CreateObjectRequest - DTO для создания объекта type CreateObjectRequest struct { OwnerID uint `json:"owner_id" binding:"required"` Title string `json:"title"` ShortName string `json:"short_name" binding:"required,min=1,max=255"` LongName string `json:"long_name"` Type string `json:"type"` Price float64 `json:"price"` PricePeriod string `json:"price_period"` Phone string `json:"phone"` Email string `json:"email" binding:"omitempty,email"` Site string `json:"site" binding:"omitempty,url"` ShortDescription string `json:"short_description"` Description string `json:"description"` Address string `json:"address"` Latitude float64 `json:"latitude" binding:"omitempty,latitude"` Longitude float64 `json:"longitude" binding:"omitempty,longitude"` Status string `json:"status"` IsActive *bool `json:"is_active"` IsVerified *bool `json:"is_verified"` AmenityIDs []uint `json:"amenity_ids"` } // UpdateObjectRequest - DTO для обновления объекта (все поля опциональны) type UpdateObjectRequest struct { Title *string `json:"title"` ShortName *string `json:"short_name" binding:"omitempty,min=1,max=255"` LongName *string `json:"long_name"` Type *string `json:"type"` Price *float64 `json:"price"` PricePeriod *string `json:"price_period"` Phone *string `json:"phone"` Email *string `json:"email" binding:"omitempty,email"` Site *string `json:"site" binding:"omitempty,url"` ShortDescription *string `json:"short_description"` Description *string `json:"description"` Address *string `json:"address"` Latitude *float64 `json:"latitude" binding:"omitempty,latitude"` Longitude *float64 `json:"longitude" binding:"omitempty,longitude"` Status *string `json:"status"` IsActive *bool `json:"is_active"` IsVerified *bool `json:"is_verified"` AmenityIDs []uint `json:"amenity_ids"` } // ObjectResponse - DTO для полного ответа с объектом (включая связанные данные) type ObjectResponse struct { ID uint `json:"id"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` DeletedAt *time.Time `json:"deleted_at,omitempty"` OwnerID uint `json:"owner_id"` Owner *account.AccountResponse `json:"owner,omitempty"` Title string `json:"title"` ShortName string `json:"short_name"` LongName string `json:"long_name"` Type string `json:"type"` Price float64 `json:"price"` PricePeriod string `json:"price_period"` Phone string `json:"phone"` Email string `json:"email"` Site string `json:"site"` ShortDescription string `json:"short_description"` Description string `json:"description"` Address string `json:"address"` Latitude float64 `json:"latitude"` Longitude float64 `json:"longitude"` IsActive bool `json:"is_active"` IsVerified bool `json:"is_verified"` Status string `json:"status"` ViewCount int `json:"view_count"` FeedbackCount int `json:"feedback_count"` TouristRating *RatingResponse `json:"tourist_rating,omitempty"` EntrepreneurRating *RatingResponse `json:"entrepreneur_rating,omitempty"` Feedbacks []FeedbackShortResponse `json:"feedbacks,omitempty"` Images []ImageResponse `json:"images,omitempty"` Amenities []AmenityResponse `json:"amenities,omitempty"` } // ObjectShortResponse - DTO для краткого ответа (списки, вложенные данные) type ObjectShortResponse struct { ID uint `json:"id"` Title string `json:"title"` ShortName string `json:"short_name"` LongName string `json:"long_name"` Type string `json:"type"` Price float64 `json:"price"` PricePeriod string `json:"price_period"` Address string `json:"address"` IsActive bool `json:"is_active"` IsVerified bool `json:"is_verified"` Status string `json:"status"` FeedbackCount int `json:"feedback_count"` // Агрегированные рейтинги для списка TouristAverageScore float64 `json:"tourist_average_score,omitempty"` EntrepreneurAverageScore float64 `json:"entrepreneur_average_score,omitempty"` } // ImageResponse - DTO для изображения type ImageResponse struct { ID uint `json:"id"` ObjectID uint `json:"object_id"` URL string `json:"url"` IsPrimary bool `json:"is_primary"` SortOrder int `json:"sort_order"` } // AmenityResponse - DTO для удобства type AmenityResponse struct { ID uint `json:"id"` Name string `json:"name"` Category string `json:"category,omitempty"` Icon string `json:"icon,omitempty"` Description string `json:"description,omitempty"` } // ObjectListResponse - DTO для списка объектов с пагинацией type ObjectListResponse struct { Items []ObjectShortResponse `json:"items"` Total int64 `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` TotalPages int `json:"total_pages"` } // ==================== Feedback DTOs ==================== // CreateFeedbackRequest - DTO для создания отзыва type CreateFeedbackRequest struct { ObjectID uint `json:"object_id" binding:"required"` Platform models.PlatformType `json:"platform" binding:"required,oneof=entrepreneur tourist"` Score int `json:"score" binding:"required,min=1,max=5"` Text string `json:"text" binding:"required"` } // UpdateFeedbackRequest - DTO для обновления отзыва type UpdateFeedbackRequest struct { Score *int `json:"score" binding:"omitempty,min=1,max=5"` Text *string `json:"text"` } // FeedbackResponse - DTO для полного ответа с отзывом type FeedbackResponse struct { ID uint `json:"id"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` DeletedAt *time.Time `json:"deleted_at,omitempty"` OwnerID uint `json:"owner_id"` Owner *account.AccountResponse `json:"owner,omitempty"` ObjectID uint `json:"object_id"` Object *ObjectShortResponse `json:"object,omitempty"` Platform models.PlatformType `json:"platform"` Score int `json:"score"` Text string `json:"text"` CommentCount int `json:"comment_count"` Comments []comment.CommentShortResponse `json:"comments,omitempty"` } // FeedbackShortResponse - DTO для краткого ответа (вложенный в объект) type FeedbackShortResponse struct { ID uint `json:"id"` CreatedAt time.Time `json:"created_at"` OwnerID uint `json:"owner_id"` OwnerName string `json:"owner_name,omitempty"` // из Account Platform models.PlatformType `json:"platform"` Score int `json:"score"` Text string `json:"text"` } // ==================== Rating DTOs ==================== // RatingResponse - DTO для ответа с рейтингом type RatingResponse struct { ID uint `json:"id"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` Platform models.PlatformType `json:"platform"` AverageScore float64 `json:"average_score"` TotalVotes int `json:"total_votes"` VoteBreakdown VoteBreakdownDTO `json:"vote_breakdown"` } // VoteBreakdownDTO - DTO для детализации оценок type VoteBreakdownDTO struct { Score1 int `json:"score_1"` Score2 int `json:"score_2"` Score3 int `json:"score_3"` Score4 int `json:"score_4"` Score5 int `json:"score_5"` } // CreateRatingVoteRequest - DTO для голосования type CreateRatingVoteRequest struct { Platform models.PlatformType `json:"platform" binding:"required,oneof=entrepreneur tourist"` TargetID uint `json:"target_id" binding:"required"` // ObjectID Score int `json:"score" binding:"required,min=1,max=5"` } // RatingVoteResponse - DTO для ответа о голосе пользователя type RatingVoteResponse struct { ID uint `json:"id"` CreatedAt time.Time `json:"created_at"` Platform models.PlatformType `json:"platform"` TargetID uint `json:"target_id"` VoterID uint `json:"voter_id"` Score int `json:"score"` }