diff --git a/.beads/sync_base.jsonl b/.beads/sync_base.jsonl index 534ceb9..15b99f0 100644 --- a/.beads/sync_base.jsonl +++ b/.beads/sync_base.jsonl @@ -27,6 +27,7 @@ {"id":"checkvist-api-mnh","title":"Implement error types and sentinel errors","description":"Create errors.go with:\n- APIError struct (StatusCode, Message, RequestID, Err) with Error() and Unwrap() methods\n- Sentinel errors: ErrUnauthorized, ErrNotFound, ErrRateLimited, ErrBadRequest, ErrServerError\n- Helper function to create APIError from HTTP response","status":"closed","priority":0,"issue_type":"task","owner":"mail@oliverjakoubek.de","created_at":"2026-01-14T12:31:07.619359293+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-14T13:23:43.296883265+01:00","closed_at":"2026-01-14T13:23:43.296883265+01:00","close_reason":"Closed","dependencies":[{"issue_id":"checkvist-api-mnh","depends_on_id":"checkvist-api-5wr","type":"blocks","created_at":"2026-01-14T12:32:46.754134799+01:00","created_by":"Oliver Jakoubek"}]} {"id":"checkvist-api-nrk","title":"Create README with quickstart","description":"Create README.md (in English) with:\n- Project description\n- Installation: go get code.beautifulmachines.dev/jakoubek/checkvist-api\n- Quick start example (init client, list checklists, create task)\n- API overview (Checklists, Tasks, Notes, Filters)\n- Builder pattern examples\n- Error handling examples\n- Configuration options\n- Link to GoDoc\n- License (MIT)","status":"closed","priority":0,"issue_type":"task","owner":"mail@oliverjakoubek.de","created_at":"2026-01-14T12:31:38.724338606+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-14T13:48:30.163762004+01:00","closed_at":"2026-01-14T13:48:30.163762004+01:00","close_reason":"Closed","dependencies":[{"issue_id":"checkvist-api-nrk","depends_on_id":"checkvist-api-c2k","type":"blocks","created_at":"2026-01-14T12:33:15.785698203+01:00","created_by":"Oliver Jakoubek"},{"issue_id":"checkvist-api-nrk","depends_on_id":"checkvist-api-rl9","type":"blocks","created_at":"2026-01-14T12:33:16.125115134+01:00","created_by":"Oliver Jakoubek"}]} {"id":"checkvist-api-otm","title":"Fix DueDate parsing: API returns slashes, parser expects dashes","description":"## Problem\n\nWhen fetching tasks via `TaskService.List()`, `DueDate` is always `nil` even for tasks that have a due date set.\n\n## Root Cause\n\nThe Checkvist API returns due dates in slash format (`2026/01/15`), but `parseDueDate()` in `tasks.go:250` only parses the ISO format with dashes:\n\n```go\n// Current implementation - only supports dashes\nif t, err := time.Parse(\"2006-01-02\", task.DueDateRaw); err == nil {\n task.DueDate = &t\n}\n```\n\nAPI response format: `\"due\": \"2026/01/15\"` (slashes)\nExpected by parser: `\"2026-01-15\"` (dashes)\n\n## Solution\n\nExtend `parseDueDate()` to also parse the slash format:\n\n```go\nfunc parseDueDate(task *Task) {\n if task.DueDateRaw == \"\" {\n return\n }\n \n // Try multiple formats\n formats := []string{\n \"2006-01-02\", // ISO format (dashes)\n \"2006/01/02\", // Checkvist API format (slashes)\n }\n \n for _, format := range formats {\n if t, err := time.Parse(format, task.DueDateRaw); err == nil {\n task.DueDate = &t\n return\n }\n }\n}\n```\n\n## Affected Code\n\n- `tasks.go:244-253` - `parseDueDate()` function\n\n## Acceptance Criteria\n\n- [ ] Tasks with due dates have `DueDate` correctly parsed\n- [ ] Both slash format (`2026/01/15`) and dash format (`2026-01-15`) work\n- [ ] Unit test added for slash format parsing","status":"closed","priority":2,"issue_type":"bug","owner":"mail@oliverjakoubek.de","created_at":"2026-01-15T09:05:02.138578452+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-15T09:29:14.390484526+01:00","closed_at":"2026-01-15T09:29:14.390484526+01:00","close_reason":"Closed"} +{"id":"checkvist-api-rcj","title":"Fix Task.tasks field: expect []int not []*Task","description":"## Problem\n\nWhen decoding API responses containing the `tasks` field, JSON unmarshaling fails with:\n```\njson: cannot unmarshal number into Go struct field Task.tasks of type checkvist.Task\n```\n\n## Root Cause\n\nIn `models.go:144`, the `Children` field is incorrectly typed:\n```go\nChildren []*Task `json:\"tasks,omitempty\"`\n```\n\nAccording to the Checkvist API documentation, the `tasks` field is:\n> \"tasks [JSON] Javascript array of children task IDs\"\n\nThe API returns an **array of integers** (child task IDs), not an array of full Task objects.\n\n## Solution\n\nChange the field type from `[]*Task` to `[]int` and rename appropriately:\n```go\nChildIDs []int `json:\"tasks,omitempty\"` // IDs of child tasks\n```\n\nThis is a breaking change for users who relied on `Children []*Task`, but the current implementation was incorrect and would fail on real API responses anyway.\n\n## Acceptance Criteria\n\n- [ ] `Task.ChildIDs` correctly unmarshals as `[]int`\n- [ ] Update test fixtures to include `tasks` field with sample child IDs\n- [ ] Tests pass with real API response structure\n- [ ] Update CHANGELOG.md noting the breaking change","status":"in_progress","priority":2,"issue_type":"bug","owner":"mail@oliverjakoubek.de","created_at":"2026-01-18T14:32:44.748293162+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-18T14:34:44.774842767+01:00"} {"id":"checkvist-api-rl9","title":"Implement Task operations","description":"Create tasks.go with TaskService:\n- client.Tasks(checklistID) returns TaskService\n- List(ctx) ([]Task, error) - GET /checklists/{id}/tasks.json\n- Get(ctx, taskID) (*Task, error) - GET /checklists/{id}/tasks/{task_id}.json (includes parent hierarchy)\n- Create(ctx, builder *TaskBuilder) (*Task, error) - POST /checklists/{id}/tasks.json\n- Update(ctx, taskID, opts) (*Task, error) - PUT /checklists/{id}/tasks/{task_id}.json\n- Delete(ctx, taskID) error - DELETE /checklists/{id}/tasks/{task_id}.json\n- Close(ctx, taskID) (*Task, error) - POST /checklists/{id}/tasks/{task_id}/close.json\n- Reopen(ctx, taskID) (*Task, error) - POST /checklists/{id}/tasks/{task_id}/reopen.json\n- Invalidate(ctx, taskID) (*Task, error) - POST /checklists/{id}/tasks/{task_id}/invalidate.json\nParse DueDate from DueDateRaw when retrieving tasks.","status":"closed","priority":0,"issue_type":"feature","owner":"mail@oliverjakoubek.de","created_at":"2026-01-14T12:30:53.90629838+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-14T13:39:29.443727155+01:00","closed_at":"2026-01-14T13:39:29.443727155+01:00","close_reason":"Closed","dependencies":[{"issue_id":"checkvist-api-rl9","depends_on_id":"checkvist-api-8u6","type":"blocks","created_at":"2026-01-14T12:32:55.247292478+01:00","created_by":"Oliver Jakoubek"},{"issue_id":"checkvist-api-rl9","depends_on_id":"checkvist-api-lpn","type":"blocks","created_at":"2026-01-14T12:32:55.536931433+01:00","created_by":"Oliver Jakoubek"}]} {"id":"checkvist-api-tjk","title":"Implement TaskBuilder fluent interface","description":"Enhance task creation with builder pattern:\n- NewTask(content string) *TaskBuilder\n- WithTags(tags ...string) *TaskBuilder\n- WithDueDate(due DueDate) *TaskBuilder\n- WithPriority(p int) *TaskBuilder\n- WithParent(parentID int64) *TaskBuilder\n- WithPosition(pos int) *TaskBuilder\n- Build() returns parameters for API call\nTaskBuilder should be chainable and return itself for fluent usage:\n checkvist.NewTask(\"Content\").WithTags(\"tag1\").WithDueDate(checkvist.DueTomorrow).WithPriority(1)","status":"closed","priority":1,"issue_type":"feature","owner":"mail@oliverjakoubek.de","created_at":"2026-01-14T12:30:55.929907579+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-14T14:30:42.405125498+01:00","closed_at":"2026-01-14T14:30:42.405125498+01:00","close_reason":"TaskBuilder war bereits vollständig implementiert und getestet","dependencies":[{"issue_id":"checkvist-api-tjk","depends_on_id":"checkvist-api-rl9","type":"blocks","created_at":"2026-01-14T12:33:02.20339206+01:00","created_by":"Oliver Jakoubek"}]} {"id":"checkvist-api-v2f","title":"Write unit tests for Tasks","description":"Create tasks_test.go with tests:\n- TestTasks_List\n- TestTasks_Get\n- TestTasks_Get_WithParentHierarchy\n- TestTasks_Create\n- TestTasks_Create_WithBuilder\n- TestTasks_Update\n- TestTasks_Delete\n- TestTasks_Close\n- TestTasks_Reopen\n- TestTasks_Invalidate\n- TestDueDate_Parsing\nUse table-driven tests. Create testdata/tasks/ fixtures.","status":"closed","priority":0,"issue_type":"task","owner":"mail@oliverjakoubek.de","created_at":"2026-01-14T12:31:37.538754679+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-14T13:46:01.50434559+01:00","closed_at":"2026-01-14T13:46:01.50434559+01:00","close_reason":"Closed","dependencies":[{"issue_id":"checkvist-api-v2f","depends_on_id":"checkvist-api-rl9","type":"blocks","created_at":"2026-01-14T12:33:13.81085058+01:00","created_by":"Oliver Jakoubek"}]}