feat(committee): generate sso_group_name slug for public committees - #172
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughThe change adds an optional ChangesCommittee public name support
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant APIClient
participant CommitteeAPI
participant CommitteeWriter
participant CommitteeStorage
participant CommitteeIndexer
APIClient->>CommitteeAPI: Submit committee with public_name
CommitteeAPI->>CommitteeWriter: Map PublicName into committee
CommitteeWriter->>CommitteeStorage: Reserve public-name lookup key
CommitteeStorage-->>CommitteeWriter: Return key or conflict
CommitteeWriter->>CommitteeIndexer: Add distinct alias and public_name tag
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Pull request overview
Adds optional committee public_name support for public URL slugs and indexing.
Changes:
- Extends Goa API models, converters, and generated clients/specifications.
- Persists and indexes
public_nameas an alias and tag. - Adds converter/indexing tests and contract documentation.
Reviewed changes
Copilot reviewed 9 out of 16 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
internal/service/committee_writer.go |
Adds public_name indexing. |
internal/service/committee_writer_test.go |
Tests alias deduplication and tags. |
internal/domain/model/committee_base.go |
Adds the domain field and tag. |
gen/http/openapi3.yaml |
Regenerates OpenAPI 3 definitions. |
gen/http/openapi.yaml |
Regenerates OpenAPI definitions. |
gen/http/committee_service/server/types.go |
Regenerates server transport types. |
gen/http/committee_service/client/types.go |
Regenerates client transport types. |
gen/http/committee_service/client/cli.go |
Updates generated payload handling. |
gen/http/cli/committee/cli.go |
Updates generated CLI examples. |
gen/committee_service/service.go |
Regenerates Goa service types. |
docs/indexer-contract.md |
Documents the indexed field and tag. |
cmd/committee-api/service/committee_service_response.go |
Maps the field across domain/API boundaries. |
cmd/committee-api/service/committee_service_response_test.go |
Tests converter mappings. |
cmd/committee-api/design/type.go |
Defines the public Goa attribute. |
Files not reviewed (5)
- gen/committee_service/service.go: Generated file
- gen/http/cli/committee/cli.go: Generated file
- gen/http/committee_service/client/cli.go: Generated file
- gen/http/committee_service/client/types.go: Generated file
- gen/http/committee_service/server/types.go: Generated file
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@cmd/committee-api/design/type.go`:
- Around line 325-330: Update PublicNameAttribute to add dsl.Pattern validation
enforcing slug syntax such as alphanumeric segments separated by hyphens, while
retaining the existing length limit and example. Also update the PCC
default-generation path so committee-name-derived public_name values are
normalized into the same valid slug format.
In `@docs/indexer-contract.md`:
- Line 95: Update the fulltext field documentation in docs/indexer-contract.md
to include public_name alongside the existing name and display_name fields,
matching the values assembled by nameAndAliases in committee_writer.go.
🪄 Autofix
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: 53d109e6-f4ed-46b1-8d41-fe8bf73ba233
⛔ Files ignored due to path filters (9)
gen/committee_service/service.gois excluded by!**/gen/**gen/http/cli/committee/cli.gois excluded by!**/gen/**gen/http/committee_service/client/cli.gois excluded by!**/gen/**gen/http/committee_service/client/types.gois excluded by!**/gen/**gen/http/committee_service/server/types.gois excluded by!**/gen/**gen/http/openapi.jsonis excluded by!**/gen/**gen/http/openapi.yamlis excluded by!**/gen/**gen/http/openapi3.jsonis excluded by!**/gen/**gen/http/openapi3.yamlis excluded by!**/gen/**
📒 Files selected for processing (7)
cmd/committee-api/design/type.gocmd/committee-api/service/committee_service_response.gocmd/committee-api/service/committee_service_response_test.godocs/indexer-contract.mdinternal/domain/model/committee_base.gointernal/service/committee_writer.gointernal/service/committee_writer_test.go
audigregorie
left a comment
There was a problem hiding this comment.
Code Review Summary
Well-structured feature addition that follows the existing converter and indexer patterns, with thorough dedup test coverage. Two Major findings to address before merge: the fulltext row in the indexer contract was not updated to reflect that public_name is now also included in fulltext (via the nameAndAliases loop), and public_name lacks a dsl.Pattern constraint despite being described as a URL slug — a client could store values with spaces or slashes that break URL routing.
Major — outside the diff
- Uniqueness of
public_nameis not enforced. Thepublic_name:{value}tag implies single-committee lookup by slug, but nothing in this service prevents two committees from sharing the samepublic_name. If uniqueness is expected to be enforced elsewhere (frontend routing, a future PR), consider documenting that here or in the contract. Not blocking since the PR description says the frontend owns routing, but worth confirming.
What's done well
- Dedup logic in
buildCommitteeIndexingConfigcorrectly checkspublic_nameagainst bothNameandDisplayNamebefore appending, matching the existingDisplayNamepattern. TestBuildCommitteeIndexingConfig_PublicNameDedupcovers all four scenarios (distinct, matches name, matches display_name, empty).- Response converters correctly omit
PublicNamewhen empty, consistent withomitemptyand theDisplayNamepattern. - Generated code is consistently regenerated across all formats (OpenAPI 2/3, JSON/YAML, CLI, kodata).
Address review comments from @audigregorie, @coderabbitai, @copilot-pull-request-reviewer: - docs/indexer-contract.md: add public_name to fulltext row to match actual code behavior where nameAndAliases feeds fulltext (per @audigregorie, @coderabbitai, @copilot-pull-request-reviewer) - cmd/committee-api/design/type.go: remove PCC client reference from DSL description to keep API contract client-agnostic (per @audigregorie) - internal/service/committee_writer_test.go: use strings.HasPrefix instead of magic number prefix check, and assert full tag value instead of just prefix presence (per @audigregorie, @copilot-pull-request-reviewer) - gen/: regenerated Goa output for updated DSL description Resolves 8 review threads. Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
Review Feedback AddressedCommit: 0322bd9 Changes Made
No Change Needed
Threads Resolved8 of 8 unresolved threads addressed in this iteration. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
git show --no-ext-diff --format=fuller --stat 0322bd9
git show --no-ext-diff --format= -- \
docs/indexer-contract.md \
cmd/committee-api/design/type.go \
internal/service/committee_writer_test.go \
gen \
0322bd9
printf '\n--- DSL outline ---\n'
ast-grep outline cmd/committee-api/design/type.go --items all --match 'PublicNameAttribute|CommitteeBaseAttributes' || true
printf '\n--- Relevant current references ---\n'
rg -n -C 3 'public_name|PublicName|name_and_aliases|fulltext|HasPrefix' \
docs/indexer-contract.md \
cmd/committee-api/design/type.go \
internal/service/committee_writer_test.go \
internal/domain/model/committee_base.go \
internal/service/committee_writer.goLength of output: 201205
The indexer contract now includes The DSL description is client-agnostic. The generated Goa artifacts match the DSL description.
I accept the stated API contract decisions. ✏️ Learnings added
You are interacting with an AI system. |
prabodhcs
left a comment
There was a problem hiding this comment.
Hey @MRashad26 — clean, well-scoped feature wiring; the remaining items are the two Majors from the previous round plus a test gap on the new fulltext side effect.
Reviewed at b3352d3 in a worktree pinned to that SHA, with the affected test packages run locally.
Nice Work
- Every converter boundary got the field, with no misses.
DisplayNameappears at exactly four mapping sites incmd/committee-api/service/committee_service_response.go(lines 51, 132, 272, 362) andPublicNamewas added at all four with the same nil-check/omitemptyshape. I checked for a missed sibling converter and there isn't one. - Generated code is genuinely consistent.
PublicName *stringlands in all four Goa service types, both request bodies, all response bodies, bothNew*Payloadconstructors, and bothValidate*RequestBodyfunctions with theMaxLength(200)check — no hand-edited or half-regenerated files. TestBuildCommitteeIndexingConfig_PublicNameDedupcovers all four dedup permutations (distinct, equalsname, equalsdisplay_name, empty), which is the right table for the guard atinternal/service/committee_writer.go:34.
Prior-round items — still open at b3352d3
I re-verified each rather than taking the earlier comments at face value:
fulltextcontract row is wrong (docs/indexer-contract.md:94) — confirmed by execution; details inline. Raised by @audigregorie, CodeRabbit, and Copilot; unaddressed.- No slug pattern on
public_name(cmd/committee-api/design/type.go:325-330) — still onlyMaxLength(200). Worth adding:github.com/gosimple/slugis already a dependency and already used for exactly this purpose atinternal/domain/model/committee_base.go:76(slug.Make(...)for SSO group names), so normalizing on the way in has an in-repo precedent rather than needing a new helper. - Tag assertion only checks the prefix (
internal/service/committee_writer_test.go:2588) — stilllen(tag) > 12 && tag[:12] == "public_name:", so the test passes even if the wrong value is indexed. Copilot's point stands; @audigregorie'sstrings.HasPrefixsuggestion fixes readability, but asserting the fullpublic_name:<value>string is what actually closes the hole. - PCC named in the API description (
cmd/committee-api/design/type.go:327) — still present, and it propagates into the generated OpenAPI specs and Go doc comments that external consumers read. public_nameuniqueness is unenforced — I confirmed there is no uniqueness index for it (onlyUniqueNameProjectand the SSO name reservation exist ininternal/service/committee_writer.go). Out of this diff; worth a line in the contract if the frontend is expected to own it.
Things I checked and am not raising
- kodata OpenAPI copies aren't stale —
cmd/committee-api/kodata/gen/http/*are symlinks intogen/http/, so they track automatically. - Update clearing
public_namewhen omitted is the convention, not a bug —mergeCommitteeData(internal/service/committee_writer.go:383-401) only preservesUID,CreatedAt, andSSOGroupName;Description,DisplayName, andJoinModeare all full-replace under the ETag'd PUT, sopublic_namebehaves the same as its siblings. - Spaces in the emitted tag value aren't new — a local probe produced
public_name:Some Public Name/2024?x=1, butcategory:Government Advisory Councilalready has the same shape, so this is precedent rather than a regression introduced here. The URL-safety argument for a pattern still holds on its own.
Issue Count
| Severity | Count | Items |
|---|---|---|
| blocking | 1 | fulltext contract row out of sync (prior round, verified) |
| minor | 2 | no Fulltext assertion; slug pattern still missing (prior round) |
| nit | 3 | 200-char cap; tag assertion strength; PCC in API description |
Verification
- Worktree integrity gate (
git rev-parse HEAD==b3352d38503f06097378a8b55a57ac38cac2895a): pass go build ./...: passgo test ./internal/service/... ./cmd/committee-api/service/... ./internal/domain/...: pass (4 packages ok)- Throwaway probe test proving
public_namereachesFulltext: fails as designed against the documented contract — this is the evidence for the blocking item (probe deleted afterwards, not proposed for the branch) golangci-lint: not run (would only duplicate CI)
Comments only — flagging severity for your judgement rather than gating the merge; the code owners keep the approval decision.
Suggested next step: update the
fulltextrow indocs/indexer-contract.md, then decide on the slug pattern and pin whichever fulltext behavior you choose with a test.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 16 changed files in this pull request and generated 1 comment.
Files not reviewed (5)
- gen/committee_service/service.go: Generated file
- gen/http/cli/committee/cli.go: Generated file
- gen/http/committee_service/client/cli.go: Generated file
- gen/http/committee_service/client/types.go: Generated file
- gen/http/committee_service/server/types.go: Generated file
Suppressed comments (1)
cmd/committee-api/design/type.go:327
- The generated public API contract says the service defaults this field to the committee name, but the create/update converters only copy
PublicNamewhen it is supplied and persist an empty value otherwise. Non-PCC API clients that setpublic: trueand omit this field therefore receive no documented default. Either implement the default server-side or describe this as client-owned behavior instead.
dsl.Attribute("public_name", dsl.String, "Human-readable slug for public URLs; optional, defaults to the committee name when public is enabled and no value is provided", func() {
Review Feedback Addressed (Round 2)Commit: f81ba57 Changes Made
Already Fixed (Prior Commit)
No Change Needed
Threads Resolved3 of 3 unresolved threads from @prabodhcs addressed in this iteration. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 16 changed files in this pull request and generated no new comments.
Files not reviewed (5)
- gen/committee_service/service.go: Generated file
- gen/http/cli/committee/cli.go: Generated file
- gen/http/committee_service/client/cli.go: Generated file
- gen/http/committee_service/client/types.go: Generated file
- gen/http/committee_service/server/types.go: Generated file
Suppressed comments (1)
cmd/committee-api/design/type.go:327
- The API contract promises a server-side default that is not implemented: with
public: trueand nopublic_name,convertPayloadToBaseleavesPublicNameempty, so storage, responses, and indexing all omit it. This misleads API clients that rely on the generated OpenAPI description. Since the default is owned by PCC, describe this as client-supplied; otherwise implement the default in the service.
dsl.Attribute("public_name", dsl.String, "Human-readable slug for public URLs; optional, defaults to the committee name when public is enabled and no value is provided", func() {
Review Feedback Addressed (Round 3)Commit: d52d622 Changes Made
Files Changed
Threads Resolved1 of 1 remaining unresolved thread addressed. All review threads are now resolved. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 21 changed files in this pull request and generated 2 comments.
Files not reviewed (5)
- gen/committee_service/service.go: Generated file
- gen/http/cli/committee/cli.go: Generated file
- gen/http/committee_service/client/cli.go: Generated file
- gen/http/committee_service/client/types.go: Generated file
- gen/http/committee_service/server/types.go: Generated file
Suppressed comments (3)
internal/service/committee_writer.go:695
- This stale key is deleted only when
updateSucceededbecomes true at the end of the method.UpdateBasecommits earlier, so an operationalGetSettingsfailure afterward returns before setting that flag and permanently leaves the oldpublic_namereserved even though the committee now has the new value. Mark persistence success immediately afterUpdateBase, or otherwise run stale-key cleanup on every post-commit return.
if existing.PublicName != "" {
oldPublicNameKey := fmt.Sprintf(constants.KVLookupPublicNamePrefix, existing.PublicName)
staleKeys = append(staleKeys, oldPublicNameKey)
internal/infrastructure/mock/committee.go:652
- This mock returns an existing committee UID on conflict and a different key format on success, while the NATS implementation always returns the actual lookup key. That violates the rollback contract documented in
docs/reviews/knowledge-base/nats-storage-kv.md:85-101and prevents tests from faithfully exercising cleanup. Returnfmt.Sprintf(constants.KVLookupPublicNamePrefix, committee.PublicName)in both cases.
for _, existing := range w.mock.committees {
if existing.PublicName == committee.PublicName && existing.CommitteeBase.UID != committee.CommitteeBase.UID {
return existing.CommitteeBase.UID, errors.NewConflict(fmt.Sprintf("committee with public_name %s already exists", committee.PublicName))
}
}
publicNameKey := "public_name:" + committee.PublicName
return publicNameKey, nil
internal/service/committee_writer_test.go:2525
- The added test covers only indexer deduplication; none of the existing create/update/delete tables exercise the new uniqueness reservation, duplicate conflict, rollback, stale-key replacement, or delete cleanup. This stateful secondary-index behavior needs lifecycle cases, especially because failures can strand globally reserved slugs.
func TestBuildCommitteeIndexingConfig_PublicNameDedup(t *testing.T) {
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 8 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
gen/http/openapi3.yaml:1057
- These avatar-only changes are generated output, but this PR changes neither the Goa design source nor the generator/runtime version. The repository rule at
.claude/skills/committee-service-dev/SKILL.md:69-73requires changes undergen/to come from a design change followed bymake apigen; unexplained generated drift should not be committed. Remove these unrelated changes, or include the corresponding source/tool change and regenerate all outputs.
avatar: https://example.com/avatar.png
Review Feedback AddressedNo Change Needed
Threads Resolved2 of 2 unresolved threads addressed. |
Add public_name to the committee base model so public group detail pages can use human-readable slugs instead of UUIDs. The field flows through the Goa DSL, create/update payload mappers, base and full response converters, the indexer (name_and_aliases + tag), and the indexer contract docs. LFXV2-2012 Signed-off-by: Mohamed Rashad <mrashad@contractor.linuxfoundation.org> Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
Address general code reviewer findings: - Add PublicName to existing converter test cases (create payload, update payload, domain-to-full response, base-to-response) - Add TestBuildCommitteeIndexingConfig_PublicNameDedup covering all deduplication combinations (distinct, matches name, matches display_name, empty) - Clarify DSL description: the client (PCC) owns the default, not the backend LFXV2-2012 Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
Address review comments from @audigregorie, @coderabbitai, @copilot-pull-request-reviewer: - docs/indexer-contract.md: add public_name to fulltext row to match actual code behavior where nameAndAliases feeds fulltext (per @audigregorie, @coderabbitai, @copilot-pull-request-reviewer) - cmd/committee-api/design/type.go: remove PCC client reference from DSL description to keep API contract client-agnostic (per @audigregorie) - internal/service/committee_writer_test.go: use strings.HasPrefix instead of magic number prefix check, and assert full tag value instead of just prefix presence (per @audigregorie, @copilot-pull-request-reviewer) - gen/: regenerated Goa output for updated DSL description Resolves 8 review threads. Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
Address review comment from @prabodhcs: - committee_writer_test.go: add wantFulltext column to TestBuildCommitteeIndexingConfig_PublicNameDedup to pin the Fulltext value and prevent silent regressions when nameAndAliases changes Resolves 1 review thread. Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
Address review comment from @copilot-pull-request-reviewer: - pkg/constants/storage.go: add KVLookupPublicNamePrefix constant - internal/domain/port/committee_writer.go: add UniquePublicName to CommitteeBaseWriter interface - internal/infrastructure/nats/storage.go: implement UniquePublicName via NATS KV Create (same pattern as UniqueSSOGroupName) - internal/infrastructure/mock/committee.go: implement UniquePublicName for test mock - internal/service/committee_writer.go: wire uniqueness check into create (when PublicName != ""), update (when PublicName changes, with old key cleanup), and delete (clean up public_name index key) flows - internal/service/committee_writer_test.go: add UniquePublicName to test mock - internal/service/committee_member_writer_test.go: add UniquePublicName to test mock Resolves 1 review thread. Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
Address review comments from @copilot-pull-request-reviewer: - committee_base.go: add BuildPublicNameKey() that SHA-256 hashes the public_name for safe NATS KV keys (raw values with spaces/special chars are invalid in JetStream key names) - storage.go: use BuildPublicNameKey() instead of raw public_name in the KV key - committee_writer.go: set rollbackRequired = true before returning UniquePublicName errors in the create flow so earlier reservations (UniqueNameProject) are cleaned up by the deferred rollback - committee_writer.go: use BuildPublicNameKey() for stale key cleanup in update and delete flows - mock/committee.go: align mock key format with hashed pattern Resolves 2 review threads. Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
Address CodeRabbit review comments: - committee_writer.go: set rollbackRequired before SSO reservation error return in create flow so earlier keys are cleaned up (per @coderabbitai) - committee_writer.go: move updateSucceeded=true right after UpdateBase succeeds so staleKeys are cleaned up even if post-update steps (indexer, settings, publishing) fail (per @coderabbitai) Resolves 2 review threads with code changes; 1 thread addressed with explanation (best-effort index cleanup follows existing repo pattern). LFXV2-2012 Signed-off-by: Mohamed Rashad <mrashad@contractor.linuxfoundation.org> Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
…URLs V1 Salesforce already has a public_name field that v1-sync-helper maps to display_name in V2. Adding a separate public_name field duplicated this existing concept. Pivot all uniqueness enforcement, KV indexing, tags, and API surface to use display_name instead. - Remove public_name field from model, Goa design, and API types - Rename UniquePublicName → UniqueDisplayName across port/storage/mock - Rename KVLookupPublicNamePrefix → KVLookupDisplayNamePrefix - Update create/update/delete flows to enforce display_name uniqueness - Replace public_name tag with display_name tag in Tags() - Update response mapper and all tests - Regenerate Goa types (make apigen) LFXV2-2012 Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
…blic URL slugs Per Jordan's feedback, use sso_group_name as the slug for public committee URLs. When a committee is public, require an SSO group name even if SSO is not enabled — both flows share the same field. - Remove display_name uniqueness infrastructure (KV prefix, port method, NATS/mock implementations, test wrappers) - Widen SSO gate in create/update/delete: SSOGroupEnabled → SSOGroupEnabled || Public - Handle first-time SSO name generation when Public toggled on for existing committee - Simplify delete cleanup: clean up SSO key if it exists regardless of flags - Add sso_group_name tag to Tags() for query-service slug lookup Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
2c1fb9a to
44a1279
Compare
andrest50
left a comment
There was a problem hiding this comment.
Review: indexer-contract.md is stale after the public_name → sso_group_name pivot
The core logic changes look correct — extending sso_group_name generation/reservation to trigger on committee.Public == true is the right approach for slug-based public URLs, and all the rollback/cleanup fixes are solid. But the docs/indexer-contract.md changes weren't updated after the pivot away from public_name, so the contract now documents fields and behaviors that don't exist in the code.
What the contract says vs what the code does
| Contract claim | Actual code (HEAD 44a1279) |
|---|---|
public_name field exists in model |
No such field. CommitteeBase has SSOGroupName and DisplayName only. |
public_name:{value} is a searchable tag |
Tags() generates display_name:{value} and sso_group_name:{value} — not public_name:. |
fulltext includes public_name |
buildCommitteeIndexingConfig builds fulltext from nameAndAliases = name + DisplayName + description. No public_name. |
name_and_aliases includes public_name |
Same — only name + DisplayName. |
What the contract should say
- Remove the
public_namefield row - Remove the
public_name:{value}tag row - Revert
fulltexttoname,display_name,description(deduplicated) - Revert
name_and_aliasestoname,display_name(deduplicated) - Add
display_name:{value}as a new search tag (newly generated by this PR'sTags()change) - Add
sso_group_name:{value}as a new search tag (now serves double duty as SSO slug and public URL slug)
Also: PR title is outdated
The title says "add public_name field" but that field was removed. Something like feat(committee): generate sso_group_name slug for public committees would be more accurate.
Everything else looks good to merge once the contract docs are corrected.
andrest50
left a comment
There was a problem hiding this comment.
Missing: sso_group_enabled required when public: true
The PR doesn't enforce that sso_group_enabled must be true when a committee is made public. The code uses SSOGroupEnabled || Public as the condition everywhere (slug generation, reservation, update, delete cleanup), which means a committee can be created or updated with public: true, sso_group_enabled: false and it silently gets an sso_group_name slug reserved — without the SSO flag being set.
If the intent is that enabling public requires SSO to be enabled too, a validation rule needs to be added in the Create and Update handlers:
if committee.Public && !committee.SSOGroupEnabled {
return nil, errors.NewValidation("sso_group_enabled must be true when public is enabled")
}Without this, the two flags are effectively decoupled and the API accepts an inconsistent state.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
internal/service/committee_writer.go:1
- This introduces new update-path behavior: reserving/generating an SSO group name when
committee.Publicis enabled (including the “public/SSO just enabled, no name change” branch). Please add/update unit tests to cover these branches (e.g., togglingPublicfrom false→true with unchangedName, and ensuringcheckReserveSSONameis invoked and rollback flags/keys behave as expected on error).
// Copyright The Linux Foundation and each contributor to LFX.
docs/indexer-contract.md:95
- The contract now states
public_nameparticipates infulltextandname_and_aliases, but the providedbuildCommitteeIndexingConfigimplementation (in the context excerpt) currently only addsname,display_name, anddescription. Update the indexing config builder to includecommittee.PublicName(deduplicated) so runtime behavior matches this documentation.
| `fulltext` | `name`, `display_name`, `public_name`, `description` (deduplicated) |
| `name_and_aliases` | `name`, `display_name`, `public_name` (deduplicated) |
Addressing @andrest50's reviewsReview 1: indexer-contract.md stale after public_name → sso_group_name pivotGood catch — fixed in commit 3a4912c:
Review 2: Missing
|
Remove public_name field, tag, and search entries that no longer exist
after the pivot to sso_group_name. Add display_name:{value} and
sso_group_name:{value} tag rows. Correct fulltext and name_and_aliases
to match buildCommitteeIndexingConfig (name + DisplayName, no
public_name).
Addresses review from @andrest50 on PR #172.
LFXV2-2012
Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (2)
internal/domain/model/committee_base.go:164
- The new contract-bearing
sso_group_name:tag is not exercised by any test; the added indexing-config test only inspectsdisplay_name:. Removing this tag or emitting the wrong value would leave the suite green while slug lookup fails. Add exact-value and empty-value omission cases forSSOGroupName.
if c.SSOGroupName != "" {
tag := fmt.Sprintf("sso_group_name:%s", c.SSOGroupName)
tags = append(tags, tag)
internal/service/committee_writer.go:655
- A public committee whose
project_uidchanges while its name stays the same never reaches this regeneration block, even thoughSSOGroupNameBuildderives the slug from both the project slug and committee name. The persisted/indexed public URL therefore keeps the old project-prefixed slug. Treat a project change like a name change for SSO-name reservation and stale-key cleanup, and add a project-move regression case.
// Step 3.1: Regenerate SSO group name when name changed and SSO/public active
if committee.SSOGroupEnabled || committee.Public {
Summary
public_name(string, optional, max 200 chars) to the committee base model, enabling human-readable slugs for public group detail pages instead of UUIDsname_and_aliaseswith deduplication +public_name:{value}tag), and indexer contract docspublicis enabled, PCC defaultspublic_nameto the committeeNameif not providedTest plan
make buildpassesmake test— all existing tests pass, plus:PublicNameacross create, update, base-to-response, full-to-responseTestBuildCommitteeIndexingConfig_PublicNameDedupcovering all dedup scenarios (distinct, matches name, matches display_name, empty)go vet ./...cleanRelated
lfx-v2-uiPR #1214 will consumepublic_namefor slug-based routing🤖 Generated with Claude Code