feat: add teams resource (dhq teams list|show|create|update|delete)#33
Merged
Conversation
Adds account-level permission groups: SDK types + CRUD methods and a `dhq teams` command tree, following the established resource pattern (request bodies wrapped under `team`, bare responses, PATCH for update). Membership syncs via --user-ids on create/update; the update request uses *[]int so an explicit empty list clears all members while omitting the flag leaves membership untouched. Scalar update flags use pointers so partial updates don't clobber unset permissions.
The SDK models an empty membership list as a non-nil *[]int so it reaches the server as "user_ids":[], but that empty case was unreachable from the CLI: cobra's IntSliceVar rejects --user-ids "" at parse time (strconv.Atoi on the empty string fails). Add a dedicated --clear-members flag (update only) to express "remove all members", mutually exclusive with --user-ids. Found by live smoke-testing the command against a real backend; the SDK unit test passed because it builds the request struct directly, bypassing flag parsing.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughChangesTeams resource support
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant TeamsCommand
participant SDKClient
participant TeamsAPI
participant CLIOutput
User->>TeamsCommand: Run a teams command
TeamsCommand->>SDKClient: Invoke the matching team operation
SDKClient->>TeamsAPI: Send the team API request
TeamsAPI-->>SDKClient: Return team data or an error
SDKClient-->>TeamsCommand: Return the decoded result
TeamsCommand->>CLIOutput: Render JSON, table, quiet, or status output
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@internal/commands/teams.go`:
- Around line 251-280: Validate an explicitly provided empty name in
newTeamsUpdateCmd before constructing or sending the update request, matching
the existing teams create validation behavior and returning the same user-facing
error. Keep omitted --name behavior unchanged so updates can leave the existing
team name intact.
🪄 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: 16de2242-125c-45c5-bc12-af1663bba8a9
📒 Files selected for processing (7)
internal/assist/prompt.gointernal/commands/agent_metadata.gointernal/commands/root.gointernal/commands/teams.gointernal/commands/teams_test.gopkg/sdk/teams.gopkg/sdk/teams_test.go
Match `teams create`, which rejects a blank name before the API call. Previously `teams update --name ""` passed the Changed() check and sent "name":"" to the server, relying on a round-trip 422 rather than failing fast. Addresses CodeRabbit feedback on PR #33.
# Conflicts: # internal/assist/prompt.go # internal/commands/agent_metadata.go
facundofarias
added a commit
that referenced
this pull request
Jul 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes out the last piece of DHQ-639 (API coverage). Teams are the account-level permission groups exposed by the DeployHQ API (
teams_controller'svalid_api_actions) that the CLI didn't cover yet — distinct from folders (project_categories), which organise projects for display.What this PR does
Adds a
dhq teamscommand tree and the SDK methods behind it, following the established resource pattern (agents,global-servers, …):dhq teams list— table of teams (name, identifier, admin, member count, all-projects), with--json, quiet mode, and breadcrumbs.dhq teams show <id>— full detail, including nested members, project assignments, and project exclusions.dhq teams create <name>— scalar permission flags (--admin,--can-manage-users,--can-manage-billing,--can-manage-agents,--can-create-projects,--all-projects) plus--user-idsto seed membership.dhq teams update <id>— partial update of any of the above, plus--clear-members.dhq teams delete <id>.SDK types + CRUD live in
pkg/sdk/teams.go; the command tree ininternal/commands/teams.go. Registered inroot.go,agent_metadata.go(agent-facing flags), and theassistallowlist.Contract details worth a look
The DeployHQ API wraps request bodies under the resource key (
{"team": {...}}) but returns bare responses, and updates go over PATCH — matching the users/account/profile convention, not folders' PUT. Verified against the live backend.Partial updates don't clobber — including membership
Update flags are pointers gated on
cmd.Flags().Changed(...), so an unset flag is omitted from the PATCH rather than sent as a zero value that would wipe an existing permission.Membership needed the same care, and it's the one subtle bit here. There are three distinct intents:
--user-ids 5,6→ sync to those users--clear-members→ remove all membersA plain
[]intwithomitemptycollapses the last two — an explicit empty list serialises to nothing, so "remove everyone" would silently no-op. For a permission group, silently failing to revoke access is the wrong default. SoTeamUpdateRequest.UserIDsis a*[]int: nil omits the key, non-nil-but-empty sends"user_ids": [].--clear-membersexists as its own flag because cobra'sIntSliceVarcan't express an empty list from the command line (--user-ids ""fails to parse as an int slice). It's update-only and mutually exclusive with--user-ids.Note on
--adminWhen
--adminis set the server force-enables every other permission flag and grants all-projects access, regardless of what else is sent. The flag help and the SDK doc comment call this out; JSON output reflects the server's effective state.Test plan
go build ./cmd/dhq/go test ./...— full suite green (Teams: 12 SDK + 12 command tests)golangci-lint run ./...— 0 issuesuser_idsclear-membership path--user-ids/--clear-membersconflict--clear-members→ delete → list (cleanup confirmed)Out of scope
Write support for
project_assignmentsandexcluded_project_idsis deferred — both are surfaced read-side indhq teams show. First cut is scalar permission flags +--user-ids/--clear-membersmembership, which covers the common case.Summary by CodeRabbit
dhq teamsaccount-level commands to list, show, create, update, and delete teams.dhq teamscommand set.