v0.0.12 Добавлен avatar для пользователей, а также реализован резолвер получения всех пользователей
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
7e1fad19c2
commit
562c4c2228
@ -96,9 +96,11 @@ func main() {
|
||||
|
||||
// Запуск сервера в отдельной горутине
|
||||
go func() {
|
||||
log.Println("server started")
|
||||
if err := server.Run(); err != nil {
|
||||
log.Printf("server error: %v", err)
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
// Ожидание сигнала завершения
|
||||
|
||||
@ -3,7 +3,6 @@ package config
|
||||
import (
|
||||
"github.com/caarlos0/env/v8"
|
||||
"github.com/joho/godotenv"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -40,9 +39,5 @@ func Load() (*Config, error) {
|
||||
if err := env.Parse(cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Для отладки (можно убрать в продакшене)
|
||||
log.Printf("Config loaded: %+v", cfg)
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
type User struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Avatar string `json:"avatar"`
|
||||
Email string `json:"email"`
|
||||
EmailConfirmationToken string `json:"-"`
|
||||
EmailConfirmedAt *time.Time `json:"emailConfirmedAt,omitempty"`
|
||||
|
||||
@ -113,7 +113,7 @@ type ComplexityRoot struct {
|
||||
SendMessage func(childComplexity int, receiverID int, content string) int
|
||||
TerminateSession func(childComplexity int, sessionID int) int
|
||||
UnlikePost func(childComplexity int, postID int) int
|
||||
UpdateProfile func(childComplexity int, username string, email string) int
|
||||
UpdateProfile func(childComplexity int, username string, email string, avatar string) int
|
||||
}
|
||||
|
||||
Post struct {
|
||||
@ -137,6 +137,7 @@ type ComplexityRoot struct {
|
||||
Post func(childComplexity int, id int) int
|
||||
Posts func(childComplexity int) int
|
||||
User func(childComplexity int, id int) int
|
||||
Users func(childComplexity int) int
|
||||
}
|
||||
|
||||
Session struct {
|
||||
@ -160,6 +161,7 @@ type ComplexityRoot struct {
|
||||
}
|
||||
|
||||
User struct {
|
||||
Avatar func(childComplexity int) int
|
||||
CreatedAt func(childComplexity int) int
|
||||
Email func(childComplexity int) int
|
||||
EmailConfirmedAt func(childComplexity int) int
|
||||
@ -197,7 +199,7 @@ type MutationResolver interface {
|
||||
CreateComment(ctx context.Context, postID int, content string) (*domain.Comment, error)
|
||||
LikePost(ctx context.Context, postID int) (*domain.Like, error)
|
||||
UnlikePost(ctx context.Context, postID int) (bool, error)
|
||||
UpdateProfile(ctx context.Context, username string, email string) (*domain.User, error)
|
||||
UpdateProfile(ctx context.Context, username string, email string, avatar string) (*domain.User, error)
|
||||
ChangePassword(ctx context.Context, oldPassword string, newPassword string) (bool, error)
|
||||
SendMessage(ctx context.Context, receiverID int, content string) (*domain.Message, error)
|
||||
MarkAsRead(ctx context.Context, messageID int) (bool, error)
|
||||
@ -222,6 +224,7 @@ type QueryResolver interface {
|
||||
Post(ctx context.Context, id int) (*domain.Post, error)
|
||||
Posts(ctx context.Context) ([]*domain.Post, error)
|
||||
User(ctx context.Context, id int) (*domain.User, error)
|
||||
Users(ctx context.Context) ([]*domain.User, error)
|
||||
GetChatHistory(ctx context.Context, userID int) ([]*domain.Message, error)
|
||||
GetUserChats(ctx context.Context) ([]*ChatSession, error)
|
||||
MySessions(ctx context.Context) ([]*domain.Session, error)
|
||||
@ -622,7 +625,7 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.complexity.Mutation.UpdateProfile(childComplexity, args["username"].(string), args["email"].(string)), true
|
||||
return e.complexity.Mutation.UpdateProfile(childComplexity, args["username"].(string), args["email"].(string), args["avatar"].(string)), true
|
||||
|
||||
case "Post.author":
|
||||
if e.complexity.Post.Author == nil {
|
||||
@ -758,6 +761,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
|
||||
return e.complexity.Query.User(childComplexity, args["id"].(int)), true
|
||||
|
||||
case "Query.users":
|
||||
if e.complexity.Query.Users == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Query.Users(childComplexity), true
|
||||
|
||||
case "Session.device":
|
||||
if e.complexity.Session.Device == nil {
|
||||
break
|
||||
@ -835,6 +845,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
|
||||
return e.complexity.Tokens.RefreshTokenExpires(childComplexity), true
|
||||
|
||||
case "User.avatar":
|
||||
if e.complexity.User.Avatar == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.User.Avatar(childComplexity), true
|
||||
|
||||
case "User.createdAt":
|
||||
if e.complexity.User.CreatedAt == nil {
|
||||
break
|
||||
@ -1232,6 +1249,11 @@ func (ec *executionContext) field_Mutation_updateProfile_args(ctx context.Contex
|
||||
return nil, err
|
||||
}
|
||||
args["email"] = arg1
|
||||
arg2, err := processArgField(ctx, rawArgs, "avatar", ec.unmarshalNString2string)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
args["avatar"] = arg2
|
||||
return args, nil
|
||||
}
|
||||
|
||||
@ -1374,6 +1396,8 @@ func (ec *executionContext) fieldContext_ChatSession_user(_ context.Context, fie
|
||||
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":
|
||||
@ -1688,6 +1712,8 @@ func (ec *executionContext) fieldContext_Comment_author(_ context.Context, field
|
||||
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":
|
||||
@ -2164,6 +2190,8 @@ func (ec *executionContext) fieldContext_Like_user(_ context.Context, field grap
|
||||
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":
|
||||
@ -2310,6 +2338,8 @@ func (ec *executionContext) fieldContext_Message_sender(_ context.Context, field
|
||||
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":
|
||||
@ -2368,6 +2398,8 @@ func (ec *executionContext) fieldContext_Message_receiver(_ context.Context, fie
|
||||
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":
|
||||
@ -2558,6 +2590,8 @@ func (ec *executionContext) fieldContext_Mutation_register(ctx context.Context,
|
||||
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":
|
||||
@ -2998,7 +3032,7 @@ func (ec *executionContext) _Mutation_updateProfile(ctx context.Context, field g
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return ec.resolvers.Mutation().UpdateProfile(rctx, fc.Args["username"].(string), fc.Args["email"].(string))
|
||||
return ec.resolvers.Mutation().UpdateProfile(rctx, fc.Args["username"].(string), fc.Args["email"].(string), fc.Args["avatar"].(string))
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
@ -3027,6 +3061,8 @@ func (ec *executionContext) fieldContext_Mutation_updateProfile(ctx context.Cont
|
||||
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":
|
||||
@ -3727,6 +3763,8 @@ func (ec *executionContext) fieldContext_Post_author(_ context.Context, field gr
|
||||
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":
|
||||
@ -4073,6 +4111,8 @@ func (ec *executionContext) fieldContext_Query_me(_ context.Context, field graph
|
||||
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":
|
||||
@ -4274,6 +4314,8 @@ func (ec *executionContext) fieldContext_Query_user(ctx context.Context, field g
|
||||
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":
|
||||
@ -4300,6 +4342,66 @@ func (ec *executionContext) fieldContext_Query_user(ctx context.Context, field g
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Query_users(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_Query_users(ctx, field)
|
||||
if err != nil {
|
||||
return graphql.Null
|
||||
}
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return ec.resolvers.Query().Users(rctx)
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.([]*domain.User)
|
||||
fc.Result = res
|
||||
return ec.marshalNUser2ᚕᚖtailly_back_v2ᚋinternalᚋdomainᚐUserᚄ(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Query_users(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "Query",
|
||||
Field: field,
|
||||
IsMethod: true,
|
||||
IsResolver: true,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
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)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Query_getChatHistory(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_Query_getChatHistory(ctx, field)
|
||||
if err != nil {
|
||||
@ -5220,6 +5322,50 @@ func (ec *executionContext) fieldContext_User_username(_ context.Context, field
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _User_avatar(ctx context.Context, field graphql.CollectedField, obj *domain.User) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_User_avatar(ctx, field)
|
||||
if err != nil {
|
||||
return graphql.Null
|
||||
}
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.Avatar, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(string)
|
||||
fc.Result = res
|
||||
return ec.marshalNString2string(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_User_avatar(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "User",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type String does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _User_email(ctx context.Context, field graphql.CollectedField, obj *domain.User) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_User_email(ctx, field)
|
||||
if err != nil {
|
||||
@ -8626,6 +8772,28 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
||||
func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
|
||||
}
|
||||
|
||||
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
|
||||
case "users":
|
||||
field := field
|
||||
|
||||
innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
}
|
||||
}()
|
||||
res = ec._Query_users(ctx, field)
|
||||
if res == graphql.Null {
|
||||
atomic.AddUint32(&fs.Invalids, 1)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
rrm := func(ctx context.Context) graphql.Marshaler {
|
||||
return ec.OperationContext.RootResolverMiddleware(ctx,
|
||||
func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
|
||||
}
|
||||
|
||||
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
|
||||
case "getChatHistory":
|
||||
field := field
|
||||
@ -9007,6 +9175,11 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj
|
||||
if out.Values[i] == graphql.Null {
|
||||
atomic.AddUint32(&out.Invalids, 1)
|
||||
}
|
||||
case "avatar":
|
||||
out.Values[i] = ec._User_avatar(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
atomic.AddUint32(&out.Invalids, 1)
|
||||
}
|
||||
case "email":
|
||||
out.Values[i] = ec._User_email(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
@ -9905,6 +10078,50 @@ func (ec *executionContext) marshalNUser2tailly_back_v2ᚋinternalᚋdomainᚐUs
|
||||
return ec._User(ctx, sel, &v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNUser2ᚕᚖtailly_back_v2ᚋinternalᚋdomainᚐUserᚄ(ctx context.Context, sel ast.SelectionSet, v []*domain.User) graphql.Marshaler {
|
||||
ret := make(graphql.Array, len(v))
|
||||
var wg sync.WaitGroup
|
||||
isLen1 := len(v) == 1
|
||||
if !isLen1 {
|
||||
wg.Add(len(v))
|
||||
}
|
||||
for i := range v {
|
||||
i := i
|
||||
fc := &graphql.FieldContext{
|
||||
Index: &i,
|
||||
Result: &v[i],
|
||||
}
|
||||
ctx := graphql.WithFieldContext(ctx, fc)
|
||||
f := func(i int) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = nil
|
||||
}
|
||||
}()
|
||||
if !isLen1 {
|
||||
defer wg.Done()
|
||||
}
|
||||
ret[i] = ec.marshalNUser2ᚖtailly_back_v2ᚋinternalᚋdomainᚐUser(ctx, sel, v[i])
|
||||
}
|
||||
if isLen1 {
|
||||
f(i)
|
||||
} else {
|
||||
go f(i)
|
||||
}
|
||||
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
for _, e := range ret {
|
||||
if e == graphql.Null {
|
||||
return graphql.Null
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNUser2ᚖtailly_back_v2ᚋinternalᚋdomainᚐUser(ctx context.Context, sel ast.SelectionSet, v *domain.User) graphql.Marshaler {
|
||||
if v == nil {
|
||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
type User {
|
||||
id: Int! # Уникальный идентификатор
|
||||
username: String! # Имя пользователя
|
||||
avatar: String! # Аватар
|
||||
email: String! # Email (уникальный)
|
||||
emailConfirmedAt: String # Дата подтверждения email (может быть null)
|
||||
createdAt: String! # Дата создания
|
||||
@ -98,6 +99,7 @@ type Query {
|
||||
post(id: Int!): Post! # Получить пост по ID
|
||||
posts: [Post!]! # Получить все посты
|
||||
user(id: Int!): User! # Получить пользователя по ID
|
||||
users: [User!]!
|
||||
getChatHistory(userId: Int!): [Message!]!
|
||||
getUserChats: [ChatSession!]!
|
||||
mySessions: [Session!]!
|
||||
@ -125,7 +127,7 @@ type Mutation {
|
||||
|
||||
# Удаление лайка
|
||||
unlikePost(postId: Int!): Boolean!
|
||||
updateProfile(username: String!, email: String!): User!
|
||||
updateProfile(username: String!, email: String!, avatar: String!): User!
|
||||
changePassword(oldPassword: String!, newPassword: String!): Boolean!
|
||||
sendMessage(receiverId: Int!, content: String!): Message!
|
||||
markAsRead(messageId: Int!): Boolean!
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
package graph
|
||||
|
||||
// This file will be automatically regenerated based on the schema, any resolver implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
// Code generated by github.com/99designs/gqlgen version v0.17.77
|
||||
@ -61,13 +61,13 @@ func (r *userResolver) UpdatedAt(ctx context.Context, obj *domain.User) (string,
|
||||
}
|
||||
|
||||
// UpdateProfile is the resolver for the updateProfile field.
|
||||
func (r *mutationResolver) UpdateProfile(ctx context.Context, username string, email string) (*domain.User, error) {
|
||||
func (r *mutationResolver) UpdateProfile(ctx context.Context, username string, email string, avatar string) (*domain.User, error) {
|
||||
userID, err := getUserIDFromContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
user, err := r.Services.User.UpdateProfile(ctx, userID, username, email)
|
||||
user, err := r.Services.User.UpdateProfile(ctx, userID, username, email, avatar)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update profile: %w", err)
|
||||
}
|
||||
@ -109,3 +109,12 @@ func (r *mutationResolver) Login(ctx context.Context, input domain.LoginInput) (
|
||||
}
|
||||
return tokens, nil
|
||||
}
|
||||
|
||||
// Users is the resolver for the users field.
|
||||
func (r *queryResolver) Users(ctx context.Context) ([]*domain.User, error) {
|
||||
users, err := r.Services.User.GetAll(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get users: %w", err)
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ var (
|
||||
type UserRepository interface {
|
||||
Create(ctx context.Context, user *domain.User) error
|
||||
GetByID(ctx context.Context, id int) (*domain.User, error)
|
||||
GetAll(ctx context.Context) ([]*domain.User, error)
|
||||
GetByEmail(ctx context.Context, email string) (*domain.User, error)
|
||||
GetByConfirmationToken(ctx context.Context, token string) (*domain.User, error)
|
||||
Update(ctx context.Context, user *domain.User) error
|
||||
@ -50,7 +51,7 @@ func (r *userRepository) Create(ctx context.Context, user *domain.User) error {
|
||||
|
||||
func (r *userRepository) GetByID(ctx context.Context, id int) (*domain.User, error) {
|
||||
query := `
|
||||
SELECT id, username, email, password, email_confirmation_token, email_confirmed_at, created_at, updated_at
|
||||
SELECT id, username, email, password, email_confirmation_token, email_confirmed_at, created_at, updated_at, avatar
|
||||
FROM users
|
||||
WHERE id = $1
|
||||
`
|
||||
@ -67,6 +68,7 @@ func (r *userRepository) GetByID(ctx context.Context, id int) (*domain.User, err
|
||||
&confirmedAt,
|
||||
&user.CreatedAt,
|
||||
&user.UpdatedAt,
|
||||
&user.Avatar,
|
||||
)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
@ -82,7 +84,7 @@ func (r *userRepository) GetByID(ctx context.Context, id int) (*domain.User, err
|
||||
|
||||
func (r *userRepository) GetByEmail(ctx context.Context, email string) (*domain.User, error) {
|
||||
query := `
|
||||
SELECT id, username, email, password, email_confirmation_token, email_confirmed_at, created_at, updated_at
|
||||
SELECT id, username, email, password, email_confirmation_token, email_confirmed_at, created_at, updated_at, avatar
|
||||
FROM users
|
||||
WHERE email = $1
|
||||
`
|
||||
@ -99,6 +101,7 @@ func (r *userRepository) GetByEmail(ctx context.Context, email string) (*domain.
|
||||
&confirmedAt,
|
||||
&user.CreatedAt,
|
||||
&user.UpdatedAt,
|
||||
&user.Avatar,
|
||||
)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
@ -114,7 +117,7 @@ func (r *userRepository) GetByEmail(ctx context.Context, email string) (*domain.
|
||||
|
||||
func (r *userRepository) GetByConfirmationToken(ctx context.Context, token string) (*domain.User, error) {
|
||||
query := `
|
||||
SELECT id, username, email, password, email_confirmation_token, email_confirmed_at, created_at, updated_at
|
||||
SELECT id, username, email, password, email_confirmation_token, email_confirmed_at, created_at, updated_at, avatar
|
||||
FROM users
|
||||
WHERE email_confirmation_token = $1
|
||||
`
|
||||
@ -131,6 +134,7 @@ func (r *userRepository) GetByConfirmationToken(ctx context.Context, token strin
|
||||
&confirmedAt,
|
||||
&user.CreatedAt,
|
||||
&user.UpdatedAt,
|
||||
&user.Avatar,
|
||||
)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
@ -152,8 +156,9 @@ func (r *userRepository) Update(ctx context.Context, user *domain.User) error {
|
||||
password = $3,
|
||||
email_confirmation_token = $4,
|
||||
email_confirmed_at = $5,
|
||||
updated_at = $6
|
||||
WHERE id = $7
|
||||
avatar = $6,
|
||||
updated_at = $7
|
||||
WHERE id = $8
|
||||
`
|
||||
|
||||
var confirmedAt interface{}
|
||||
@ -169,6 +174,7 @@ func (r *userRepository) Update(ctx context.Context, user *domain.User) error {
|
||||
user.Password,
|
||||
user.EmailConfirmationToken,
|
||||
confirmedAt,
|
||||
&user.Avatar,
|
||||
time.Now(), // Обновляем updated_at
|
||||
user.ID,
|
||||
)
|
||||
@ -181,3 +187,32 @@ func (r *userRepository) Delete(ctx context.Context, id int) error {
|
||||
_, err := r.db.ExecContext(ctx, query, id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *userRepository) GetAll(ctx context.Context) ([]*domain.User, error) {
|
||||
query := `
|
||||
SELECT id, username, avatar
|
||||
FROM users
|
||||
`
|
||||
|
||||
rows, err := r.db.QueryContext(ctx, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var users []*domain.User
|
||||
for rows.Next() {
|
||||
user := &domain.User{}
|
||||
err := rows.Scan(
|
||||
&user.ID,
|
||||
&user.Username,
|
||||
&user.Avatar,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
users = append(users, user)
|
||||
}
|
||||
|
||||
return users, nil
|
||||
}
|
||||
|
||||
@ -11,8 +11,9 @@ import (
|
||||
|
||||
type UserService interface {
|
||||
GetByID(ctx context.Context, id int) (*domain.User, error)
|
||||
GetAll(ctx context.Context) ([]*domain.User, error)
|
||||
GetByEmail(ctx context.Context, email string) (*domain.User, error)
|
||||
UpdateProfile(ctx context.Context, id int, username, email string) (*domain.User, error)
|
||||
UpdateProfile(ctx context.Context, id int, username, email, avatar string) (*domain.User, error)
|
||||
ChangePassword(ctx context.Context, id int, oldPassword, newPassword string) error
|
||||
}
|
||||
|
||||
@ -52,7 +53,7 @@ func (s *userService) GetByID(ctx context.Context, id int) (*domain.User, error)
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (s *userService) UpdateProfile(ctx context.Context, id int, username, email string) (*domain.User, error) {
|
||||
func (s *userService) UpdateProfile(ctx context.Context, id int, username, email, avatar string) (*domain.User, error) {
|
||||
user, err := s.userRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -67,6 +68,7 @@ func (s *userService) UpdateProfile(ctx context.Context, id int, username, email
|
||||
|
||||
user.Username = username
|
||||
user.Email = email
|
||||
user.Avatar = avatar
|
||||
user.UpdatedAt = time.Now()
|
||||
|
||||
if err := s.userRepo.Update(ctx, user); err != nil {
|
||||
@ -96,3 +98,17 @@ func (s *userService) ChangePassword(ctx context.Context, id int, oldPassword, n
|
||||
user.Password = hashedPassword
|
||||
return s.userRepo.Update(ctx, user)
|
||||
}
|
||||
|
||||
func (s *userService) GetAll(ctx context.Context) ([]*domain.User, error) {
|
||||
users, err := s.userRepo.GetAll(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Возвращаем пустой слайс вместо nil
|
||||
if users == nil {
|
||||
return []*domain.User{}, nil
|
||||
}
|
||||
|
||||
return users, nil
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
CREATE TABLE users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
username VARCHAR(50) NOT NULL UNIQUE,
|
||||
avatar TEXT NOT NULL DEFAULT 'https://s3.regru.cloud/tailly/default_avatar.jpg',
|
||||
email VARCHAR(255) NOT NULL UNIQUE,
|
||||
email_confirmation_token VARCHAR(255),
|
||||
email_confirmed_at TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user