Skip to content

Conversation

jordane
Copy link
Contributor

@jordane jordane commented Oct 2, 2025

This pull request updates the project API to include richer user profile information for project auditors and writers, replacing simple username lists with detailed user objects. The changes introduce a new UserInfo type and update CLI examples to reflect the new structure.

API Type Enhancements:

  • Added a new UserInfo type in types.go to represent user profiles with name, email, username, and avatar attributes.
  • Updated the auditors and writers attributes in project-related DSL functions to use arrays of UserInfo instead of arrays of usernames, along with updated example data to match the new structure.

CLI Example Updates:

  • Modified CLI examples for creating and updating projects in cli.go to show auditors and writers as arrays of user objects, providing realistic sample data for each field. [1] [2] [3]

jordane and others added 4 commits October 2, 2025 14:22
Replace simple string arrays for writers and auditors with rich user objects
containing name, email, username, and avatar fields. This provides better
user experience for display purposes while maintaining backward compatibility
for access control systems.

Changes:
- Add UserInfo type with name, email, username, avatar fields
- Update Goa API design and regenerate types
- Update domain models and service layer converters
- Maintain username extraction for OpenFGA access control
- Update tests for new structure

Breaking Change: API consumers must update to use new user object format
instead of simple username strings for writers and auditors fields.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>
Update root-project-setup and load_mock_data scripts to use the new UserInfo
objects instead of simple strings for writers and auditors.

Changes:
- Update root-project-setup to parse structured user data with backward compatibility
- Support both "username" and "username:name:email:avatar" formats
- Update load_mock_data to generate UserInfo objects with mock data
- Add helper functions for creating test user objects

Environment Variable Formats:
- Simple (backward compatible): ROOT_PROJECT_WRITERS="user1,user2"
- Structured: ROOT_PROJECT_WRITERS="user1:John Doe:[email protected]:avatar.jpg,user2:Jane Smith:[email protected]:"

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>
Complete the test file updates to support the new UserInfo structure for
writers and auditors fields. All tests now use proper UserInfo objects
instead of simple strings.

Changes:
- Fix NATS repository tests to use UserInfo objects
- Update service converter tests with helper functions
- Fix project operations tests
- Ensure all test fixtures use realistic user data
- All tests now pass successfully

This completes the migration to the new UserInfo structure across the
entire codebase including all test files.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>
Update the Helm chart to support both simple and structured formats for
root project writers and auditors. The chart now correctly handles the
new UserInfo structure while maintaining backward compatibility.

Changes:
- Update Chart.yaml version from 0.4.4 to 0.5.0
- Fix deployment template to properly quote environment variables
- Update values.yaml with structured format examples and documentation
- Add support for mixed format usage (simple + structured in same array)

Environment Variable Formats Supported:
- Simple: "username1,username2"
- Structured: "user:Name:[email protected]:avatar.jpg,user2:Name2:email2:"
- Mixed: "simple_user,structured:Full Name:[email protected]:"

The root-project-setup script automatically detects and handles both formats.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>
@jordane jordane requested a review from a team as a code owner October 2, 2025 21:24
@Copilot Copilot AI review requested due to automatic review settings October 2, 2025 21:24
Copy link

coderabbitai bot commented Oct 2, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds a UserInfo type and replaces writer/auditor string lists with structured UserInfo across API DSL, domain models, converters, service operations, tests, Helm charts/values, mock data, and root-project setup parsing.

Changes

Cohort / File(s) Summary
API DSL: UserInfo and attributes
api/project/v1/design/types.go
Adds public DSL type UserInfo (name, email, username, avatar). Changes ProjectAuditorsAttribute and ProjectWritersAttribute from ArrayOf(String) to ArrayOf(UserInfo) with updated examples/descriptions.
Domain models: ProjectSettings
internal/domain/models/project.go
Adds models.UserInfo. Changes ProjectSettings.Writers and ProjectSettings.Auditors from []string to []UserInfo.
Service converters & tests
internal/service/converters.go, internal/service/converters_test.go
Adds conversion helpers (convertUsersToAPI, convertUsersFromAPI, extractUsernames, test helpers) and updates converters/tests to map between domain UserInfo and API UserInfo pointers.
Service operations & tests
internal/service/project_operations.go, internal/service/project_operations_test.go
Uses extractUsernames when publishing access/index updates in create/update flows; updates tests to use models.UserInfo.
API endpoints tests
cmd/project-api/service_endpoint_project_test.go
Updates endpoint tests/mocks to use API UserInfo pointers for Writers/Auditors in payloads and settings.
Repository / NATS tests
internal/infrastructure/nats/repository_test.go
Adjusts test fixtures to use models.UserInfo for Writers/Auditors.
Mock data generator
scripts/load_mock_data/main.go
Changes mock ProjectData.Writers/Auditors to []*projectservice.UserInfo; populates UserInfo objects and adds helper stringPtr.
Root project setup script
scripts/root-project-setup/main.go
Environment fields RootProjectWriters / RootProjectAuditors changed to []models.UserInfo; adds parseUserInfo to accept simple or structured username:name:email:avatar formats.
Helm chart: version
charts/lfx-v2-project-service/Chart.yaml
Bumps chart version from 0.4.5 to 0.5.0.
Helm templates: env quoting
charts/lfx-v2-project-service/templates/deployment.yaml
Quotes ROOT_PROJECT_WRITERS and ROOT_PROJECT_AUDITORS values in initContainers (scalar quoting only).
Helm values: writers/auditors formats
charts/lfx-v2-project-service/values.yaml
Documents two formats (simple username list and structured username:name:email:avatar), updates sample entries and comments; minor comment spacing adjustments.
CI workflow YAML minor formatting
.github/workflows/ko-build-tag.yaml
Minor YAML formatting/comment adjustments (quotes for on, comment placement).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant API as Project API (projsvc)
  participant Svc as Service Layer
  participant Repo as Repository/DB
  participant NATS as Publisher

  Client->>API: CreateProject(payload with writers/auditors as UserInfo[])
  API->>Svc: Convert payload → domain (UserInfo[] via convertUsersFromAPI)
  Svc->>Repo: Save project/settings
  Repo-->>Svc: Saved project
  Note over Svc: extractUsernames(UserInfo[]) → []string for downstream messages
  Svc->>NATS: Publish access/index updates (usernames only)
  NATS-->>Svc: Ack
  Svc-->>API: Project created (UserInfo[] preserved)
  API-->>Client: Response (writers/auditors as UserInfo[])
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The PR includes unrelated modifications to the CI workflow file (.github/workflows/ko-build-tag.yaml) that are not part of the objective to update writers and auditors to objects. Extract or remove the unrelated CI workflow changes into a separate PR so that only the scoped updates to writers and auditors remain in this branch.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly and accurately captures the primary change of replacing writers and auditors from simple lists to object structures, directly reflecting the main objective.
Linked Issues Check ✅ Passed The changes fully implement the linked issue’s requirement to replace simple username lists with structured objects for writers and auditors by introducing the UserInfo type and updating all relevant APIs, models, tests, and scripts.
Description Check ✅ Passed The description clearly outlines the introduction of the UserInfo type and the replacement of auditor and writer lists with structured objects, which matches the changes in the PR.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jme/LFXV2-638

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3b63c8c and 468ef62.

📒 Files selected for processing (2)
  • .github/workflows/ko-build-tag.yaml (3 hunks)
  • charts/lfx-v2-project-service/values.yaml (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • charts/lfx-v2-project-service/values.yaml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: MegaLinter
🔇 Additional comments (3)
.github/workflows/ko-build-tag.yaml (3)

6-6: Quoting on avoids YAML 1.1 pitfalls

Nice catch—quoting the on key prevents YAML 1.1 parsers (and yamllint) from treating it as a boolean, keeping the workflow valid.


92-93: Scoped lint suppression looks good

Targeting the line-length rule disablement to just this action keeps the linting noise down without masking other issues.


104-110: Inline version comments stay tidy

Keeping the action pins with their version notes on the same line is readable and still highlights the exact revisions in use.


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

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This pull request transforms the project API to use richer user profile information by introducing a new UserInfo type and updating project auditors and writers from simple username strings to detailed user objects containing name, email, username, and avatar information.

Key changes include:

  • Introduction of a new UserInfo type with comprehensive user profile data
  • Conversion of auditors and writers from string arrays to UserInfo object arrays across all API layers
  • Addition of backward compatibility support in environment parsing for root project configuration

Reviewed Changes

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

Show a summary per file
File Description
internal/domain/models/project.go Adds new UserInfo struct with profile fields and updates ProjectSettings to use UserInfo arrays
internal/service/converters.go Implements conversion functions between domain and API UserInfo types
internal/service/project_operations.go Updates to extract usernames from UserInfo objects for access control
api/project/v1/design/types.go Defines UserInfo DSL type and updates attribute functions to use UserInfo arrays
scripts/root-project-setup/main.go Adds parseUserInfo function supporting both simple and structured user formats
api/project/v1/gen/http/project_service/server/types.go Updates generated HTTP types to use UserInfo request/response bodies
charts/lfx-v2-project-service/values.yaml Updates configuration format to support structured user information

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +96 to +108
parts := strings.Split(trimmed, ":")
user := models.UserInfo{
Username: parts[0],
}
if len(parts) > 1 {
user.Name = parts[1]
}
if len(parts) > 2 {
user.Email = parts[2]
}
if len(parts) > 3 {
user.Avatar = parts[3]
}
Copy link
Preview

Copilot AI Oct 2, 2025

Choose a reason for hiding this comment

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

Potential panic if parts[0] is accessed when parts slice is empty. The code should check len(parts) > 0 before accessing parts[0].

Copilot uses AI. Check for mistakes.

Comment on lines +436 to +454
// createTestUserInfo creates a UserInfo for testing purposes
func createTestUserInfo(username, name, email, avatar string) models.UserInfo {
return models.UserInfo{
Name: name,
Email: email,
Username: username,
Avatar: avatar,
}
}

// createTestAPIUserInfo creates an API UserInfo for testing purposes
func createTestAPIUserInfo(username, name, email, avatar string) *projsvc.UserInfo {
return &projsvc.UserInfo{
Name: &name,
Email: &email,
Username: &username,
Avatar: &avatar,
}
}
Copy link
Preview

Copilot AI Oct 2, 2025

Choose a reason for hiding this comment

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

Test utility functions should be moved to a test file or testing package instead of being included in production code. These functions are only used in tests but are compiled into the production binary.

Suggested change
// createTestUserInfo creates a UserInfo for testing purposes
func createTestUserInfo(username, name, email, avatar string) models.UserInfo {
return models.UserInfo{
Name: name,
Email: email,
Username: username,
Avatar: avatar,
}
}
// createTestAPIUserInfo creates an API UserInfo for testing purposes
func createTestAPIUserInfo(username, name, email, avatar string) *projsvc.UserInfo {
return &projsvc.UserInfo{
Name: &name,
Email: &email,
Username: &username,
Avatar: &avatar,
}
}

Copilot uses AI. Check for mistakes.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/load_mock_data/main.go (1)

37-45: Fix ProjectResponse to match structured auditors/writers payload

The service now returns auditors and writers as user objects, but ProjectResponse still expects []string. When the script decodes the API response this mismatch triggers json: cannot unmarshal object into Go struct field … of type string, breaking the loader.

Update these fields to the new shape:

 type ProjectResponse struct {
 	ID          *string  `json:"id,omitempty"`
 	Slug        *string  `json:"slug,omitempty"`
 	Name        *string  `json:"name,omitempty"`
 	Description *string  `json:"description,omitempty"`
 	Public      *bool    `json:"public,omitempty"`
 	ParentUID   *string  `json:"parent_uid,omitempty"`
-	Auditors    []string `json:"auditors,omitempty"`
-	Writers     []string `json:"writers,omitempty"`
+	Auditors    []*projectservice.UserInfo `json:"auditors,omitempty"`
+	Writers     []*projectservice.UserInfo `json:"writers,omitempty"`
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between fe7df5b and 3b63c8c.

⛔ Files ignored due to path filters (11)
  • api/project/v1/gen/http/cli/lfx_v2_project_service/cli.go is excluded by !**/gen/**
  • api/project/v1/gen/http/openapi.json is excluded by !**/gen/**
  • api/project/v1/gen/http/openapi.yaml is excluded by !**/gen/**
  • api/project/v1/gen/http/openapi3.json is excluded by !**/gen/**
  • api/project/v1/gen/http/openapi3.yaml is excluded by !**/gen/**
  • api/project/v1/gen/http/project_service/client/cli.go is excluded by !**/gen/**
  • api/project/v1/gen/http/project_service/client/encode_decode.go is excluded by !**/gen/**
  • api/project/v1/gen/http/project_service/client/types.go is excluded by !**/gen/**
  • api/project/v1/gen/http/project_service/server/encode_decode.go is excluded by !**/gen/**
  • api/project/v1/gen/http/project_service/server/types.go is excluded by !**/gen/**
  • api/project/v1/gen/project_service/service.go is excluded by !**/gen/**
📒 Files selected for processing (14)
  • api/project/v1/design/types.go (1 hunks)
  • charts/lfx-v2-project-service/Chart.yaml (1 hunks)
  • charts/lfx-v2-project-service/templates/deployment.yaml (1 hunks)
  • charts/lfx-v2-project-service/values.yaml (1 hunks)
  • cmd/project-api/service_endpoint_project_test.go (3 hunks)
  • internal/domain/models/project.go (2 hunks)
  • internal/domain/models/project_test.go (1 hunks)
  • internal/infrastructure/nats/repository_test.go (1 hunks)
  • internal/service/converters.go (4 hunks)
  • internal/service/converters_test.go (4 hunks)
  • internal/service/project_operations.go (3 hunks)
  • internal/service/project_operations_test.go (1 hunks)
  • scripts/load_mock_data/main.go (3 hunks)
  • scripts/root-project-setup/main.go (3 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Ensure code formatting and linting pass (make fmt, make lint, make check)

Files:

  • internal/service/project_operations.go
  • internal/domain/models/project_test.go
  • internal/service/converters.go
  • scripts/root-project-setup/main.go
  • cmd/project-api/service_endpoint_project_test.go
  • api/project/v1/design/types.go
  • internal/service/converters_test.go
  • scripts/load_mock_data/main.go
  • internal/service/project_operations_test.go
  • internal/domain/models/project.go
  • internal/infrastructure/nats/repository_test.go
**/*_test.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*_test.go: Place unit tests alongside implementation with the same filename and *_test.go suffix
Each production function must have exactly one corresponding TestFunction test (table with multiple cases allowed)
Use table-driven tests for coverage (subtests over a single TestFunction)
Mock all external dependencies (e.g., repositories, message builders) in unit tests
Focus unit tests on exported package functions

Files:

  • internal/domain/models/project_test.go
  • cmd/project-api/service_endpoint_project_test.go
  • internal/service/converters_test.go
  • internal/service/project_operations_test.go
  • internal/infrastructure/nats/repository_test.go
cmd/project-api/service*.go

📄 CodeRabbit inference engine (CLAUDE.md)

cmd/project-api/service*.go: Implement Goa-generated service interfaces in cmd/project-api/service*.go
Enforce ETag concurrency via If-Match on PUT/DELETE handlers

Files:

  • cmd/project-api/service_endpoint_project_test.go
api/project/v1/design/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Define and update the REST API using Goa v3 in api/project/v1/design/ (Design First)

Files:

  • api/project/v1/design/types.go
🧬 Code graph analysis (8)
internal/domain/models/project_test.go (3)
api/project/v1/design/types.go (1)
  • UserInfo (226-243)
internal/domain/models/project.go (1)
  • UserInfo (12-17)
api/project/v1/gen/project_service/service.go (1)
  • UserInfo (431-440)
internal/service/converters.go (3)
api/project/v1/design/types.go (1)
  • UserInfo (226-243)
internal/domain/models/project.go (1)
  • UserInfo (12-17)
api/project/v1/gen/project_service/service.go (1)
  • UserInfo (431-440)
cmd/project-api/service_endpoint_project_test.go (4)
api/project/v1/design/types.go (1)
  • UserInfo (226-243)
internal/domain/models/project.go (1)
  • UserInfo (12-17)
api/project/v1/gen/project_service/service.go (1)
  • UserInfo (431-440)
pkg/misc/misc.go (1)
  • StringPtr (7-9)
api/project/v1/design/types.go (2)
internal/domain/models/project.go (1)
  • UserInfo (12-17)
api/project/v1/gen/project_service/service.go (1)
  • UserInfo (431-440)
internal/service/converters_test.go (2)
pkg/misc/misc.go (1)
  • StringPtr (7-9)
internal/domain/models/project.go (2)
  • UserInfo (12-17)
  • ProjectSettings (46-55)
scripts/load_mock_data/main.go (2)
api/project/v1/design/types.go (1)
  • UserInfo (226-243)
internal/domain/models/project.go (1)
  • UserInfo (12-17)
internal/service/project_operations_test.go (2)
api/project/v1/design/types.go (1)
  • UserInfo (226-243)
internal/domain/models/project.go (1)
  • UserInfo (12-17)
internal/domain/models/project.go (2)
api/project/v1/design/types.go (1)
  • UserInfo (226-243)
api/project/v1/gen/project_service/service.go (1)
  • UserInfo (431-440)
🪛 YAMLlint (1.37.1)
charts/lfx-v2-project-service/templates/deployment.yaml

[error] 69-69: syntax error: expected , but found ','

(syntax)


[warning] 71-71: too few spaces after comma

(commas)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Build and Test
  • GitHub Check: MegaLinter

Comment on lines +69 to +71
value: "{{ .Values.rootProject.writers | join "," }}"
- name: ROOT_PROJECT_AUDITORS
value: {{ .Values.rootProject.auditors | join "," }}
value: "{{ .Values.rootProject.auditors | join "," }}"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix quoting: current template fails lint/render

Wrapping {{ .Values.rootProject.* | join "," }} in raw double quotes introduces unescaped quotes inside a YAML double-quoted scalar, triggering the yamllint syntax error (expected <block end>, but found ',') and breaking chart linting. Replace the manual quoting with Helm’s quote helper after the join so the rendered value is correctly quoted.

-              value: "{{ .Values.rootProject.writers | join "," }}"
+              value: {{ .Values.rootProject.writers | join "," | quote }}
-              value: "{{ .Values.rootProject.auditors | join "," }}"
+              value: {{ .Values.rootProject.auditors | join "," | quote }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
value: "{{ .Values.rootProject.writers | join "," }}"
- name: ROOT_PROJECT_AUDITORS
value: {{ .Values.rootProject.auditors | join "," }}
value: "{{ .Values.rootProject.auditors | join "," }}"
value: {{ .Values.rootProject.writers | join "," | quote }}
- name: ROOT_PROJECT_AUDITORS
value: {{ .Values.rootProject.auditors | join "," | quote }}
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 69-69: syntax error: expected , but found ','

(syntax)


[warning] 71-71: too few spaces after comma

(commas)

🤖 Prompt for AI Agents
In charts/lfx-v2-project-service/templates/deployment.yaml around lines 69 to
71, the current template wraps the join output in raw double quotes which can
inject unescaped quotes and break YAML; replace the manual quoting by piping the
joined string into Helm's quote helper (e.g. .Values.rootProject.auditors | join
"," | quote) so the rendered scalar is safely quoted; apply the same pattern to
any other similar lines (e.g. writers) to ensure lint/render passes.

Comment on lines +383 to +392
apiUsers := make([]*projsvc.UserInfo, len(users))
for i, user := range users {
apiUsers[i] = &projsvc.UserInfo{
Name: &user.Name,
Email: &user.Email,
Username: &user.Username,
Avatar: &user.Avatar,
}
}
return apiUsers
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Don’t take addresses of the range variable

Here we take &user.Name (and friends) where user is the loop variable. Because Go reuses the same variable each iteration, every pointer ends up referencing the last element—tests with multiple writers/auditors will return duplicates.

-	apiUsers := make([]*projsvc.UserInfo, len(users))
-	for i, user := range users {
-		apiUsers[i] = &projsvc.UserInfo{
-			Name:     &user.Name,
-			Email:    &user.Email,
-			Username: &user.Username,
-			Avatar:   &user.Avatar,
-		}
-	}
+	apiUsers := make([]*projsvc.UserInfo, len(users))
+	for i := range users {
+		user := users[i]
+		apiUsers[i] = &projsvc.UserInfo{
+			Name:     misc.StringPtr(user.Name),
+			Email:    misc.StringPtr(user.Email),
+			Username: misc.StringPtr(user.Username),
+			Avatar:   misc.StringPtr(user.Avatar),
+		}
+	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
apiUsers := make([]*projsvc.UserInfo, len(users))
for i, user := range users {
apiUsers[i] = &projsvc.UserInfo{
Name: &user.Name,
Email: &user.Email,
Username: &user.Username,
Avatar: &user.Avatar,
}
}
return apiUsers
apiUsers := make([]*projsvc.UserInfo, len(users))
for i := range users {
user := users[i]
apiUsers[i] = &projsvc.UserInfo{
Name: misc.StringPtr(user.Name),
Email: misc.StringPtr(user.Email),
Username: misc.StringPtr(user.Username),
Avatar: misc.StringPtr(user.Avatar),
}
}
return apiUsers
🤖 Prompt for AI Agents
internal/service/converters.go around lines 383 to 392: the loop takes addresses
of the range variable (e.g., &user.Name) which is reused each iteration causing
all pointers to reference the last element; change to take addresses of the
actual slice element (e.g., &users[i].Name, &users[i].Email, &users[i].Username,
&users[i].Avatar) or assign a local copy per-iteration (u := users[i]; use
&u.Name etc.) so each pointer refers to the correct element.

Comment on lines +95 to +109
// Structured format: username:name:email:avatar
parts := strings.Split(trimmed, ":")
user := models.UserInfo{
Username: parts[0],
}
if len(parts) > 1 {
user.Name = parts[1]
}
if len(parts) > 2 {
user.Email = parts[2]
}
if len(parts) > 3 {
user.Avatar = parts[3]
}
users = append(users, user)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Structured user parsing drops avatar URLs

Using strings.Split treats every : as a separator. Avatar values like https://… are truncated to "https", so the structured env format breaks immediately. Please switch to strings.SplitN(..., 4) (and trim parts) so we preserve the full avatar URL and keep backwards compatibility.

-			if strings.Contains(trimmed, ":") {
-				// Structured format: username:name:email:avatar
-				parts := strings.Split(trimmed, ":")
+			if strings.Contains(trimmed, ":") {
+				// Structured format: username:name:email:avatar
+				parts := strings.SplitN(trimmed, ":", 4)
 				user := models.UserInfo{
-					Username: parts[0],
+					Username: strings.TrimSpace(parts[0]),
 				}
 				if len(parts) > 1 {
-					user.Name = parts[1]
+					user.Name = strings.TrimSpace(parts[1])
 				}
 				if len(parts) > 2 {
-					user.Email = parts[2]
+					user.Email = strings.TrimSpace(parts[2])
 				}
 				if len(parts) > 3 {
-					user.Avatar = parts[3]
+					user.Avatar = strings.TrimSpace(parts[3])
 				}
 				users = append(users, user)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Structured format: username:name:email:avatar
parts := strings.Split(trimmed, ":")
user := models.UserInfo{
Username: parts[0],
}
if len(parts) > 1 {
user.Name = parts[1]
}
if len(parts) > 2 {
user.Email = parts[2]
}
if len(parts) > 3 {
user.Avatar = parts[3]
}
users = append(users, user)
if strings.Contains(trimmed, ":") {
// Structured format: username:name:email:avatar
parts := strings.SplitN(trimmed, ":", 4)
user := models.UserInfo{
Username: strings.TrimSpace(parts[0]),
}
if len(parts) > 1 {
user.Name = strings.TrimSpace(parts[1])
}
if len(parts) > 2 {
user.Email = strings.TrimSpace(parts[2])
}
if len(parts) > 3 {
user.Avatar = strings.TrimSpace(parts[3])
}
users = append(users, user)
🤖 Prompt for AI Agents
In scripts/root-project-setup/main.go around lines 95 to 109, the current
parsing uses strings.Split which splits on every ':' and truncates avatar URLs;
change the split to use strings.SplitN(trimmed, ":", 4) and trim whitespace on
each returned part so the fourth part preserves the full avatar URL while
maintaining backwards compatibility for fewer fields.

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.

1 participant