feat: bl project version add / update / delete#83
Conversation
📝 WalkthroughWalkthroughThis PR adds three new project version management commands ( Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches✨ Simplify code
📝 Coding Plan
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. Comment |
There was a problem hiding this comment.
Pull request overview
Adds full CRUD support for Backlog project versions (milestones) to the bl CLI, including API client support, clap wiring, tests, and command documentation updates to reflect the newly implemented subcommands (Issue #41).
Changes:
- Introduce
bl project version add|update|deletesubcommands and wire them insrc/main.rs. - Implement
add_project_version,update_project_version,delete_project_versioninBacklogClientand expose them via theBacklogApitrait. - Document the new commands and mark them as implemented in both English and Japanese command docs.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
src/api/project.rs |
Adds BacklogClient methods for adding/updating/deleting project versions via form/patch/delete requests. |
src/api/mod.rs |
Extends BacklogApi trait + delegates new methods in BacklogClient impl. |
src/cmd/project/version.rs |
Adds args structs and add/update/delete command handlers with unit tests. |
src/main.rs |
Wires new clap subcommands to the corresponding command handlers. |
website/docs/commands.md |
Documents new commands and updates the endpoint/command mapping table to “Implemented”. |
website/i18n/ja/docusaurus-plugin-content-docs/current/commands.md |
Japanese docs for new commands + mapping table updates. |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/cmd/project/version.rs (1)
17-95: Consider enforcing date-format invariants in args construction.
start_date/release_due_dateare documented asYYYY-MM-DDbut currently pass through unchecked. Atry_newconstructor for add/update args would keep validation at the intended boundary and fail fast before API calls.As per coding guidelines: "Validation boundaries:
main.rs(clap) handles syntactic/type-level checks;Args::try_newhandles domain invariants;cmd/*_withhandles API call logic, output formatting, and API-spec constraints;api/handles HTTP-level error translation only."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/cmd/project/version.rs` around lines 17 - 95, Add a try_new constructor that validates the YYYY-MM-DD date invariants for ProjectVersionAddArgs and ProjectVersionUpdateArgs: implement ProjectVersionAddArgs::try_new(...) -> Result<Self, YourError> and ProjectVersionUpdateArgs::try_new(...) -> Result<Self, YourError> which parse/validate optional start_date and release_due_date (e.g., via chrono::NaiveDate::parse_from_str or equivalent) and return Err on invalid format; keep the same fields (Option<String>) if validation passes and return Ok(Self{...}); update call sites to use try_new where args are constructed so domain invariants are enforced before API calls.src/api/project.rs (1)
293-367: Add API-layer tests for the new project version mutation methods.
add_project_version,update_project_version, anddelete_project_versionwere added, but this file doesn’t add correspondinghttpmocktests for request path/form payloads and response parsing. Please add parity tests like the other project API methods.As per coding guidelines: "For `api/` layer tests, use `httpmock` to spin up a local HTTP server and construct `BacklogClient::new_with(base_url, api_key)` instead of calling `BacklogClient::from_config()`."🧪 Suggested test additions (pattern)
+ #[test] + fn add_project_version_returns_parsed_struct() { + let server = MockServer::start(); + server.mock(|when, then| { + when.method(POST).path("/projects/TEST/versions"); + then.status(201).json_body(json!({ + "id": 5, "projectId": 1, "name": "v1.0", + "description": null, "startDate": null, "releaseDueDate": null, + "archived": false, "displayOrder": 0 + })); + }); + let client = BacklogClient::new_with(&server.base_url(), "test-key").unwrap(); + let v = client.add_project_version("TEST", "v1.0", None, None, None).unwrap(); + assert_eq!(v.id, 5); + } + + #[test] + fn update_project_version_returns_parsed_struct() { /* same pattern for PATCH */ } + + #[test] + fn delete_project_version_returns_parsed_struct() { /* same pattern for DELETE */ }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/api/project.rs` around lines 293 - 367, Add httpmock-based API tests that exercise add_project_version, update_project_version, and delete_project_version: spin up an httpmock server, construct BacklogClient::new_with(base_url, api_key), register mock endpoints for POST /projects/{key}/versions, PATCH /projects/{key}/versions/{version_id}, and DELETE /projects/{key}/versions/{version_id}, assert incoming request paths and form payloads (name, description, startDate, releaseDueDate, archived as applicable), return representative JSON responses, and verify serde parsing by asserting the returned ProjectVersion values; follow the same test pattern used by the other project API tests and use httpmock for server lifecycle.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/api/project.rs`:
- Around line 293-367: Add httpmock-based API tests that exercise
add_project_version, update_project_version, and delete_project_version: spin up
an httpmock server, construct BacklogClient::new_with(base_url, api_key),
register mock endpoints for POST /projects/{key}/versions, PATCH
/projects/{key}/versions/{version_id}, and DELETE
/projects/{key}/versions/{version_id}, assert incoming request paths and form
payloads (name, description, startDate, releaseDueDate, archived as applicable),
return representative JSON responses, and verify serde parsing by asserting the
returned ProjectVersion values; follow the same test pattern used by the other
project API tests and use httpmock for server lifecycle.
In `@src/cmd/project/version.rs`:
- Around line 17-95: Add a try_new constructor that validates the YYYY-MM-DD
date invariants for ProjectVersionAddArgs and ProjectVersionUpdateArgs:
implement ProjectVersionAddArgs::try_new(...) -> Result<Self, YourError> and
ProjectVersionUpdateArgs::try_new(...) -> Result<Self, YourError> which
parse/validate optional start_date and release_due_date (e.g., via
chrono::NaiveDate::parse_from_str or equivalent) and return Err on invalid
format; keep the same fields (Option<String>) if validation passes and return
Ok(Self{...}); update call sites to use try_new where args are constructed so
domain invariants are enforced before API calls.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 28d7c344-f6ed-4b2c-b85d-a3dacadadac1
📒 Files selected for processing (6)
src/api/mod.rssrc/api/project.rssrc/cmd/project/version.rssrc/main.rswebsite/docs/commands.mdwebsite/i18n/ja/docusaurus-plugin-content-docs/current/commands.md
Checklist
mainwebsite/docs/,website/i18n/ja/,README.md)Summary
bl project version add,update,deletesubcommandsadd_project_version,update_project_version,delete_project_versioninBacklogClientandBacklogApitraitReason for change
Implements #41.
Changes
src/api/project.rs: Addadd_project_version,update_project_version,delete_project_versionsrc/api/mod.rs: Declare trait methods and delegate toBacklogClientsrc/cmd/project/version.rs: Addadd_with,update_with,delete_withwith testssrc/main.rs: Wire up new subcommands via clapwebsite/docs/commands.md,website/i18n/ja/.../commands.md: Add docs and mark as implementedNotes
Closes #41