Add CreateHabit and DeleteHabit#49
Conversation
Promotes CreateHabit and DeleteHabit from phase-2 exclusions through the full pipeline: Smithy spec → OpenAPI → generated Go client → HabitsService methods → unit tests → conformance tests → routing tests → documentation. - spec/hey.smithy: add CreateHabit (POST) and DeleteHabit (DELETE @idempotent) with HabitPayload struct (title required, days optional) - spec/excluded-routes.json: remove phase-2 exclusions for habit create/delete - openapi.json, behavior-model.json: regenerated - go/pkg/generated/client.gen.go: regenerated with new operations - spec/route-coverage.json: updated to 47 operations - go/pkg/hey/url-routes.json: updated to 43 routes / 47 operations - go/pkg/hey/habits.go: Create and Delete service methods - go/pkg/hey/url.go: fix sort.Slice → sort.SliceStable for deterministic route ordering when multiple entries share the same URL pattern - go/pkg/hey/services_test.go: unit tests for Create (with/without days) and Delete - go/pkg/hey/url_test.go: routing table tests for both new paths - conformance/tests/paths.json: path conformance tests for both operations - conformance/tests/idempotency.json: retry conformance test for DeleteHabit - conformance/runner/go/main.go: dispatch cases for CreateHabit and DeleteHabit - go/pkg/hey/doc.go: Working with Habits section Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- habits.go, calendar_todos.go: fix CheckResponse named-return bug — `return CheckResponse(...)` did not assign through the named `err` variable, causing OnOperationEnd hooks to fire with err=nil on HTTP errors; now explicitly `err = CheckResponse(...); return err` - habits.go: clarify days doc comment — nil or empty slice both omit the field; a non-empty slice is sent verbatim - services_test.go: add method and path assertions to TestHabitsService_Delete (matching TestDesignationsService_Destroy pattern) - services_test.go: add TestHabitsService_Create_Error (422) and TestHabitsService_Delete_Error (404) negative-path tests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- habits.go, doc.go: change Create days parameter from []int to []int32 to match HabitPayload.Days in the generated client (following the []int64 precedent in postings.go) - services_test.go: update test calls to []int32; add per-value assertions for days array (JSON numbers unmarshal as float64 in map[string]any) - conformance/tests/idempotency.json: add "DELETE habit retries on 429" test alongside the existing 503 test (behavior-model lists both 429 and 503 as retry triggers for DeleteHabit) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Spec Change ImpactModel output did not match expected format. Raw output truncated below. |
There was a problem hiding this comment.
1 issue found across 16 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="go/pkg/hey/habits.go">
<violation number="1" location="go/pkg/hey/habits.go:29">
P2: New habit operations use a different `OperationInfo.ResourceType` (`calendar_habit`) than existing habit operations (`habit`), creating inconsistent hook/gating classification within the same service.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
There was a problem hiding this comment.
Pull request overview
Promotes the CreateHabit and DeleteHabit operations from excluded/phase-2 into the full SDK pipeline (Smithy/OpenAPI specs, generated Go client, hand-written service wrapper, routing metadata, and conformance/unit tests).
Changes:
- Added Smithy + OpenAPI definitions for
CreateHabit(POST/calendar/habits.json) andDeleteHabit(DELETE/calendar/habits/{habitId},@idempotent) and updated behavior metadata. - Implemented
HabitsService.CreateandHabitsService.Deletein the Go SDK, plus corresponding unit and conformance coverage. - Regenerated routing tables and adjusted route sorting to be stable for deterministic matching when patterns collide.
Tip
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| spec/route-coverage.json | Adds coverage entries for Create/Delete habit and updates some existing route paths to .json variants. |
| spec/hey.smithy | Defines CreateHabit/DeleteHabit operations and HabitPayload wire contract. |
| spec/excluded-routes.json | Removes the phase-2 exclusions for habit create/delete routes. |
| openapi.json | Publishes the new habit endpoints and schemas into the OpenAPI output. |
| go/pkg/hey/url_test.go | Adds router match tests for the habit create/delete paths. |
| go/pkg/hey/url.go | Switches to sort.SliceStable for deterministic route ordering. |
| go/pkg/hey/url-routes.json | Adds the new habit route entries to the embedded route table. |
| go/pkg/hey/services_test.go | Adds unit tests for HabitsService create/delete (happy + error paths). |
| go/pkg/hey/habits.go | Adds HabitsService.Create and HabitsService.Delete. |
| go/pkg/hey/doc.go | Documents basic habit usage examples in the package docs. |
| go/pkg/hey/calendar_todos.go | Minor refactor to store and return CheckResponse error consistently. |
| go/pkg/generated/client.gen.go | Regenerates the Go client with CreateHabit/DeleteHabit operations and models. |
| conformance/tests/paths.json | Adds path conformance cases for CreateHabit/DeleteHabit and reformats existing cases. |
| conformance/tests/idempotency.json | Adds idempotency/retry conformance cases for DeleteHabit and reformats. |
| conformance/runner/go/main.go | Wires the new operations into the Go conformance runner dispatch. |
| behavior-model.json | Adds behavior metadata for CreateHabit/DeleteHabit (retry/idempotency flags). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- habits.go: align ResourceType to "habit" for Create and Delete,
matching Complete/Uncomplete in the same service; inconsistency
caused different hook/gating classification within HabitsService
- services_test.go: add TestHabitsService_Create_EmptyDays to cover
the []int32{} case (len == 0, non-nil), asserting days is omitted
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Good morning, haven't heard anything since opening this PR so following up. I addressed all of the automated feedback. Anything further you'd like me to change? |
What
Promotes
CreateHabitandDeleteHabitfrom the phase-2 exclusion list through the full pipeline.Changes
CreateHabit(POST/calendar/habits.json) andDeleteHabit(DELETE/calendar/habits/{habitId},@idempotent)HabitPayload:title(required),days []int32(optional — omit for server default){calendar_habit: {title, days}}— matches thecalendar_todo/calendar_eventconventionspec/excluded-routes.json: removed the two phase-2 entriesDeleteHabitusesdoWithRetry(..., true, ...)per@idempotentHabitsService:Create(ctx, title, days []int32)andDelete(ctx, habitID int64)url-routes.json+url.go: regenerated; fixedsort.Slice→sort.SliceStableto preserve deterministic ordering when two routes share a pattern (the/topics/{topicId}/entriescollision)Tests
[]int{}edge case, method/path verification on Delete, error paths (422, 404)DeleteHabiton 503 and 429TestRouterMatchPathcases for both pathsChecks
Summary by cubic
Adds
CreateHabit(POST/calendar/habits.json) andDeleteHabit(DELETE/calendar/habits/{habitId}) to the SDK with end-to-end support.DeleteHabitis idempotent with retries; hooks metadata for habits is aligned.New Features
CreateHabitandDeleteHabittospec/hey.smithyand OpenAPI;DeleteHabitretries on 429/503 with exponential backoff.HabitPayload(title required; days[]int32optional) with JSON{calendar_habit: {title, days}}.HabitsServicemethods:Create(ctx, title string, days []int32)andDelete(ctx, habitID int64).doc.go.Bug Fixes
ResourceTypeto "habit" for Create/Delete to keep hooks/gating consistent; added empty-slice days test.sort.SliceStablefor patterns that collide.CheckResponseerrors propagate to operation hooks incalendar_todos.goandhabits.go.Written for commit 9e312e6. Summary will update on new commits.