Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion charts/lfx-v2-committee-service/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ apiVersion: v2
name: lfx-v2-committee-service
description: LFX Platform V2 Committee Service chart
type: application
version: 0.2.19
version: 0.2.20
appVersion: "latest"
2 changes: 1 addition & 1 deletion cmd/committee-api/design/committee.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ var _ = dsl.Service("committee-service", func() {
})

dsl.Result(func() {
dsl.Attribute("member", CommitteeMemberFullWithReadonlyAttributes)
dsl.Attribute("member", CommitteeMemberBasicWithReadonlyAttributes)
ETagAttribute()
dsl.Required("member")
})
Expand Down
30 changes: 28 additions & 2 deletions cmd/committee-api/design/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,14 +384,18 @@ func AuditorsAttribute() {
// CommitteeMemberBase is the DSL type for a committee member base.
var CommitteeMemberBase = dsl.Type("committee-member-base", func() {
dsl.Description("A base representation of committee members.")

CommitteeMemberBaseAttributes()
})

// CommitteeMemberSensitive is the DSL type for a committee member sensitive information.
var CommitteeMemberSensitive = dsl.Type("committee-member-sensitive", func() {
dsl.Description("Sensitive information of a committee member.")
CommitteeMemberSensitiveAttributes()
})

// CommitteeMemberBaseAttributes defines the base attributes for a committee member.
func CommitteeMemberBaseAttributes() {
UsernameAttribute()
EmailAttribute()
FirstNameAttribute()
LastNameAttribute()
JobTitleAttribute()
Expand All @@ -403,11 +407,30 @@ func CommitteeMemberBaseAttributes() {
OrganizationInfoAttributes()
}

// CommitteeMemberSensitiveAttributes defines the sensitive attributes for a committee member.
func CommitteeMemberSensitiveAttributes() {
EmailAttribute()
}

// CommitteeMemberFull is the DSL type for a complete committee member.
var CommitteeMemberFull = dsl.Type("committee-member-full", func() {
dsl.Description("A complete representation of committee members with all attributes.")

CommitteeMemberBaseAttributes()
CommitteeMemberSensitiveAttributes()
})

// CommitteeMemberBasicWithReadonlyAttributes is the DSL type for a basic committee member with readonly attributes.
var CommitteeMemberBasicWithReadonlyAttributes = dsl.Type("committee-member-basic-with-readonly-attributes", func() {
dsl.Description("A basic representation of committee members with readonly attributes.")

CommitteeMemberUIDAttribute()
CommitteeUIDMemberAttribute()
CommitteeNameMemberAttribute()
CommitteeCategoryMemberAttribute()
CommitteeMemberBaseAttributes()
CreatedAtAttribute()
UpdatedAtAttribute()
})

// CommitteeMemberFullWithReadonlyAttributes is the DSL type for a complete committee member with readonly attributes.
Expand All @@ -419,18 +442,21 @@ var CommitteeMemberFullWithReadonlyAttributes = dsl.Type("committee-member-full-
CommitteeNameMemberAttribute()
CommitteeCategoryMemberAttribute()
CommitteeMemberBaseAttributes()
CommitteeMemberSensitiveAttributes()
CreatedAtAttribute()
UpdatedAtAttribute()
})

// CommitteeMemberCreateAttributes defines attributes for creating a committee member.
func CommitteeMemberCreateAttributes() {
CommitteeMemberBaseAttributes()
CommitteeMemberSensitiveAttributes()
}

// CommitteeMemberUpdateAttributes defines attributes for updating a committee member.
func CommitteeMemberUpdateAttributes() {
CommitteeMemberBaseAttributes()
CommitteeMemberSensitiveAttributes()
}

// Organization Information Attributes
Expand Down
3 changes: 2 additions & 1 deletion cmd/committee-api/service/committee_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,8 @@ func (s *committeeServicesrvc) GetCommitteeMember(ctx context.Context, p *commit
}

// Convert domain model to GOA response
result := s.convertMemberDomainToFullResponse(committeeMember)
// Only basic info, no sensitive data
result := s.convertMemberDomainBasicResponse(committeeMember)

// Create result with ETag (using revision from NATS)
revisionStr := fmt.Sprintf("%d", revision)
Expand Down
114 changes: 112 additions & 2 deletions cmd/committee-api/service/committee_service_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,12 @@ func (s *committeeServicesrvc) convertMemberPayloadToDomain(p *committeeservice.
member := &model.CommitteeMember{
CommitteeMemberBase: model.CommitteeMemberBase{
CommitteeUID: p.UID,
Email: p.Email,
AppointedBy: p.AppointedBy,
Status: p.Status,
},
CommitteeMemberSensitive: model.CommitteeMemberSensitive{
Email: p.Email,
},
}

// Handle Username with nil check
Expand Down Expand Up @@ -407,10 +409,12 @@ func (s *committeeServicesrvc) convertPayloadToUpdateMember(p *committeeservice.
CommitteeMemberBase: model.CommitteeMemberBase{
UID: p.MemberUID, // Member UID is required for updates
CommitteeUID: p.UID, // Committee UID from path parameter
Email: p.Email,
AppointedBy: p.AppointedBy,
Status: p.Status,
},
CommitteeMemberSensitive: model.CommitteeMemberSensitive{
Email: p.Email,
},
}

// Handle Username with nil check
Expand Down Expand Up @@ -585,3 +589,109 @@ func (s *committeeServicesrvc) convertMemberDomainToFullResponse(member *model.C

return result
}

// convertMemberDomainBasicResponse converts domain CommitteeMember to GOA basic response type
func (s *committeeServicesrvc) convertMemberDomainBasicResponse(member *model.CommitteeMember) *committeeservice.CommitteeMemberBasicWithReadonlyAttributes {
if member == nil {
return nil
}

memberUID := member.UID
result := &committeeservice.CommitteeMemberBasicWithReadonlyAttributes{
CommitteeUID: &member.CommitteeUID,
UID: &memberUID,
AppointedBy: member.AppointedBy,
Status: member.Status,
}

// Only set optional fields if they have values
if member.Username != "" {
result.Username = &member.Username
}
if member.FirstName != "" {
result.FirstName = &member.FirstName
}
if member.LastName != "" {
result.LastName = &member.LastName
}
if member.JobTitle != "" {
result.JobTitle = &member.JobTitle
}
if member.LinkedInProfile != "" {
result.LinkedinProfile = &member.LinkedInProfile
}
if member.CommitteeName != "" {
result.CommitteeName = &member.CommitteeName
}
if member.CommitteeCategory != "" {
result.CommitteeCategory = &member.CommitteeCategory
}

// Handle Role mapping - only include if role has meaningful data
if member.Role.Name != "" {
role := &struct {
Name string
StartDate *string
EndDate *string
}{
Name: member.Role.Name,
}
if member.Role.StartDate != "" {
role.StartDate = &member.Role.StartDate
}
if member.Role.EndDate != "" {
role.EndDate = &member.Role.EndDate
}
result.Role = role
}

// Handle Voting mapping - only include if voting has meaningful data
if member.Voting.Status != "" {
voting := &struct {
Status string
StartDate *string
EndDate *string
}{
Status: member.Voting.Status,
}
if member.Voting.StartDate != "" {
voting.StartDate = &member.Voting.StartDate
}
if member.Voting.EndDate != "" {
voting.EndDate = &member.Voting.EndDate
}
result.Voting = voting
}

// Handle Organization mapping - only include if organization has meaningful data
if member.Organization.ID != "" || member.Organization.Name != "" || member.Organization.Website != "" {
org := &struct {
ID *string
Name *string
Website *string
}{}
if member.Organization.ID != "" {
org.ID = &member.Organization.ID
}
if member.Organization.Name != "" {
org.Name = &member.Organization.Name
}
if member.Organization.Website != "" {
org.Website = &member.Organization.Website
}
result.Organization = org
}

// Convert timestamps to strings if they exist
if !member.CreatedAt.IsZero() {
createdAt := member.CreatedAt.Format("2006-01-02T15:04:05Z07:00")
result.CreatedAt = &createdAt
}

if !member.UpdatedAt.IsZero() {
updatedAt := member.UpdatedAt.Format("2006-01-02T15:04:05Z07:00")
result.UpdatedAt = &updatedAt
}

return result
}
Loading