Skip to content

feat(groups): add public_name slug resolution for public group URLs - #1318

Open
MRashad26 wants to merge 4 commits into
mainfrom
feat/LFXV2-2012
Open

feat(groups): add public_name slug resolution for public group URLs#1318
MRashad26 wants to merge 4 commits into
mainfrom
feat/LFXV2-2012

Conversation

@MRashad26

Copy link
Copy Markdown
Contributor

Summary

  • When the :id route parameter on /public/api/groups/:id is not a UUID, resolve it as a public_name slug via query-service tag lookup (public_name:<slug>)
  • Add public_name field to Committee and PublicGroupDetail interfaces
  • Include public_name in the public group API response so the frontend can use it for canonical URLs

Depends on backend PR: linuxfoundation/lfx-v2-committee-service#172

Test plan

  • Navigate to /groups/<valid-uuid> — page renders as before (no regression)
  • Navigate to /groups/<valid-public-name-slug> — slug resolves and page renders
  • Navigate to /groups/<nonexistent-slug> — shows not-found page
  • Verify public_name is present in the API response when set on the committee

🤖 Generated with Claude Code

LFXV2-2012

When the :id route param is not a UUID, resolve it as a public_name slug
via query-service tag lookup before fetching the committee. This enables
human-readable URLs like /groups/technical-steering-committee alongside
the existing UUID-based /groups/<uid> route.

Signed-off-by: Mohamed Rashad <mrashad@contractor.linuxfoundation.org>
Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
Copilot AI balanced review requested due to automatic review settings August 5, 2026 11:27
@MRashad26
MRashad26 requested a review from a team as a code owner August 5, 2026 11:27
@cursor

cursor Bot commented Aug 5, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Adds a new query-service lookup path on a public endpoint; wrong tag semantics or missing committees surface as 404, but behavior for UUID URLs is unchanged.

Overview
Public group detail (GET /public/api/groups/:id) now accepts either a committee UUID or a non-UUID identifier. When :id fails UUID_REGEX, the BFF looks up a committee via query-service (type: committee, tag sso_group_name:<id>), returns 404 if none match, then loads members, meetings, mailing lists, and calendar links using the resolved committeeUid.

The JSON payload adds optional sso_group_name on PublicGroupDetail (from committee.sso_group_name) for canonical public URLs. Logging and error paths use the resolved UID where applicable.

Reviewed by Cursor Bugbot for commit 012de66. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4bc82e80-e76b-467d-80f3-9293de836a41

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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 public-name slug resolution for public group URLs while retaining UUID support.

Changes:

  • Resolves non-UUID identifiers through query-service tags.
  • Uses the resolved committee UID for downstream requests.
  • Exposes public_name through shared group interfaces and API responses.

Reviewed changes

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

File Description
packages/shared/src/interfaces/public-group.interface.ts Adds public_name to public group details.
packages/shared/src/interfaces/committee.interface.ts Adds the committee public URL slug field.
apps/lfx-one/src/server/controllers/public-groups.controller.ts Implements slug lookup and returns the slug.
Suppressed comments (1)

apps/lfx-one/src/server/controllers/public-groups.controller.ts:66

  • QueryServiceResponse.resources[].id is the query index key (for committees it is committee:<uid>), not the committee UID. Passing it to getCommitteeById produces /committees/committee:<uid>, so every successful slug lookup fails before rendering. Read the UID from the indexed payload instead.
        committeeUid = resources[0].id;

Comment thread apps/lfx-one/src/server/controllers/public-groups.controller.ts
Comment thread apps/lfx-one/src/server/controllers/public-groups.controller.ts Outdated
Comment thread apps/lfx-one/src/server/controllers/public-groups.controller.ts
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

🚀 Deployment Status

Your branch has been deployed to: https://ui-pr-1318.dev.v2.cluster.linuxfound.info

Deployment Details:

  • Environment: Development
  • Namespace: ui-pr-1318
  • ArgoCD App: ui-pr-1318

The deployment will be automatically removed when this PR is closed.

Comment thread apps/lfx-one/src/server/controllers/public-groups.controller.ts Outdated
Comment thread apps/lfx-one/src/server/controllers/public-groups.controller.ts
Address review comments from @copilot-pull-request-reviewer, @cursor:

- public-groups.controller.ts: use resources[0].data.uid instead of
  resources[0].id — the query-service id is the type-prefixed index key
  (committee:<uid>), not the raw UID (per @cursor, @copilot)
- public-groups.controller.ts: throw ResourceNotFoundError (404) instead
  of AuthorizationError (403) when slug lookup finds no match — frontend
  treats 403 as "private group" which is wrong UX for a missing slug
  (per @copilot, @cursor)

Resolves 2 code review threads.

Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
Copilot AI review requested due to automatic review settings August 5, 2026 11:45

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 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (1)

apps/lfx-one/src/server/controllers/public-groups.controller.ts:56

  • The upstream public_name contract explicitly does not enforce uniqueness, so limiting this lookup to one result silently selects whichever duplicate the query service returns first. Two committees with the same value can therefore route the same canonical URL to the wrong group (or to a private group and return 403). Fetch enough results to detect ambiguity and return a deterministic error, or make public_name globally unique before relying on it as a route key.
        const { resources } = await this.microserviceProxy.proxyRequest<QueryServiceResponse<Committee>>(req, 'LFX_V2_SERVICE', '/query/resources', 'GET', {
          type: 'committee',
          tags: `public_name:${id}`,
          page_size: 1,

@MRashad26

Copy link
Copy Markdown
Contributor Author

Review Feedback Addressed

Commit: 48e1a8e

Changes Made

  • public-groups.controller.ts:66: Changed resources[0].id to resources[0].data.uid — the query-service id is the type-prefixed index key (committee:<uid>), not the raw UID (per @copilot-pull-request-reviewer, @cursor)
  • public-groups.controller.ts:59-65: Changed AuthorizationError (403) to ResourceNotFoundError (404) for missing slug lookups — frontend treats 403 as "private group" which is wrong UX for a nonexistent slug (per @copilot-pull-request-reviewer, @cursor)

No Change Needed

  • public-groups.controller.ts:56: Slug uniqueness is enforced at the application layer (PCC), not at the query-service level. Design decision documented in the backend PR feat(ui): improve ux with contextual descriptions and ui polish #172 review.
  • public-groups.controller.ts:52-56: Controller tests are a valid suggestion but deferred to a follow-up — analogous public controllers in this repo also lack Vitest specs currently.

Threads Resolved

5 of 5 unresolved threads addressed in this iteration.

Replace public_name with sso_group_name in the public groups
controller tag query and response mapping, plus the shared
Committee and PublicGroupDetail interfaces.

LFXV2-2012

Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
Copilot AI review requested due to automatic review settings August 6, 2026 08:53

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4cbbb94. Configure here.

Comment thread apps/lfx-one/src/server/controllers/public-groups.controller.ts

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 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (2)

apps/lfx-one/src/server/controllers/public-groups.controller.ts:55

  • The implementation now resolves sso_group_name, while the PR title, summary, interface bullets, and test plan still promise a public_name contract. The latest dependency commit (2c1fb9a) confirms the upstream implementation pivoted to sso_group_name, so update this PR's metadata to match; otherwise consumers and reviewers are directed to a field/tag that no longer exists.
          tags: `sso_group_name:${id}`,

packages/shared/src/interfaces/committee.interface.ts:419

  • Committee already declares sso_group_name?: string at lines 363–366. Declaring it again here duplicates the same upstream field and splits its documentation across two locations. Remove this declaration and, if needed, extend the existing field's JSDoc to mention its public-URL role.
  /** SSO group name, also used as slug for public URLs */
  sso_group_name?: string;

The Committee interface already had sso_group_name at line 366;
renaming public_name created a duplicate. Remove the second one.

LFXV2-2012

Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
Copilot AI review requested due to automatic review settings August 6, 2026 10:22

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 2 out of 2 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

apps/lfx-one/src/server/controllers/public-groups.controller.ts:159

  • This response exposes sso_group_name rather than the canonical public_name promised by this API change. As a result, clients cannot build canonical public URLs, and the newly added PublicGroupDetail field models the unrelated SSO identifier. Add public_name to the shared Committee and PublicGroupDetail contracts and map committee.public_name here.
        sso_group_name: committee.sso_group_name || undefined,

if (!UUID_REGEX.test(id)) {
const { resources } = await this.microserviceProxy.proxyRequest<QueryServiceResponse<Committee>>(req, 'LFX_V2_SERVICE', '/query/resources', 'GET', {
type: 'committee',
tags: `sso_group_name:${id}`,
@MRashad26

Copy link
Copy Markdown
Contributor Author

Review Feedback Addressed

No Change Needed

  • public-groups.controller.ts:55: The sso_group_name tag query is correct — the committee-service emits sso_group_name:<value> tags and this field serves as both SSO identifier and URL slug by design. The duplicate interface declaration was already fixed in commit 012de66.

Threads Resolved

1 of 1 unresolved thread addressed.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants