diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index a132e20..0fa83b7 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -5,7 +5,7 @@ {"id":"checkvist-api-1zf","title":"Write unit tests for Filter","description":"Create filter_test.go with tests:\n- TestFilter_WithTag\n- TestFilter_WithMultipleTags\n- TestFilter_WithStatus\n- TestFilter_WithDueBefore\n- TestFilter_WithDueAfter\n- TestFilter_WithDueOn\n- TestFilter_WithOverdue\n- TestFilter_WithSearch\n- TestFilter_Combined\n- TestFilter_Performance_1000Tasks\nUse table-driven tests.","status":"open","priority":1,"issue_type":"task","owner":"mail@oliverjakoubek.de","created_at":"2026-01-14T12:31:38.136650557+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-14T12:31:38.136650557+01:00","dependencies":[{"issue_id":"checkvist-api-1zf","depends_on_id":"checkvist-api-1ze","type":"blocks","created_at":"2026-01-14T12:33:14.4378645+01:00","created_by":"Oliver Jakoubek"}]} {"id":"checkvist-api-347","title":"Write unit tests for Checklists","description":"Create checklists_test.go with tests:\n- TestChecklists_List\n- TestChecklists_ListArchived\n- TestChecklists_Get\n- TestChecklists_Get_NotFound\n- TestChecklists_Create\n- TestChecklists_Update\n- TestChecklists_Delete\nUse table-driven tests. Create testdata/checklists/ fixtures.","status":"open","priority":0,"issue_type":"task","owner":"mail@oliverjakoubek.de","created_at":"2026-01-14T12:31:37.243525209+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-14T12:31:37.243525209+01:00","dependencies":[{"issue_id":"checkvist-api-347","depends_on_id":"checkvist-api-c2k","type":"blocks","created_at":"2026-01-14T12:33:13.512887479+01:00","created_by":"Oliver Jakoubek"}]} {"id":"checkvist-api-47y","title":"Quality \u0026 Documentation","description":"Phase 4: Complete unit tests, GoDoc examples, README, and CHANGELOG. Target \u003e80% test coverage. All public functions documented with examples.","status":"open","priority":0,"issue_type":"epic","owner":"mail@oliverjakoubek.de","created_at":"2026-01-14T12:31:36.655509387+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-14T12:31:36.655509387+01:00"} -{"id":"checkvist-api-5ab","title":"Implement Note operations","description":"Create notes.go with NoteService:\n- client.Notes(checklistID, taskID) returns NoteService\n- List(ctx) ([]Note, error) - GET /checklists/{id}/tasks/{task_id}/comments.json\n- Create(ctx, comment string) (*Note, error) - POST /checklists/{id}/tasks/{task_id}/comments.json\n- Update(ctx, noteID, comment string) (*Note, error) - PUT /checklists/{id}/tasks/{task_id}/comments/{note_id}.json\n- Delete(ctx, noteID) error - DELETE /checklists/{id}/tasks/{task_id}/comments/{note_id}.json\nContext support for all methods.","status":"open","priority":0,"issue_type":"feature","owner":"mail@oliverjakoubek.de","created_at":"2026-01-14T12:30:54.268124634+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-14T12:30:54.268124634+01:00","dependencies":[{"issue_id":"checkvist-api-5ab","depends_on_id":"checkvist-api-rl9","type":"blocks","created_at":"2026-01-14T12:32:55.843507717+01:00","created_by":"Oliver Jakoubek"}]} +{"id":"checkvist-api-5ab","title":"Implement Note operations","description":"Create notes.go with NoteService:\n- client.Notes(checklistID, taskID) returns NoteService\n- List(ctx) ([]Note, error) - GET /checklists/{id}/tasks/{task_id}/comments.json\n- Create(ctx, comment string) (*Note, error) - POST /checklists/{id}/tasks/{task_id}/comments.json\n- Update(ctx, noteID, comment string) (*Note, error) - PUT /checklists/{id}/tasks/{task_id}/comments/{note_id}.json\n- Delete(ctx, noteID) error - DELETE /checklists/{id}/tasks/{task_id}/comments/{note_id}.json\nContext support for all methods.","status":"closed","priority":0,"issue_type":"feature","owner":"mail@oliverjakoubek.de","created_at":"2026-01-14T12:30:54.268124634+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-14T13:40:31.06124818+01:00","closed_at":"2026-01-14T13:40:31.06124818+01:00","close_reason":"Closed","dependencies":[{"issue_id":"checkvist-api-5ab","depends_on_id":"checkvist-api-rl9","type":"blocks","created_at":"2026-01-14T12:32:55.843507717+01:00","created_by":"Oliver Jakoubek"}]} {"id":"checkvist-api-5wr","title":"Initialize Go module and project structure","description":"Create go.mod with module path code.beautifulmachines.dev/jakoubek/checkvist-api. Set up flat package structure with placeholder files: client.go, checklists.go, tasks.go, notes.go, filter.go, models.go, errors.go, options.go. Create magefiles/ directory with separate go.mod for Mage build targets. Add LICENSE (MIT) file.","status":"closed","priority":0,"issue_type":"task","owner":"mail@oliverjakoubek.de","created_at":"2026-01-14T12:31:06.285510329+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-14T12:43:45.392753825+01:00","closed_at":"2026-01-14T12:43:45.392753825+01:00","close_reason":"Closed"} {"id":"checkvist-api-8bn","title":"Write unit tests for Client and Auth","description":"Create client_test.go with tests using httptest.Server:\n- TestNewClient_Defaults\n- TestNewClient_WithOptions\n- TestAuthenticate_Success\n- TestAuthenticate_InvalidCredentials\n- TestAuthenticate_2FA\n- TestTokenRefresh_Auto\n- TestTokenRefresh_Manual\n- TestCurrentUser\n- TestRetryLogic_429\n- TestRetryLogic_5xx\n- TestRetryLogic_NetworkError\nUse table-driven tests. Create testdata/auth/ fixtures.","status":"closed","priority":0,"issue_type":"task","owner":"mail@oliverjakoubek.de","created_at":"2026-01-14T12:31:36.964610587+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-14T13:35:19.981723023+01:00","closed_at":"2026-01-14T13:35:19.981723023+01:00","close_reason":"Closed","dependencies":[{"issue_id":"checkvist-api-8bn","depends_on_id":"checkvist-api-lpn","type":"blocks","created_at":"2026-01-14T12:33:12.783142853+01:00","created_by":"Oliver Jakoubek"},{"issue_id":"checkvist-api-8bn","depends_on_id":"checkvist-api-8u6","type":"blocks","created_at":"2026-01-14T12:33:13.232028837+01:00","created_by":"Oliver Jakoubek"}]} {"id":"checkvist-api-8jh","title":"Implement repeating tasks configuration","description":"Add P2 (nice-to-have) repeat support to TaskBuilder:\n- WithRepeat(pattern string) *TaskBuilder\nSupport Checkvist smart syntax for repeats.\nDocument common patterns in GoDoc.","status":"open","priority":2,"issue_type":"feature","owner":"mail@oliverjakoubek.de","created_at":"2026-01-14T12:30:56.826106108+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-14T12:30:56.826106108+01:00","dependencies":[{"issue_id":"checkvist-api-8jh","depends_on_id":"checkvist-api-tjk","type":"blocks","created_at":"2026-01-14T12:33:03.159849575+01:00","created_by":"Oliver Jakoubek"}]} diff --git a/notes.go b/notes.go index 7911513..18390dd 100644 --- a/notes.go +++ b/notes.go @@ -1,3 +1,75 @@ package checkvist +import ( + "context" + "fmt" +) + // notes.go contains the NoteService for CRUD operations on notes (comments) attached to tasks. + +// NoteService provides operations on notes (comments) attached to a specific task. +type NoteService struct { + client *Client + checklistID int + taskID int +} + +// Notes returns a NoteService for performing note operations on the specified task. +func (c *Client) Notes(checklistID, taskID int) *NoteService { + return &NoteService{ + client: c, + checklistID: checklistID, + taskID: taskID, + } +} + +// List returns all notes (comments) attached to the task. +func (s *NoteService) List(ctx context.Context) ([]Note, error) { + path := fmt.Sprintf("/checklists/%d/tasks/%d/comments.json", s.checklistID, s.taskID) + + var notes []Note + if err := s.client.doGet(ctx, path, ¬es); err != nil { + return nil, err + } + return notes, nil +} + +// createNoteRequest is the request body for creating a note. +type createNoteRequest struct { + Comment string `json:"comment"` +} + +// Create creates a new note (comment) on the task. +func (s *NoteService) Create(ctx context.Context, comment string) (*Note, error) { + path := fmt.Sprintf("/checklists/%d/tasks/%d/comments.json", s.checklistID, s.taskID) + body := createNoteRequest{Comment: comment} + + var note Note + if err := s.client.doPost(ctx, path, body, ¬e); err != nil { + return nil, err + } + return ¬e, nil +} + +// updateNoteRequest is the request body for updating a note. +type updateNoteRequest struct { + Comment string `json:"comment"` +} + +// Update updates an existing note's comment text. +func (s *NoteService) Update(ctx context.Context, noteID int, comment string) (*Note, error) { + path := fmt.Sprintf("/checklists/%d/tasks/%d/comments/%d.json", s.checklistID, s.taskID, noteID) + body := updateNoteRequest{Comment: comment} + + var note Note + if err := s.client.doPut(ctx, path, body, ¬e); err != nil { + return nil, err + } + return ¬e, nil +} + +// Delete permanently deletes a note. +func (s *NoteService) Delete(ctx context.Context, noteID int) error { + path := fmt.Sprintf("/checklists/%d/tasks/%d/comments/%d.json", s.checklistID, s.taskID, noteID) + return s.client.doDelete(ctx, path) +}