v0.0.30 Добавлено получение информации об авторе клипа и авторе комментария к нему
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
admin 2025-09-02 21:57:58 +03:00
parent df2871357a
commit 7ae6060e61
4 changed files with 152 additions and 68 deletions

View File

@ -5,14 +5,15 @@ import "time"
type Clip struct { type Clip struct {
ID int `json:"id"` ID int `json:"id"`
Title string `json:"title"` Title string `json:"title"`
VideoURL string `json:"video_url"` VideoURL string `json:"videoUrl"`
ThumbnailURL string `json:"thumbnail_url"` ThumbnailURL string `json:"thumbnailUrl"`
Duration int `json:"duration"` // seconds Duration int `json:"duration"`
AuthorID int `json:"author_id"` AuthorID int `json:"-"`
LikesCount int `json:"likes_count"` Author *User `json:"author"`
CommentsCount int `json:"comments_count"` LikesCount int `json:"likesCount"`
CreatedAt time.Time `json:"created_at"` CommentsCount int `json:"commentsCount"`
UpdatedAt time.Time `json:"updated_at"` CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
} }
type ClipLike struct { type ClipLike struct {
@ -25,7 +26,8 @@ type ClipLike struct {
type ClipComment struct { type ClipComment struct {
ID int `json:"id"` ID int `json:"id"`
ClipID int `json:"clip_id"` ClipID int `json:"clip_id"`
AuthorID int `json:"author_id"` AuthorID int `json:"-"`
Author *User `json:"author"`
Content string `json:"content"` Content string `json:"content"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`

View File

@ -29,6 +29,19 @@ func (r *clipResolver) IsLiked(ctx context.Context, obj *domain.Clip) (bool, err
return resp.IsLiked, nil return resp.IsLiked, nil
} }
func (r *clipResolver) Author(ctx context.Context, obj *domain.Clip) (*domain.User, error) {
if obj.AuthorID == 0 {
return nil, fmt.Errorf("clip has no author ID")
}
author, err := r.Services.User.GetByID(ctx, obj.AuthorID)
if err != nil {
return nil, fmt.Errorf("failed to get author: %w", err)
}
return author, nil
}
// CreatedAt is the resolver for the createdAt field. // CreatedAt is the resolver for the createdAt field.
func (r *clipResolver) CreatedAt(ctx context.Context, obj *domain.Clip) (string, error) { func (r *clipResolver) CreatedAt(ctx context.Context, obj *domain.Clip) (string, error) {
return obj.CreatedAt.Format(time.RFC3339), nil return obj.CreatedAt.Format(time.RFC3339), nil
@ -401,3 +414,16 @@ func (r *Resolver) ClipLike() ClipLikeResolver { return &clipLikeResolver{r} }
type clipResolver struct{ *Resolver } type clipResolver struct{ *Resolver }
type clipCommentResolver struct{ *Resolver } type clipCommentResolver struct{ *Resolver }
type clipLikeResolver struct{ *Resolver } type clipLikeResolver struct{ *Resolver }
func (r *clipCommentResolver) Author(ctx context.Context, obj *domain.ClipComment) (*domain.User, error) {
if obj.AuthorID == 0 {
return nil, fmt.Errorf("comment has no author ID")
}
author, err := r.Services.User.GetByID(ctx, obj.AuthorID)
if err != nil {
return nil, fmt.Errorf("failed to get author: %w", err)
}
return author, nil
}

View File

@ -71,7 +71,7 @@ type ComplexityRoot struct {
} }
Clip struct { Clip struct {
AuthorID func(childComplexity int) int Author func(childComplexity int) int
CommentsCount func(childComplexity int) int CommentsCount func(childComplexity int) int
CreatedAt func(childComplexity int) int CreatedAt func(childComplexity int) int
Duration func(childComplexity int) int Duration func(childComplexity int) int
@ -85,7 +85,7 @@ type ComplexityRoot struct {
} }
ClipComment struct { ClipComment struct {
AuthorID func(childComplexity int) int Author func(childComplexity int) int
ClipID func(childComplexity int) int ClipID func(childComplexity int) int
Content func(childComplexity int) int Content func(childComplexity int) int
CreatedAt func(childComplexity int) int CreatedAt func(childComplexity int) int
@ -484,12 +484,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.Chat.User2ID(childComplexity), true return e.complexity.Chat.User2ID(childComplexity), true
case "Clip.authorId": case "Clip.author":
if e.complexity.Clip.AuthorID == nil { if e.complexity.Clip.Author == nil {
break break
} }
return e.complexity.Clip.AuthorID(childComplexity), true return e.complexity.Clip.Author(childComplexity), true
case "Clip.commentsCount": case "Clip.commentsCount":
if e.complexity.Clip.CommentsCount == nil { if e.complexity.Clip.CommentsCount == nil {
@ -561,12 +561,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.Clip.VideoURL(childComplexity), true return e.complexity.Clip.VideoURL(childComplexity), true
case "ClipComment.authorId": case "ClipComment.author":
if e.complexity.ClipComment.AuthorID == nil { if e.complexity.ClipComment.Author == nil {
break break
} }
return e.complexity.ClipComment.AuthorID(childComplexity), true return e.complexity.ClipComment.Author(childComplexity), true
case "ClipComment.clipId": case "ClipComment.clipId":
if e.complexity.ClipComment.ClipID == nil { if e.complexity.ClipComment.ClipID == nil {
@ -3312,8 +3312,8 @@ func (ec *executionContext) fieldContext_Clip_duration(_ context.Context, field
return fc, nil return fc, nil
} }
func (ec *executionContext) _Clip_authorId(ctx context.Context, field graphql.CollectedField, obj *domain.Clip) (ret graphql.Marshaler) { func (ec *executionContext) _Clip_author(ctx context.Context, field graphql.CollectedField, obj *domain.Clip) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Clip_authorId(ctx, field) fc, err := ec.fieldContext_Clip_author(ctx, field)
if err != nil { if err != nil {
return graphql.Null return graphql.Null
} }
@ -3326,7 +3326,7 @@ func (ec *executionContext) _Clip_authorId(ctx context.Context, field graphql.Co
}() }()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return obj.AuthorID, nil return obj.Author, nil
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@ -3338,19 +3338,47 @@ func (ec *executionContext) _Clip_authorId(ctx context.Context, field graphql.Co
} }
return graphql.Null return graphql.Null
} }
res := resTmp.(int) res := resTmp.(*domain.User)
fc.Result = res fc.Result = res
return ec.marshalNInt2int(ctx, field.Selections, res) return ec.marshalNUser2ᚖtailly_back_v2ᚋinternalᚋdomainᚐUser(ctx, field.Selections, res)
} }
func (ec *executionContext) fieldContext_Clip_authorId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { func (ec *executionContext) fieldContext_Clip_author(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{ fc = &graphql.FieldContext{
Object: "Clip", Object: "Clip",
Field: field, Field: field,
IsMethod: false, IsMethod: false,
IsResolver: false, IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Int does not have child fields") switch field.Name {
case "id":
return ec.fieldContext_User_id(ctx, field)
case "username":
return ec.fieldContext_User_username(ctx, field)
case "avatar":
return ec.fieldContext_User_avatar(ctx, field)
case "email":
return ec.fieldContext_User_email(ctx, field)
case "emailConfirmedAt":
return ec.fieldContext_User_emailConfirmedAt(ctx, field)
case "createdAt":
return ec.fieldContext_User_createdAt(ctx, field)
case "updatedAt":
return ec.fieldContext_User_updatedAt(ctx, field)
case "followersCount":
return ec.fieldContext_User_followersCount(ctx, field)
case "followingCount":
return ec.fieldContext_User_followingCount(ctx, field)
case "isFollowing":
return ec.fieldContext_User_isFollowing(ctx, field)
case "followers":
return ec.fieldContext_User_followers(ctx, field)
case "following":
return ec.fieldContext_User_following(ctx, field)
case "subscriptionNotifications":
return ec.fieldContext_User_subscriptionNotifications(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
}, },
} }
return fc, nil return fc, nil
@ -3664,8 +3692,8 @@ func (ec *executionContext) fieldContext_ClipComment_clipId(_ context.Context, f
return fc, nil return fc, nil
} }
func (ec *executionContext) _ClipComment_authorId(ctx context.Context, field graphql.CollectedField, obj *domain.ClipComment) (ret graphql.Marshaler) { func (ec *executionContext) _ClipComment_author(ctx context.Context, field graphql.CollectedField, obj *domain.ClipComment) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_ClipComment_authorId(ctx, field) fc, err := ec.fieldContext_ClipComment_author(ctx, field)
if err != nil { if err != nil {
return graphql.Null return graphql.Null
} }
@ -3678,7 +3706,7 @@ func (ec *executionContext) _ClipComment_authorId(ctx context.Context, field gra
}() }()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return obj.AuthorID, nil return obj.Author, nil
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@ -3690,19 +3718,47 @@ func (ec *executionContext) _ClipComment_authorId(ctx context.Context, field gra
} }
return graphql.Null return graphql.Null
} }
res := resTmp.(int) res := resTmp.(*domain.User)
fc.Result = res fc.Result = res
return ec.marshalNInt2int(ctx, field.Selections, res) return ec.marshalNUser2ᚖtailly_back_v2ᚋinternalᚋdomainᚐUser(ctx, field.Selections, res)
} }
func (ec *executionContext) fieldContext_ClipComment_authorId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { func (ec *executionContext) fieldContext_ClipComment_author(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{ fc = &graphql.FieldContext{
Object: "ClipComment", Object: "ClipComment",
Field: field, Field: field,
IsMethod: false, IsMethod: false,
IsResolver: false, IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Int does not have child fields") switch field.Name {
case "id":
return ec.fieldContext_User_id(ctx, field)
case "username":
return ec.fieldContext_User_username(ctx, field)
case "avatar":
return ec.fieldContext_User_avatar(ctx, field)
case "email":
return ec.fieldContext_User_email(ctx, field)
case "emailConfirmedAt":
return ec.fieldContext_User_emailConfirmedAt(ctx, field)
case "createdAt":
return ec.fieldContext_User_createdAt(ctx, field)
case "updatedAt":
return ec.fieldContext_User_updatedAt(ctx, field)
case "followersCount":
return ec.fieldContext_User_followersCount(ctx, field)
case "followingCount":
return ec.fieldContext_User_followingCount(ctx, field)
case "isFollowing":
return ec.fieldContext_User_isFollowing(ctx, field)
case "followers":
return ec.fieldContext_User_followers(ctx, field)
case "following":
return ec.fieldContext_User_following(ctx, field)
case "subscriptionNotifications":
return ec.fieldContext_User_subscriptionNotifications(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
}, },
} }
return fc, nil return fc, nil
@ -7192,8 +7248,8 @@ func (ec *executionContext) fieldContext_Mutation_createClip(ctx context.Context
return ec.fieldContext_Clip_thumbnailUrl(ctx, field) return ec.fieldContext_Clip_thumbnailUrl(ctx, field)
case "duration": case "duration":
return ec.fieldContext_Clip_duration(ctx, field) return ec.fieldContext_Clip_duration(ctx, field)
case "authorId": case "author":
return ec.fieldContext_Clip_authorId(ctx, field) return ec.fieldContext_Clip_author(ctx, field)
case "commentsCount": case "commentsCount":
return ec.fieldContext_Clip_commentsCount(ctx, field) return ec.fieldContext_Clip_commentsCount(ctx, field)
case "likesCount": case "likesCount":
@ -7440,8 +7496,8 @@ func (ec *executionContext) fieldContext_Mutation_createClipComment(ctx context.
return ec.fieldContext_ClipComment_id(ctx, field) return ec.fieldContext_ClipComment_id(ctx, field)
case "clipId": case "clipId":
return ec.fieldContext_ClipComment_clipId(ctx, field) return ec.fieldContext_ClipComment_clipId(ctx, field)
case "authorId": case "author":
return ec.fieldContext_ClipComment_authorId(ctx, field) return ec.fieldContext_ClipComment_author(ctx, field)
case "content": case "content":
return ec.fieldContext_ClipComment_content(ctx, field) return ec.fieldContext_ClipComment_content(ctx, field)
case "createdAt": case "createdAt":
@ -9404,8 +9460,8 @@ func (ec *executionContext) fieldContext_Query_clip(ctx context.Context, field g
return ec.fieldContext_Clip_thumbnailUrl(ctx, field) return ec.fieldContext_Clip_thumbnailUrl(ctx, field)
case "duration": case "duration":
return ec.fieldContext_Clip_duration(ctx, field) return ec.fieldContext_Clip_duration(ctx, field)
case "authorId": case "author":
return ec.fieldContext_Clip_authorId(ctx, field) return ec.fieldContext_Clip_author(ctx, field)
case "commentsCount": case "commentsCount":
return ec.fieldContext_Clip_commentsCount(ctx, field) return ec.fieldContext_Clip_commentsCount(ctx, field)
case "likesCount": case "likesCount":
@ -9483,8 +9539,8 @@ func (ec *executionContext) fieldContext_Query_clips(ctx context.Context, field
return ec.fieldContext_Clip_thumbnailUrl(ctx, field) return ec.fieldContext_Clip_thumbnailUrl(ctx, field)
case "duration": case "duration":
return ec.fieldContext_Clip_duration(ctx, field) return ec.fieldContext_Clip_duration(ctx, field)
case "authorId": case "author":
return ec.fieldContext_Clip_authorId(ctx, field) return ec.fieldContext_Clip_author(ctx, field)
case "commentsCount": case "commentsCount":
return ec.fieldContext_Clip_commentsCount(ctx, field) return ec.fieldContext_Clip_commentsCount(ctx, field)
case "likesCount": case "likesCount":
@ -9562,8 +9618,8 @@ func (ec *executionContext) fieldContext_Query_userClips(ctx context.Context, fi
return ec.fieldContext_Clip_thumbnailUrl(ctx, field) return ec.fieldContext_Clip_thumbnailUrl(ctx, field)
case "duration": case "duration":
return ec.fieldContext_Clip_duration(ctx, field) return ec.fieldContext_Clip_duration(ctx, field)
case "authorId": case "author":
return ec.fieldContext_Clip_authorId(ctx, field) return ec.fieldContext_Clip_author(ctx, field)
case "commentsCount": case "commentsCount":
return ec.fieldContext_Clip_commentsCount(ctx, field) return ec.fieldContext_Clip_commentsCount(ctx, field)
case "likesCount": case "likesCount":
@ -9635,8 +9691,8 @@ func (ec *executionContext) fieldContext_Query_clipComments(ctx context.Context,
return ec.fieldContext_ClipComment_id(ctx, field) return ec.fieldContext_ClipComment_id(ctx, field)
case "clipId": case "clipId":
return ec.fieldContext_ClipComment_clipId(ctx, field) return ec.fieldContext_ClipComment_clipId(ctx, field)
case "authorId": case "author":
return ec.fieldContext_ClipComment_authorId(ctx, field) return ec.fieldContext_ClipComment_author(ctx, field)
case "content": case "content":
return ec.fieldContext_ClipComment_content(ctx, field) return ec.fieldContext_ClipComment_content(ctx, field)
case "createdAt": case "createdAt":
@ -10292,8 +10348,8 @@ func (ec *executionContext) fieldContext_Subscription_clipCreated(_ context.Cont
return ec.fieldContext_Clip_thumbnailUrl(ctx, field) return ec.fieldContext_Clip_thumbnailUrl(ctx, field)
case "duration": case "duration":
return ec.fieldContext_Clip_duration(ctx, field) return ec.fieldContext_Clip_duration(ctx, field)
case "authorId": case "author":
return ec.fieldContext_Clip_authorId(ctx, field) return ec.fieldContext_Clip_author(ctx, field)
case "commentsCount": case "commentsCount":
return ec.fieldContext_Clip_commentsCount(ctx, field) return ec.fieldContext_Clip_commentsCount(ctx, field)
case "likesCount": case "likesCount":
@ -10447,8 +10503,8 @@ func (ec *executionContext) fieldContext_Subscription_commentClipCreated(ctx con
return ec.fieldContext_ClipComment_id(ctx, field) return ec.fieldContext_ClipComment_id(ctx, field)
case "clipId": case "clipId":
return ec.fieldContext_ClipComment_clipId(ctx, field) return ec.fieldContext_ClipComment_clipId(ctx, field)
case "authorId": case "author":
return ec.fieldContext_ClipComment_authorId(ctx, field) return ec.fieldContext_ClipComment_author(ctx, field)
case "content": case "content":
return ec.fieldContext_ClipComment_content(ctx, field) return ec.fieldContext_ClipComment_content(ctx, field)
case "createdAt": case "createdAt":
@ -13915,8 +13971,8 @@ func (ec *executionContext) _Clip(ctx context.Context, sel ast.SelectionSet, obj
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1) atomic.AddUint32(&out.Invalids, 1)
} }
case "authorId": case "author":
out.Values[i] = ec._Clip_authorId(ctx, field, obj) out.Values[i] = ec._Clip_author(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1) atomic.AddUint32(&out.Invalids, 1)
} }
@ -14082,8 +14138,8 @@ func (ec *executionContext) _ClipComment(ctx context.Context, sel ast.SelectionS
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1) atomic.AddUint32(&out.Invalids, 1)
} }
case "authorId": case "author":
out.Values[i] = ec._ClipComment_authorId(ctx, field, obj) out.Values[i] = ec._ClipComment_author(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1) atomic.AddUint32(&out.Invalids, 1)
} }

View File

@ -173,17 +173,17 @@ type MarkNotificationReadResult {
# Клип # Клип
type Clip { type Clip {
id: Int! # Уникальный идентификатор id: Int!
title: String! # Заголовок клипа title: String!
videoUrl: String! # URL видео videoUrl: String!
thumbnailUrl: String! # URL превью thumbnailUrl: String!
duration: Int! # Длительность в секундах duration: Int!
authorId: Int! # ID автора клипа author: User!
commentsCount: Int! # Количество комментариев commentsCount: Int!
likesCount: Int! # Количество лайков likesCount: Int!
isLiked: Boolean! # Лайкнул ли текущий пользователь isLiked: Boolean!
createdAt: String! # Дата создания createdAt: String!
updatedAt: String! # Дата обновления updatedAt: String!
} }
# Лайк клипа # Лайк клипа
@ -196,12 +196,12 @@ type ClipLike {
# Комментарий к клипу # Комментарий к клипу
type ClipComment { type ClipComment {
id: Int! # Уникальный идентификатор id: Int!
clipId: Int! # ID клипа clipId: Int!
authorId: Int! # ID автора комментария author: User!
content: String! # Текст комментария content: String!
createdAt: String! # Дата создания createdAt: String!
updatedAt: String! # Дата обновления updatedAt: String!
} }
scalar Upload scalar Upload