Skip to content

fix: use int type for RoutineFolder ID fields#1

Open
asabirov wants to merge 1 commit intoobay:mainfrom
asabirov:fix/routine-folder-id-type
Open

fix: use int type for RoutineFolder ID fields#1
asabirov wants to merge 1 commit intoobay:mainfrom
asabirov:fix/routine-folder-id-type

Conversation

@asabirov
Copy link
Copy Markdown

@asabirov asabirov commented Mar 29, 2026

Summary

  • Changed RoutineFolder.ID from string to int and Routine.FolderID from *string to *int to match the Hevy API response format
  • Updated all API client methods and CLI commands to handle integer folder IDs (parsing from CLI args, formatting for display/URLs)
  • Fixes: json: cannot unmarshal number into Go struct field RoutineFolder.routine_folders.id of type string

Test plan

  • go build ./... passes
  • go test ./... passes
  • Manual: hevycli folder list no longer errors
  • Manual: hevycli folder get <id>, update, delete work with integer IDs

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes & Refactor
    • Folder IDs are now properly validated as numeric identifiers. Invalid folder ID inputs are now rejected with clear error messages in create, delete, get, and update operations.
    • Improved type consistency for folder ID handling throughout the application, ensuring more reliable operations.

The Hevy API returns routine folder IDs as JSON numbers, but the Go
structs declared them as strings, causing json.Unmarshal to fail with
"cannot unmarshal number into Go struct field RoutineFolder.id of type string".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 29, 2026

📝 Walkthrough

Walkthrough

This change converts folder ID handling from strings to integers across the codebase, updating the API type definitions, client method signatures, and CLI command parsing and output formatting to enforce numeric ID representation consistently.

Changes

Cohort / File(s) Summary
Type System & API Client
internal/api/types.go, internal/api/client.go
Updated Routine.FolderID from *string to *int and RoutineFolder.ID from string to int. Changed client methods (GetRoutineFolder, UpdateRoutineFolder, DeleteRoutineFolder) to accept id int and construct REST endpoints using %d format instead of string concatenation.
Folder Commands
cmd/folder/create.go, cmd/folder/delete.go, cmd/folder/get.go, cmd/folder/list.go, cmd/folder/update.go
Updated folder commands to parse CLI arguments and interactive selections as integers using strconv.Atoi, with error handling for invalid conversions. Output formatting changed from %s to %d for ID display. Interactive mode converts selected string IDs back to integers via fmt.Sprintf and strconv.Atoi.
Routine Commands
cmd/routine/get.go, cmd/routine/list.go
Updated routine commands to format and filter folder IDs as integers. The --folder flag now parses input as int with validation, and table output displays folder IDs as formatted decimal strings via fmt.Sprintf("%d", ...). Print statements changed from %s to %d.

Poem

🐰 With whiskers twitching, I hop with glee,
String IDs transformed to integers, you see!
No more fuzzy types in the warren's code,
Just clean, crisp numbers down the pathway trod. 🔢

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: converting RoutineFolder ID fields from string to int type, which is the core objective of all modifications across the codebase.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

@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: 1

Caution

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

⚠️ Outside diff range comments (1)
cmd/folder/get.go (1)

23-24: ⚠️ Potential issue | 🟡 Minor

Update folder get examples to numeric IDs

These examples still show string IDs, which conflicts with the new integer-only parsing and will mislead users.

Suggested patch
-  hevycli folder get abc123-def456    # Get folder by ID
-  hevycli folder get abc123 -o json   # Output as JSON`,
+  hevycli folder get 123456           # Get folder by ID
+  hevycli folder get 123456 -o json   # Output as JSON`,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/folder/get.go` around lines 23 - 24, Update the command examples in the
folder get help text so they use numeric IDs instead of string UUIDs (e.g.,
change "hevycli folder get abc123-def456" to "hevycli folder get 123" and
"hevycli folder get abc123 -o json" to "hevycli folder get 123 -o json"); locate
and edit the example/usage string in cmd/folder/get.go (the folder get command
help/usage variable or function that builds the examples) so all example
invocations reflect integer-only IDs.
🧹 Nitpick comments (2)
cmd/folder/delete.go (1)

90-90: Don't drop the interactive conversion error before delete.

If selected.ID is ever malformed, Line 90 falls back to 0 and carries that value into the fetch/delete path. It's safer to fail fast here.

Suggested fix
-		folderID, _ = strconv.Atoi(selected.ID)
+		folderID, err = strconv.Atoi(selected.ID)
+		if err != nil {
+			return fmt.Errorf("invalid folder ID: %s", selected.ID)
+		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/folder/delete.go` at line 90, The code currently ignores strconv.Atoi
errors by doing folderID, _ = strconv.Atoi(selected.ID); instead, check the
error returned from strconv.Atoi when converting selected.ID to folderID and
fail fast (return the error or call the command's error/exit path) rather than
defaulting to 0; update the conversion in the delete command so it validates
selected.ID, logs/returns a clear error mentioning selected.ID, and stops before
calling the fetch/delete logic that uses folderID.
cmd/folder/update.go (1)

84-84: Don't drop the interactive conversion error.

prompt.SelectOption.ID is still a string. If it ever stops being numeric, Line 84 silently turns that into folderID == 0 before the update call. Bubble the parse failure up here instead.

Suggested fix
-		folderID, _ = strconv.Atoi(selected.ID)
+		folderID, err = strconv.Atoi(selected.ID)
+		if err != nil {
+			return fmt.Errorf("invalid folder ID: %s", selected.ID)
+		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/folder/update.go` at line 84, The current code silently ignores
strconv.Atoi errors when converting selected.ID to folderID (folderID, _ =
strconv.Atoi(selected.ID)); change this to capture and handle the error instead:
use folderID, err := strconv.Atoi(selected.ID) and if err != nil return or
propagate the error (or wrap it with context) before proceeding to the Update
call so non-numeric IDs don't become 0; update references in
cmd/folder/update.go around the selected.ID conversion and the surrounding
function (where folderID is used) to properly bubble the parse failure.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmd/folder/get.go`:
- Line 74: The code currently ignores the error from strconv.Atoi(selected.ID)
causing a silent fallback to 0; update the conversion to capture the error
(e.g., folderID, err := strconv.Atoi(selected.ID)) and handle it by returning or
logging a clear error (for example return fmt.Errorf("invalid folder ID %q: %w",
selected.ID, err) or printing and exiting), ensuring the calling function (where
selected and folderID are used) treats the conversion failure as an actual error
rather than proceeding with 0.

---

Outside diff comments:
In `@cmd/folder/get.go`:
- Around line 23-24: Update the command examples in the folder get help text so
they use numeric IDs instead of string UUIDs (e.g., change "hevycli folder get
abc123-def456" to "hevycli folder get 123" and "hevycli folder get abc123 -o
json" to "hevycli folder get 123 -o json"); locate and edit the example/usage
string in cmd/folder/get.go (the folder get command help/usage variable or
function that builds the examples) so all example invocations reflect
integer-only IDs.

---

Nitpick comments:
In `@cmd/folder/delete.go`:
- Line 90: The code currently ignores strconv.Atoi errors by doing folderID, _ =
strconv.Atoi(selected.ID); instead, check the error returned from strconv.Atoi
when converting selected.ID to folderID and fail fast (return the error or call
the command's error/exit path) rather than defaulting to 0; update the
conversion in the delete command so it validates selected.ID, logs/returns a
clear error mentioning selected.ID, and stops before calling the fetch/delete
logic that uses folderID.

In `@cmd/folder/update.go`:
- Line 84: The current code silently ignores strconv.Atoi errors when converting
selected.ID to folderID (folderID, _ = strconv.Atoi(selected.ID)); change this
to capture and handle the error instead: use folderID, err :=
strconv.Atoi(selected.ID) and if err != nil return or propagate the error (or
wrap it with context) before proceeding to the Update call so non-numeric IDs
don't become 0; update references in cmd/folder/update.go around the selected.ID
conversion and the surrounding function (where folderID is used) to properly
bubble the parse failure.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4070201e-2551-4779-9c2c-47eadb69c920

📥 Commits

Reviewing files that changed from the base of the PR and between 0a309a5 and 996062f.

📒 Files selected for processing (9)
  • cmd/folder/create.go
  • cmd/folder/delete.go
  • cmd/folder/get.go
  • cmd/folder/list.go
  • cmd/folder/update.go
  • cmd/routine/get.go
  • cmd/routine/list.go
  • internal/api/client.go
  • internal/api/types.go

return err
}
folderID = selected.ID
folderID, _ = strconv.Atoi(selected.ID)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Handle selected.ID conversion errors instead of discarding them

Ignoring Atoi errors can silently coerce to 0 and produce misleading “not found” behavior if ID formatting changes later.

Suggested patch
-		folderID, _ = strconv.Atoi(selected.ID)
+		var err error
+		folderID, err = strconv.Atoi(selected.ID)
+		if err != nil {
+			return fmt.Errorf("invalid selected folder ID: %q", selected.ID)
+		}
📝 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
folderID, _ = strconv.Atoi(selected.ID)
var err error
folderID, err = strconv.Atoi(selected.ID)
if err != nil {
return fmt.Errorf("invalid selected folder ID: %q", selected.ID)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/folder/get.go` at line 74, The code currently ignores the error from
strconv.Atoi(selected.ID) causing a silent fallback to 0; update the conversion
to capture the error (e.g., folderID, err := strconv.Atoi(selected.ID)) and
handle it by returning or logging a clear error (for example return
fmt.Errorf("invalid folder ID %q: %w", selected.ID, err) or printing and
exiting), ensuring the calling function (where selected and folderID are used)
treats the conversion failure as an actual error rather than proceeding with 0.

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