feat(api): add display_name to member
This commit is contained in:
		
							parent
							
								
									c4ddde73ec
								
							
						
					
					
						commit
						73c5c9fc67
					
				
					 7 changed files with 61 additions and 39 deletions
				
			
		|  | @ -13,12 +13,13 @@ import ( | ||||||
| const MaxMemberCount = 500 | const MaxMemberCount = 500 | ||||||
| 
 | 
 | ||||||
| type Member struct { | type Member struct { | ||||||
| 	ID         xid.ID | 	ID          xid.ID | ||||||
| 	UserID     xid.ID | 	UserID      xid.ID | ||||||
| 	Name       string | 	Name        string | ||||||
| 	Bio        *string | 	DisplayName *string | ||||||
| 	AvatarURLs []string `db:"avatar_urls"` | 	Bio         *string | ||||||
| 	Links      []string | 	AvatarURLs  []string `db:"avatar_urls"` | ||||||
|  | 	Links       []string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
|  | @ -79,10 +80,10 @@ func (db *DB) UserMembers(ctx context.Context, userID xid.ID) (ms []Member, err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // CreateMember creates a member. | // CreateMember creates a member. | ||||||
| func (db *DB) CreateMember(ctx context.Context, tx pgx.Tx, userID xid.ID, name, bio string, links []string) (m Member, err error) { | func (db *DB) CreateMember(ctx context.Context, tx pgx.Tx, userID xid.ID, name string, displayName *string, bio string, links []string) (m Member, err error) { | ||||||
| 	sql, args, err := sq.Insert("members"). | 	sql, args, err := sq.Insert("members"). | ||||||
| 		Columns("user_id", "id", "name", "bio", "links"). | 		Columns("user_id", "id", "name", "display_name", "bio", "links"). | ||||||
| 		Values(userID, xid.New(), name, bio, links). | 		Values(userID, xid.New(), name, displayName, bio, links). | ||||||
| 		Suffix("RETURNING *").ToSql() | 		Suffix("RETURNING *").ToSql() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return m, errors.Wrap(err, "building sql") | 		return m, errors.Wrap(err, "building sql") | ||||||
|  |  | ||||||
|  | @ -12,13 +12,14 @@ import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type CreateMemberRequest struct { | type CreateMemberRequest struct { | ||||||
| 	Name     string       `json:"name"` | 	Name        string       `json:"name"` | ||||||
| 	Bio      string       `json:"bio"` | 	DisplayName *string      `json:"display_name"` | ||||||
| 	Avatar   string       `json:"avatar"` | 	Bio         string       `json:"bio"` | ||||||
| 	Links    []string     `json:"links"` | 	Avatar      string       `json:"avatar"` | ||||||
| 	Names    []db.Name    `json:"names"` | 	Links       []string     `json:"links"` | ||||||
| 	Pronouns []db.Pronoun `json:"pronouns"` | 	Names       []db.Name    `json:"names"` | ||||||
| 	Fields   []db.Field   `json:"fields"` | 	Pronouns    []db.Pronoun `json:"pronouns"` | ||||||
|  | 	Fields      []db.Field   `json:"fields"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (s *Server) createMember(w http.ResponseWriter, r *http.Request) (err error) { | func (s *Server) createMember(w http.ResponseWriter, r *http.Request) (err error) { | ||||||
|  | @ -54,7 +55,12 @@ func (s *Server) createMember(w http.ResponseWriter, r *http.Request) (err error | ||||||
| 	if cmr.Name == "" { | 	if cmr.Name == "" { | ||||||
| 		return server.APIError{ | 		return server.APIError{ | ||||||
| 			Code:    server.ErrBadRequest, | 			Code:    server.ErrBadRequest, | ||||||
| 			Details: "name may not be empty", | 			Details: "Name may not be empty", | ||||||
|  | 		} | ||||||
|  | 	} else if len(cmr.Name) > 100 { | ||||||
|  | 		return server.APIError{ | ||||||
|  | 			Code:    server.ErrBadRequest, | ||||||
|  | 			Details: "Name may not be longer than 100 characters", | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -76,25 +82,29 @@ func (s *Server) createMember(w http.ResponseWriter, r *http.Request) (err error | ||||||
| 	} | 	} | ||||||
| 	defer tx.Rollback(ctx) | 	defer tx.Rollback(ctx) | ||||||
| 
 | 
 | ||||||
| 	m, err := s.DB.CreateMember(ctx, tx, claims.UserID, cmr.Name, cmr.Bio, cmr.Links) | 	m, err := s.DB.CreateMember(ctx, tx, claims.UserID, cmr.Name, cmr.DisplayName, cmr.Bio, cmr.Links) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  | 		if errors.Cause(err) == db.ErrMemberNameInUse { | ||||||
|  | 			return server.APIError{Code: server.ErrMemberNameInUse} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// set names, pronouns, fields | 	// set names, pronouns, fields | ||||||
| 	err = s.DB.SetMemberNames(ctx, tx, claims.UserID, cmr.Names) | 	err = s.DB.SetMemberNames(ctx, tx, m.ID, cmr.Names) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Errorf("setting names for user %v: %v", claims.UserID, err) | 		log.Errorf("setting names for member %v: %v", m.ID, err) | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	err = s.DB.SetMemberPronouns(ctx, tx, claims.UserID, cmr.Pronouns) | 	err = s.DB.SetMemberPronouns(ctx, tx, m.ID, cmr.Pronouns) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Errorf("setting pronouns for user %v: %v", claims.UserID, err) | 		log.Errorf("setting pronouns for member %v: %v", m.ID, err) | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	err = s.DB.SetMemberFields(ctx, tx, claims.UserID, cmr.Fields) | 	err = s.DB.SetMemberFields(ctx, tx, m.ID, cmr.Fields) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Errorf("setting fields for user %v: %v", claims.UserID, err) | 		log.Errorf("setting fields for member %v: %v", m.ID, err) | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,11 +12,12 @@ import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type GetMemberResponse struct { | type GetMemberResponse struct { | ||||||
| 	ID         xid.ID   `json:"id"` | 	ID          xid.ID   `json:"id"` | ||||||
| 	Name       string   `json:"name"` | 	Name        string   `json:"name"` | ||||||
| 	Bio        *string  `json:"bio"` | 	DisplayName *string  `json:"display_name"` | ||||||
| 	AvatarURLs []string `json:"avatar_urls"` | 	Bio         *string  `json:"bio"` | ||||||
| 	Links      []string `json:"links"` | 	AvatarURLs  []string `json:"avatar_urls"` | ||||||
|  | 	Links       []string `json:"links"` | ||||||
| 
 | 
 | ||||||
| 	Names    []db.Name    `json:"names"` | 	Names    []db.Name    `json:"names"` | ||||||
| 	Pronouns []db.Pronoun `json:"pronouns"` | 	Pronouns []db.Pronoun `json:"pronouns"` | ||||||
|  | @ -27,11 +28,12 @@ type GetMemberResponse struct { | ||||||
| 
 | 
 | ||||||
| func dbMemberToMember(u db.User, m db.Member, names []db.Name, pronouns []db.Pronoun, fields []db.Field) GetMemberResponse { | func dbMemberToMember(u db.User, m db.Member, names []db.Name, pronouns []db.Pronoun, fields []db.Field) GetMemberResponse { | ||||||
| 	return GetMemberResponse{ | 	return GetMemberResponse{ | ||||||
| 		ID:         m.ID, | 		ID:          m.ID, | ||||||
| 		Name:       m.Name, | 		Name:        m.Name, | ||||||
| 		Bio:        m.Bio, | 		DisplayName: m.DisplayName, | ||||||
| 		AvatarURLs: m.AvatarURLs, | 		Bio:         m.Bio, | ||||||
| 		Links:      m.Links, | 		AvatarURLs:  m.AvatarURLs, | ||||||
|  | 		Links:       m.Links, | ||||||
| 
 | 
 | ||||||
| 		Names:    names, | 		Names:    names, | ||||||
| 		Pronouns: pronouns, | 		Pronouns: pronouns, | ||||||
|  |  | ||||||
|  | @ -11,11 +11,12 @@ import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type memberListResponse struct { | type memberListResponse struct { | ||||||
| 	ID         xid.ID   `json:"id"` | 	ID          xid.ID   `json:"id"` | ||||||
| 	Name       string   `json:"name"` | 	Name        string   `json:"name"` | ||||||
| 	Bio        *string  `json:"bio"` | 	DisplayName *string  `json:"display_name"` | ||||||
| 	AvatarURLs []string `json:"avatar_urls"` | 	Bio         *string  `json:"bio"` | ||||||
| 	Links      []string `json:"links"` | 	AvatarURLs  []string `json:"avatar_urls"` | ||||||
|  | 	Links       []string `json:"links"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func membersToMemberList(ms []db.Member) []memberListResponse { | func membersToMemberList(ms []db.Member) []memberListResponse { | ||||||
|  |  | ||||||
|  | @ -90,6 +90,7 @@ const ( | ||||||
| 	// Member-related error codes | 	// Member-related error codes | ||||||
| 	ErrMemberNotFound     = 3001 | 	ErrMemberNotFound     = 3001 | ||||||
| 	ErrMemberLimitReached = 3002 | 	ErrMemberLimitReached = 3002 | ||||||
|  | 	ErrMemberNameInUse    = 3003 | ||||||
| 
 | 
 | ||||||
| 	// General request error codes | 	// General request error codes | ||||||
| 	ErrRequestTooBig = 4001 | 	ErrRequestTooBig = 4001 | ||||||
|  | @ -118,6 +119,7 @@ var errCodeMessages = map[int]string{ | ||||||
| 
 | 
 | ||||||
| 	ErrMemberNotFound:     "Member not found", | 	ErrMemberNotFound:     "Member not found", | ||||||
| 	ErrMemberLimitReached: "Member limit reached", | 	ErrMemberLimitReached: "Member limit reached", | ||||||
|  | 	ErrMemberNameInUse:    "Member name already in use", | ||||||
| 
 | 
 | ||||||
| 	ErrRequestTooBig: "Request too big (max 2 MB)", | 	ErrRequestTooBig: "Request too big (max 2 MB)", | ||||||
| } | } | ||||||
|  | @ -145,6 +147,7 @@ var errCodeStatuses = map[int]int{ | ||||||
| 
 | 
 | ||||||
| 	ErrMemberNotFound:     http.StatusNotFound, | 	ErrMemberNotFound:     http.StatusNotFound, | ||||||
| 	ErrMemberLimitReached: http.StatusBadRequest, | 	ErrMemberLimitReached: http.StatusBadRequest, | ||||||
|  | 	ErrMemberNameInUse:    http.StatusBadRequest, | ||||||
| 
 | 
 | ||||||
| 	ErrRequestTooBig: http.StatusBadRequest, | 	ErrRequestTooBig: http.StatusBadRequest, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ export interface User { | ||||||
| export interface PartialMember { | export interface PartialMember { | ||||||
|   id: string; |   id: string; | ||||||
|   name: string; |   name: string; | ||||||
|  |   display_name: string | null; | ||||||
|   avatar_urls: string[] | null; |   avatar_urls: string[] | null; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								scripts/migrate/002_add_member_display_name.sql
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								scripts/migrate/002_add_member_display_name.sql
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | ||||||
|  | -- +migrate Up | ||||||
|  | 
 | ||||||
|  | -- 2022-11-20: add display name to members | ||||||
|  | alter table members add column display_name text; | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue