Skip to content

Add project name and logo to My CLAs API - #5133

Open
ahmedomosanya wants to merge 3 commits into
devfrom
feat/my-clas-project-name-logo
Open

Add project name and logo to My CLAs API#5133
ahmedomosanya wants to merge 3 commits into
devfrom
feat/my-clas-project-name-logo

Conversation

@ahmedomosanya

Copy link
Copy Markdown

Summary

  • Adds projectName and projectLogo to the My CLAs API (GET my-cla rows). A new ProjectService interface plus a projectInfo(ctx, cache, claGroupID) resolver in v2/my_clas/service.go maps a CLA Group to its Salesforce project (single-project -> project SFID/name; multi-project foundation-level -> foundation SFID/name), then upgrades the name and fetches the logo from the project-service, cached per request.
  • Swagger (my-cla.yaml), server wiring (cmd/server.go passes project_service.GetClient()), tests, and docs/MY_CLAS_API.md updated.

Why

The UI's Project cell needs a real project display name and logo instead of the current projectName = claGroupName UUID/name fallback.

Non-obvious

  • A project-service lookup miss (or a nil client) degrades to the mapping-table name and an empty logo rather than failing the whole listing.
  • make swagger MUST run first — models.MyCla.{ProjectName,ProjectLogo} are generated from the edited my-cla.yaml (gen/ is gitignored).

Test plan

  • From cla-backend-go/: make swagger && make build-mac && make test && make lint
  • New tests TestGetMyClasProjectNameAndLogo and TestGetMyClasProjectLookupDegradesGracefully in v2/my_clas/service_test.go pass

Copilot AI review requested due to automatic review settings July 31, 2026 14:21
The UI's Project cell needs a real project display name and logo
instead of the current projectName = claGroupName UUID/name fallback.

- Add projectName and projectLogo to the My CLAs API (GET my-cla rows)
- Add a ProjectService interface and projectInfo(ctx, cache,
  claGroupID) resolver in v2/my_clas/service.go that maps a CLA Group
  to its Salesforce project (single-project -> project SFID/name;
  multi-project foundation-level -> foundation SFID/name), upgrades the
  name, and fetches the logo from the project-service, cached per
  request
- A project-service lookup miss (or nil client) degrades to the
  mapping-table name and empty logo rather than failing the listing
- Wire cmd/server.go to pass project_service.GetClient()
- Update swagger my-cla.yaml, tests, and docs/MY_CLAS_API.md

Signed-off-by: ahmedomosany <aopeyemi@contractor.linuxfoundation.org>
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9047a5b5-a90e-4274-9eba-2a8b7dc92261

📥 Commits

Reviewing files that changed from the base of the PR and between 6b38082 and 17f6271.

📒 Files selected for processing (2)
  • cla-backend-go/v2/my_clas/service.go
  • cla-backend-go/v2/my_clas/service_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • cla-backend-go/v2/my_clas/service_test.go
  • cla-backend-go/v2/my_clas/service.go

Walkthrough

The My CLAs service now resolves project names and logos from CLA Group mappings and project-service records. The API schema, server wiring, tests, and documentation support the new response fields and fallback behavior.

Changes

My CLAs project metadata

Layer / File(s) Summary
Metadata contract and service wiring
cla-backend-go/v2/my_clas/service.go, cla-backend-go/cmd/server.go, cla-backend-go/swagger/common/my-cla.yaml
The service accepts project-service and project-mapping dependencies. The API schema defines optional projectName and projectLogo fields.
Project metadata resolution
cla-backend-go/v2/my_clas/service.go
CLA listing resolves foundation and single-project mappings, caches results per request, and populates project metadata. Ambiguous mappings remain unresolved. Project-service errors leave the logo empty.
Metadata validation and API documentation
cla-backend-go/v2/my_clas/service_test.go, docs/MY_CLAS_API.md
Tests cover resolution, caching, ambiguity, missing records, lookup errors, and nil clients. Documentation describes the response fields and fallback behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GetMyClas
  participant ProjectsCLAGroupsRepository
  participant ProjectService
  GetMyClas->>ProjectsCLAGroupsRepository: Retrieve CLA Group project mappings
  GetMyClas->>ProjectService: Retrieve project details by Salesforce ID
  ProjectService-->>GetMyClas: Return project name and logo
  GetMyClas-->>GetMyClas: Populate projectName and projectLogo
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding project names and logos to the My CLAs API.
Description check ✅ Passed The description directly explains the API fields, project resolution, caching, fallback behavior, wiring, tests, and documentation updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/my-clas-project-name-logo

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Salesforce project names and logos to My CLAs API responses.

Changes:

  • Resolves and caches project metadata per CLA group.
  • Wires the project-service client into My CLAs.
  • Updates Swagger, tests, and API documentation.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
docs/MY_CLAS_API.md Documents project metadata fields and UI mapping.
cla-backend-go/v2/my_clas/service.go Resolves project names and logos.
cla-backend-go/v2/my_clas/service_test.go Tests project and foundation metadata resolution.
cla-backend-go/swagger/common/my-cla.yaml Adds the response fields.
cla-backend-go/cmd/server.go Injects the project-service client.

Comment thread cla-backend-go/v2/my_clas/service.go
Comment thread cla-backend-go/v2/my_clas/service_test.go
Copilot AI review requested due to automatic review settings July 31, 2026 14:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Suppressed comments (2)

docs/MY_CLAS_API.md:368

  • The detailed “Performance notes” section is now incomplete: each distinct CLA group also incurs a projects_cla_groups GSI query and potentially a project-service lookup, but it still lists only the existing CLA-group-name GetItem. Please include these new calls so the documented request-cost and latency model matches the implementation.
| `projectName` | string | The Salesforce project display name the CLA Group belongs to (a multi-project, foundation-level CLA Group resolves to its foundation). Name comes from the `projects_cla_groups` mapping table and is upgraded to the project-service `Name` when available; both cached per request. Rendered as the bold top line of the UI's Project cell (with `claGroupName` as the subtext). Omitted when it could not be resolved |

cla-backend-go/v2/my_clas/service.go:761

  • Foundation-level status cannot be inferred from the number of mappings. This codebase identifies it by a mapping whose ProjectSFID == FoundationSFID (projects_cla_groups/repository.go:128-145 and project/service/service.go:353-378), while CLA-group validation can accept multiple project SFIDs without the foundation itself. Such a multi-project, project-level group will therefore be branded as its foundation here. Detect the foundation marker explicitly, and define a deterministic fallback for multiple mappings without that marker; add coverage for that case.
	case len(mappings) > 1:
		projectSFID = mappings[0].FoundationSFID
		info.name = mappings[0].FoundationName

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cla-backend-go/swagger/common/my-cla.yaml`:
- Around line 22-27: Regenerate the v2 Swagger artifacts after adding
projectName and projectLogo to the my-cla specification by running make swagger
from cla-backend-go, and include the generated gen/v2/models/my_cla.go and any
related generated files in the changes. Verify the generated model exposes both
ProjectName and ProjectLogo.

In `@cla-backend-go/v2/my_clas/service.go`:
- Around line 78-89: Update the ProjectService.GetProject method and its
implementations/call sites to accept and propagate context.Context, ensuring the
request context reaches the project-service client invocation. Use this
context-aware signature in the surrounding project resolution flow instead of
relying on a client call without cancellation or timeout.
- Line 764: Prevent nil dereferences from failed service-client initialization
by updating the relevant InitClient implementations to validate
client.NewHTTPClientWithConfig() results and return nil or an initialization
error when invalid. Ensure all GetClient() consumers, including
v2/my_clas.Service around projectService and cmd/server.go at the NewService
call, validate the returned client before passing it onward or accessing its
fields; apply the same guard to project, user, organization, and acs
service-client call sites.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eeddd727-d55a-472e-a498-73e70cf66e0e

📥 Commits

Reviewing files that changed from the base of the PR and between 22867ae and 4e7dba9.

📒 Files selected for processing (5)
  • cla-backend-go/cmd/server.go
  • cla-backend-go/swagger/common/my-cla.yaml
  • cla-backend-go/v2/my_clas/service.go
  • cla-backend-go/v2/my_clas/service_test.go
  • docs/MY_CLAS_API.md

Comment thread cla-backend-go/swagger/common/my-cla.yaml
Comment thread cla-backend-go/v2/my_clas/service.go
Comment thread cla-backend-go/v2/my_clas/service.go
Foundation-level CLA Groups are identified by a projects_cla_groups
mapping whose project_sfid == foundation_sfid (the SignedAtFoundation
convention), not by the number of mappings. Resolving project name and
logo purely on mapping count would mis-brand a multi-project,
project-level CLA Group as its foundation.

- Detect the foundation marker explicitly; a single project-level
  mapping resolves to that project and multiple project-level mappings
  with no marker resolve deterministically to the lowest project SFID
- Add tests for the multi-project non-foundation case and for the
  non-fatal degradation contract on a project-service error and a nil
  project-service client
- Document the extra projects_cla_groups GSI query and project-service
  call in the Performance notes and correct the projectName field note

Signed-off-by: ahmedomosany <aopeyemi@contractor.linuxfoundation.org>
Copilot AI review requested due to automatic review settings July 31, 2026 14:52

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
cla-backend-go/v2/my_clas/service_test.go (1)

230-233: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Add coverage for the request-local project metadata cache.

The test data uses one signature per CLA Group. It passes even if projectInfo() calls GetProject() once for every row.

Add two signed signatures for the same CLA Group. Track GetProject() calls in fakeProjectService. Assert that the service performs one lookup for that project during one GetMyClas() request.

Proposed test support
 type fakeProjectService struct {
   byID map[string]*v2ProjectServiceModels.ProjectOutputDetailed
   err  error
+  calls map[string]int
 }

 func (f *fakeProjectService) GetProject(projectSFID string) (*v2ProjectServiceModels.ProjectOutputDetailed, error) {
+  if f.calls != nil {
+    f.calls[projectSFID]++
+  }
   if f.err != nil {
     return nil, f.err
   }
   return f.byID[projectSFID], nil
 }

Create two distinct signatures with SignatureProjectID == "cla-group-1", then assert calls["proj-sfid-1"] == 1.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cla-backend-go/v2/my_clas/service_test.go` around lines 230 - 233, Extend the
GetMyClas() test data with two distinct signed signatures for the same CLA Group
using SignatureProjectID "cla-group-1". Update fakeProjectService to record
GetProject() calls, then assert after one GetMyClas() request that
calls["proj-sfid-1"] equals 1, verifying request-local project metadata caching.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@cla-backend-go/v2/my_clas/service_test.go`:
- Around line 230-233: Extend the GetMyClas() test data with two distinct signed
signatures for the same CLA Group using SignatureProjectID "cla-group-1". Update
fakeProjectService to record GetProject() calls, then assert after one
GetMyClas() request that calls["proj-sfid-1"] equals 1, verifying request-local
project metadata caching.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 51db75b3-2e73-475a-8283-1bc5aa9d3429

📥 Commits

Reviewing files that changed from the base of the PR and between 4e7dba9 and 6b38082.

📒 Files selected for processing (3)
  • cla-backend-go/v2/my_clas/service.go
  • cla-backend-go/v2/my_clas/service_test.go
  • docs/MY_CLAS_API.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/MY_CLAS_API.md
  • cla-backend-go/v2/my_clas/service.go

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Suppressed comments (3)

cla-backend-go/v2/my_clas/service.go:184

  • Project resolution is performed synchronously inside the user/signature loop. On a cold project-service cache this adds a DynamoDB query and potentially an HTTP round trip for every distinct CLA group, serially; this unpaginated endpoint can therefore grow linearly toward the API Gateway/Lambda deadline for users with substantial history. Collect unique CLA group IDs first and resolve them with bounded concurrency (or a bulk lookup) before building the rows.
			project, projectErr := s.projectInfo(ctx, projectInfos, sig.SignatureProjectID)
			if projectErr != nil {
				return nil, projectErr
			}

cla-backend-go/v2/my_clas/service.go:775

  • When a CLA group has multiple project mappings but no foundation marker, there is no unique project represented by the signature. Selecting the lexicographically smallest opaque Salesforce ID can therefore label the agreement with an unrelated project, and the displayed project can change whenever another mapping is added. Treat this state as ambiguous (for example, omit these fields so the consumer falls back to claGroupName) rather than inventing a project association.
	case len(mappings) > 1:
		pick := mappings[0]
		for _, m := range mappings[1:] {
			if m.ProjectSFID < pick.ProjectSFID {
				pick = m
			}
		}
		projectSFID = pick.ProjectSFID
		info.name = pick.ProjectName

cla-backend-go/v2/my_clas/service.go:88

  • This new dependency cannot receive the request context. The production GetProject implementation creates generated request parameters without setting Context, so cancellation or the Lambda deadline will not abort a stalled project-service request; the promised graceful degradation can instead hold the entire My CLAs response until infrastructure timeout. Make this method context-aware and pass ctx into the generated project-service request.
// ProjectService is the subset of the project-service client used to resolve a project's
// display name and logo from its Salesforce ID
type ProjectService interface {
	GetProject(projectSFID string) (*v2ProjectServiceModels.ProjectOutputDetailed, error)

A CLA Group with multiple project-level mappings and no foundation
marker has no single project the signature represents. Selecting an
arbitrary mapped project (e.g. the lowest SFID) could label the
agreement with an unrelated project and change the displayed project as
mappings are added, so leave the project name and logo empty and let
the consumer fall back to claGroupName instead.

- Resolve project fields only for a foundation marker or a single
  project-level mapping; leave them empty otherwise
- Add a per-request cache-hit test asserting one project-service lookup
  for repeated CLA Groups in a single request

Signed-off-by: ahmedomosany <aopeyemi@contractor.linuxfoundation.org>
Copilot AI review requested due to automatic review settings July 31, 2026 15:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants