feat: implement work add, work check, issue daily-sync (PR 5/5) #16
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/work-and-daily-sync"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
PR 5 of 5. Finishes the YouTrack subcommand port:
work add,work check, andissue daily-syncare now wired end-to-end. With this PR every command surface from the Go CLI is implemented.New api helpers (
src/yt/api.rs)add_work_item: POST{duration:{presentation:"Xm"}, text}to/api/issues/<id>/timeTracking/workItems. Rejects 0 minutes and empty description before sending.check_work: listfor:meissues, fetch each issue's work items with a minimaldate-only field selector, return<id>: <summary>rows for issues with no work in the[today_start_ms, today_end_ms)window. The window is a parameter so tests can drive the comparison from any clock; thework checkcommand supplies UTC midnight.daily_sync: orchestrates work -> comment -> state in order. ReturnsVec<String>of completed actions on success; on partial failure returnsDailySyncFailure { actions, error }so the caller can render what landed before the failure point.Command modules
work add <id> <minutes> <description...>: joins description words, rejects 0 minutes, printsWork item added successfully..work check [--json]: computes today's UTC window viaOffsetDateTime::now_utc().replace_hour(0)...(matches Go'sTruncate(24h)). PrintsAll issues have work logged for today.or- <id>: <summary>per row.--jsonemits the array.issue daily-sync <id> [--minutes N] [--comment T] [--state S] [--work W]: maps the four flags intoDailySyncOptions. On success:Daily sync completed for <id>.+ action lines. On partial failure:Partial sync for <id>:+ completed actions, then the underlying error (non-zero exit).Verification
cargo fmt --checkclean.cargo clippy --all-targets -- -D warningsclean.cargo test --all-targets: 136 tests pass (24 new on this branch)."not yet implemented"strings remain insrc/.Test coverage on this PR
daily_syncreturnsactions = ["logged 30 minutes"]plus the 500 error when the comment POST fails after work succeeds.check_workskips an issue whose work-item sub-fetch fails (logged via tracing) rather than aborting.today_utc_window_msinvariant: 24h length, midnight alignment.Behavioral notes
work checkuses UTC midnight as the "today" boundary, matching Go'sTruncate(24h). Local-time alignment is out of scope here but called out for follow-up if a user complains about late-evening edits being counted toward the wrong day.daily-syncon partial failure both prints the actions that landed AND exits non-zero, so scripts wrapping it can see the error code while operators see what state the issue is in.Sequence
This is PR 5 of 5. The 5-PR sequence (PRs #12, #13, #14, #15, this one) ports every stubbed subcommand to a real implementation backed by the YouTrack API.
CLAUDE.mdis updated to drop the "milestone 1" status line.PR 5 of 5. Finishes the YouTrack subcommand port. New `yt::api` helpers: `add_work_item` posts `{duration:{presentation:"Xm"}, text}` to `/api/issues/<id>/timeTracking/workItems` and validates minutes > 0 and non-empty description before sending; `check_work` lists assigned issues via `query=for:me`, fetches each issue's work items with a minimal `date`-only field selector, and returns the `<id>: <summary>` rows for issues with no work logged inside the `[today_start_ms, today_end_ms)` UTC window (passed in by the caller for testability, defaulted to UTC midnight by `work check`); `daily_sync` orchestrates the composite work-then-comment-then-state flow, returning the action log on success and a `DailySyncFailure { actions, error }` on partial failure so callers can show what landed before the failure point. The command modules are thin: `work add` joins the multi-word description, prints `Work item added successfully.`, refuses 0 minutes upfront. `work check` computes today's UTC window via `OffsetDateTime::now_utc().replace_hour(0)` (matches Go's `Truncate(24h)`), prints either `All issues have work logged for today.` or `- <id>: <summary>` per row, supports `--json` for the array. `issue daily-sync` maps the four optional flags into `DailySyncOptions`, prints `Daily sync completed for <id>.` plus the action log on success; on partial failure, prints `Partial sync for <id>:` with the actions that completed, then surfaces the underlying error so the exit code is non-zero. Tests cover every body shape via wiremock body_json matchers, every input-validation path (minutes=0, empty description, nothing-to-do, minutes-without-description), partial-failure with action-list preservation, per-issue work-fetch failure being skipped rather than fatal in `check_work`, plus a `today_utc_window_ms` invariant test (24h length, midnight alignment). 136 tests pass; clippy clean; fmt clean. CLAUDE.md status line updated since every subcommand is now wired end-to-end. The 5-PR sequence is complete.