Skip to content

Add CreateHabit and DeleteHabit#49

Open
JoshuaOliphant wants to merge 4 commits into
basecamp:mainfrom
JoshuaOliphant:add-create-delete-habit
Open

Add CreateHabit and DeleteHabit#49
JoshuaOliphant wants to merge 4 commits into
basecamp:mainfrom
JoshuaOliphant:add-create-delete-habit

Conversation

@JoshuaOliphant
Copy link
Copy Markdown

@JoshuaOliphant JoshuaOliphant commented Apr 22, 2026

What

Promotes CreateHabit and DeleteHabit from the phase-2 exclusion list through the full pipeline.

Changes

  • Smithy spec: CreateHabit (POST /calendar/habits.json) and DeleteHabit (DELETE /calendar/habits/{habitId}, @idempotent)
  • HabitPayload: title (required), days []int32 (optional — omit for server default)
  • Wire format: {calendar_habit: {title, days}} — matches the calendar_todo / calendar_event convention
  • spec/excluded-routes.json: removed the two phase-2 entries
  • Generated client: regenerated — DeleteHabit uses doWithRetry(..., true, ...) per @idempotent
  • HabitsService: Create(ctx, title, days []int32) and Delete(ctx, habitID int64)
  • url-routes.json + url.go: regenerated; fixed sort.Slicesort.SliceStable to preserve deterministic ordering when two routes share a pattern (the /topics/{topicId}/entries collision)

Tests

  • Unit: happy path, nil days, []int{} edge case, method/path verification on Delete, error paths (422, 404)
  • Conformance: path tests for both operations; idempotency tests for DeleteHabit on 503 and 429
  • Routing: TestRouterMatchPath cases for both paths

Checks

Check Result
Go vet + lint 0 issues
Go tests PASS
Conformance 85/85 PASS
Smithy validation
URL routes freshness

Summary by cubic

Adds CreateHabit (POST /calendar/habits.json) and DeleteHabit (DELETE /calendar/habits/{habitId}) to the SDK with end-to-end support. DeleteHabit is idempotent with retries; hooks metadata for habits is aligned.

  • New Features

    • Added CreateHabit and DeleteHabit to spec/hey.smithy and OpenAPI; DeleteHabit retries on 429/503 with exponential backoff.
    • Introduced HabitPayload (title required; days []int32 optional) with JSON {calendar_habit: {title, days}}.
    • Regenerated Go client and added HabitsService methods: Create(ctx, title string, days []int32) and Delete(ctx, habitID int64).
    • Updated routing and conformance: path tests for both ops and idempotency tests for delete; runner dispatch added; removed phase-2 exclusions.
    • Added “Working with Habits” examples to doc.go.
  • Bug Fixes

    • Aligned ResourceType to "habit" for Create/Delete to keep hooks/gating consistent; added empty-slice days test.
    • Made route sorting deterministic by switching to sort.SliceStable for patterns that collide.
    • Ensured CheckResponse errors propagate to operation hooks in calendar_todos.go and habits.go.

Written for commit 9e312e6. Summary will update on new commits.

JoshuaOliphant and others added 3 commits April 22, 2026 08:36
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>
Copilot AI review requested due to automatic review settings April 22, 2026 16:04
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 22, 2026

Spec Change Impact

Model output did not match expected format. Raw output truncated below.

```markdown
## Spec Change Impact

### Summary of Changes
- **New Operations Added:**
  - `CreateHabit`: Adds a new habit using the POST `/calendar/habits.json` endpoint.
  - `DeleteHabit`: Removes a habit using the DELETE `/calendar/habits/{habitId}` endpoint.

- **New Structures Added:**
  - `CreateHabitRequestContent`
  - `CreateHabitResponseContent`
  - `HabitPayload`

- **Removed Operations/Route Exclusions:**
  - Removed exclusion for `POST /calendar/habits`.
  - Removed exclusion for `DELETE /calendar/habits/{id}`.

### Impact Assessment
- **Go SDK Regeneration Required:** Yes. The new operations and their associated structures will need to be reflected in the Go SDK.
- **Breaking API Change:** No breaking changes identified. This PR only adds new operations and related types; no existing operations or structures are removed or modified.

### Checklist
- [

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

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.

Comment thread go/pkg/hey/habits.go Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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) and DeleteHabit (DELETE /calendar/habits/{habitId}, @idempotent) and updated behavior metadata.
  • Implemented HabitsService.Create and HabitsService.Delete in 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.

Comment thread go/pkg/hey/habits.go Outdated
Comment thread go/pkg/hey/habits.go Outdated
Comment thread go/pkg/hey/services_test.go
- 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>
@JoshuaOliphant
Copy link
Copy Markdown
Author

JoshuaOliphant commented May 15, 2026

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants