Commit graph

49 commits

Author SHA1 Message Date
8063341150 feat: add GetTaskByReference function v1.4.0
Look up tasks by external reference within a project, following
the same pattern as GetTask with ErrTaskNotFound on missing results.
2026-02-02 11:25:57 +01:00
c4caf4b876 Added badges to README 2026-01-30 12:30:52 +01:00
4e856cd206 feat: add category write operations (create, update, remove, get-by-name) v1.3.0
Add CreateCategory, UpdateCategory, RemoveCategory, and GetCategoryByName
methods to the client, with BoardScope wrappers for project-scoped operations.
Includes comprehensive tests for all new methods.

Closes kanboard-4n3
2026-01-29 09:20:13 +01:00
56da2e0fdc chore: update beads export state v1.2.0 2026-01-28 12:09:27 +01:00
12c1660d94 chore: update beads export state 2026-01-28 12:09:21 +01:00
a381c0dc51 chore: update beads export state 2026-01-28 12:09:14 +01:00
bc478b44e0 feat: add DateMoved timestamp field to Task struct
Adds the date_moved field to capture when a task was last moved
between columns or swimlanes in Kanboard.
2026-01-28 12:09:06 +01:00
5fd38721b5 chore: update beads export state v1.1.0 2026-01-27 17:01:48 +01:00
280fff21a3 feat: add GetTaskFile and RemoveAllTaskFiles methods
Complete the Task File API implementation with:
- GetTaskFile: retrieve single file metadata by ID
- RemoveAllTaskFiles: remove all files attached to a task
- Add Username/UserName fields to TaskFile struct
- Add TaskScope convenience methods: GetFile, RemoveFile,
  DownloadFile, RemoveAllFiles
- Comprehensive tests for all new methods

Closes: kanboard-amh
2026-01-27 17:01:21 +01:00
c15d52633f feat: add GetColorList for available task colors v1.0.1
Adds GetColorList() to query the available task colors from the
Kanboard instance. Returns a map of color_id to display name
(e.g., "yellow" -> "Yellow").

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 12:13:35 +01:00
449cd2626c feat: add OperationFailedError with actionable hints
The Kanboard API returns only true/false for many operations without
explaining why they failed. Added OperationFailedError type that
includes operation details and hints about possible causes.

Updated MoveTaskPosition and MoveTaskToProject to use this new error
type, providing users with actionable debugging information instead
of generic "failed to move task" messages.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 11:12:25 +01:00
508c3ac6d2 fix: remove Basic prefix from custom auth headers
Custom headers like X-API-Auth expect raw base64 credentials without
the "Basic " prefix. The standard Authorization header continues to
use the proper Basic auth format via SetBasicAuth().

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 11:01:41 +01:00
96601980c3 fix: handle URLs already ending in /jsonrpc.php
NewClient() now detects when the provided URL already ends with
/jsonrpc.php and avoids appending it again. This prevents double-path
issues like /jsonrpc.php/jsonrpc.php.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 10:27:34 +01:00
f8daa20ddd feat: use random request IDs instead of sequential counter v1.0.0
Replace the atomic counter-based request ID generation with random
int64 values using math/rand/v2. This improves unpredictability and
avoids potential ID collisions across client instances or restarts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 10:21:31 +01:00
735b288504 fix: add HTML response body validation before JSON parsing
Adds a backup check that validates the response body starts with '{'
before attempting JSON unmarshal. This catches cases where:
- Server returns HTML with incorrect Content-Type header
- Reverse proxy/load balancer modifies headers but not body
- PHP error pages with HTTP 200 status

Includes a preview of the HTML content (up to 200 chars) for debugging.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 20:35:21 +01:00
770e05ef7c Update beads export state 2026-01-23 18:27:14 +01:00
192053952f Add WithAuthHeader for custom authentication header name
Support configuring a custom HTTP header name for authentication
(e.g., X-API-Auth instead of Authorization) for Kanboard servers
with specific proxy configurations that use alternative auth headers.

- Add headerName field to apiTokenAuth and basicAuth structs
- Add WithAuthHeader() fluent method to Client
- Auth methods pass custom header name when creating auth structs
- Add tests for custom header with API token, basic auth, and custom user

Closes kanboard-9wa

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 18:26:55 +01:00
10e2ecf47e Add optional API user support for token authentication
- Add user field to apiTokenAuth struct
- Add WithAPITokenUser(token, user) method for custom username
- Default to "jsonrpc" when no user specified (backward compatible)
- Add tests for custom user and empty user scenarios

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 17:55:31 +01:00
ef7bd74e4a Added debug output to jsonrpc.go 2026-01-23 11:42:11 +01:00
a34a40cb12 Add IntOrFalse type to handle polymorphic API responses
Kanboard API returns int (ID) on success and false (bool) on failure
for create operations. Add IntOrFalse type that handles both cases
and update CreateTask, CreateComment, CreateTag, CreateTaskFile, and
CreateTaskLink to use it.
2026-01-15 20:23:53 +01:00
59252a3f63 Fix StringBool to handle numeric JSON values
Some Kanboard versions return is_active and similar fields as
numeric 0/1 instead of string "0"/"1". Update UnmarshalJSON to
try string, then number, then bool parsing.
2026-01-15 20:11:58 +01:00
8aa611d3d7 Add MIT license 2026-01-15 19:25:27 +01:00
a2913c6b8d Add example programs
- examples/basic: Client setup, projects, tasks, and create operations
- examples/fluent: Fluent API with TaskParams, TaskUpdateParams, tags
- examples/search: Project-specific and global search functionality
2026-01-15 19:24:58 +01:00
ff06643bc8 Add package-level GoDoc documentation
Creates doc.go with comprehensive package documentation including
quick start, authentication, fluent API usage, task creation,
error handling, thread safety, and tag operation warnings.
2026-01-15 19:23:32 +01:00
408fb60b54 Add comprehensive README.md documentation
Documents installation, quick start, authentication methods,
fluent and direct API usage, task operations, error handling,
thread safety, and configuration options.
2026-01-15 19:20:57 +01:00
b325e7b3fd Add Mage build system
Set up magefiles/ directory with targets for test, coverage,
lint, and build commands. Uses github.com/magefile/mage v1.15.0.
2026-01-15 19:19:58 +01:00
610998283b Implement File API methods
- GetAllTaskFiles: retrieve all files attached to a task
- CreateTaskFile: upload file with base64 encoding
- DownloadTaskFile: download file with base64 decoding
- RemoveTaskFile: delete a task file
- TaskScope.GetFiles and UploadFile for fluent API
- Automatic base64 encoding/decoding for file content
- Comprehensive test coverage
2026-01-15 18:45:11 +01:00
39ff0a90c8 Implement Link API methods
- GetAllTaskLinks: retrieve all links for a task
- CreateTaskLink: create link between two tasks
- RemoveTaskLink: delete a task link
- TaskScope.GetLinks and LinkTo for fluent API
- Link types include "blocks", "is blocked by", etc.
- Comprehensive test coverage
2026-01-15 18:43:35 +01:00
4907a7caad Implement MoveToNextColumn and MoveToPreviousColumn
- MoveToNextColumn: moves task to next column in workflow
- MoveToPreviousColumn: moves task to previous column
- Gets columns sorted by position, finds current, moves to adjacent
- Returns ErrAlreadyInLastColumn when at workflow end
- Returns ErrAlreadyInFirstColumn when at workflow start
- Handles column gaps (non-sequential positions)
- Comprehensive test coverage for all edge cases
2026-01-15 18:42:02 +01:00
527d27b73f Implement global task search with parallel execution
- SearchTasksGlobally: cross-project search using errgroup
- Gets all projects, then searches each in parallel
- Results aggregated from all accessible projects
- Context cancellation propagates to all goroutines
- Single project failure cancels remaining searches
- Added golang.org/x/sync/errgroup dependency
- Comprehensive test coverage
2026-01-15 18:40:14 +01:00
87adebd798 Implement Comment API methods
- GetAllComments: retrieve all comments for a task
- GetComment: retrieve single comment by ID
- CreateComment: create comment and return the created comment
- UpdateComment: update comment content
- RemoveComment: delete a comment
- TaskScope.GetComments and AddComment for fluent API
- Returns ErrCommentNotFound when appropriate
- Comprehensive test coverage
2026-01-15 18:38:24 +01:00
c8eea853e5 Implement TaskScope tag methods with read-modify-write (CRITICAL)
- GetTags: retrieve task tags as map[int]string
- SetTags: replace all tags on a task
- ClearTags: remove all tags
- AddTag: read-modify-write, idempotent (no-op if tag exists)
- RemoveTag: read-modify-write, idempotent (no-op if tag doesn't exist)
- HasTag: check if task has a specific tag

WARNING: Tag operations are NOT atomic. Concurrent modifications may
cause data loss due to the read-modify-write pattern required by
Kanboard's setTaskTags API.

Comprehensive test coverage including idempotency tests.
2026-01-15 18:36:40 +01:00
371bdb8ba9 Implement TaskScope fluent builder (core methods)
- TaskScope struct for task-scoped operations
- Client.Task(taskID) returns a TaskScope
- Methods: Get, Close, Open, MoveToColumn, MoveToProject, Update
- MoveToColumn fetches task to get project_id and swimlane_id
- All methods delegate to direct Client methods
- Comprehensive test coverage
2026-01-15 18:34:38 +01:00
0c5b7fd6e9 Implement TaskUpdateParams builder
- TaskUpdateParams struct with fluent setter methods
- NewTaskUpdate() constructor
- Setters: SetTitle, SetDescription, SetColor, SetOwner, SetCategory,
  SetPriority, SetScore, SetDueDate, SetStartDate, SetReference, SetTags
- Clear methods: ClearDueDate, ClearStartDate, ClearOwner, ClearCategory
- Only set fields are included in update request (partial updates)
- Client.UpdateTaskFromParams for fluent task updates
- Comprehensive test coverage
2026-01-15 18:33:20 +01:00
28e517289a Implement TaskParams builder (Options Pattern)
- TaskParams struct with fluent setter methods
- NewTask(title) constructor
- Setters: WithDescription, InColumn, WithCategory, WithOwner, WithCreator,
  WithColor, WithPriority, WithScore, WithDueDate, WithStartDate,
  InSwimlane, WithReference, WithTags
- toCreateTaskRequest for conversion to CreateTaskRequest
- BoardScope.CreateTaskFromParams for fluent task creation
- Comprehensive test coverage for all setters and chaining
2026-01-15 18:31:13 +01:00
f04ea8866f Implement BoardScope fluent builder
- BoardScope struct for project-scoped operations
- Client.Board(projectID) returns a BoardScope
- Methods: GetColumns, GetCategories, GetTasks, SearchTasks, CreateTask
- All methods delegate to direct Client methods
- CreateTask automatically sets project ID from scope
- Comprehensive test coverage
2026-01-15 18:29:35 +01:00
c2a107054f Implement Task search and move methods
- SearchTasks: search tasks using Kanboard query syntax
- MoveTaskPosition: move task to specific position in column/swimlane
- MoveTaskToProject: move task to different project
- Comprehensive test coverage for all methods
2026-01-15 18:28:11 +01:00
d27aabe4c4 Implement Task API methods (CRUD operations)
- GetTask: retrieve single task by ID
- GetAllTasks: retrieve all tasks for a project with status filter
- CreateTask: create new task and return the created task
- UpdateTask: partial updates via pointer fields
- CloseTask/OpenTask: status operations with proper error handling
- Returns ErrTaskNotFound, ErrTaskClosed, ErrTaskOpen as appropriate
- Comprehensive test coverage for all methods and edge cases
2026-01-15 18:26:55 +01:00
fc4577e729 Implement Category API methods (GetAllCategories, GetCategory)
- GetAllCategories returns all categories for a project
- GetCategory returns a single category by ID
- Returns ErrCategoryNotFound for non-existent categories
- Added ErrCategoryNotFound to IsNotFound helper
- Comprehensive test coverage
2026-01-15 18:25:12 +01:00
2d3be3619c Implement Column API methods (GetColumns, GetColumn)
- GetColumns returns all columns for a project, sorted by position
- GetColumn returns a single column by ID
- Returns ErrColumnNotFound for non-existent columns
- Comprehensive test coverage including edge cases
2026-01-15 18:23:44 +01:00
7c8ebcc491 Implement Project API methods
Add direct client methods for project/board operations:

- GetAllProjects(ctx) - list all accessible projects
- GetProjectByID(ctx, projectID) - get project by ID
- GetProjectByName(ctx, name) - get project by name

All methods:
- Use context for cancellation support
- Return ErrProjectNotFound when project doesn't exist
- Properly wrap errors with context

Closes: kanboard-api-apl
2026-01-15 18:21:42 +01:00
88b92aa028 Implement Tag API methods (CRITICAL)
Add direct client methods for tag operations:

Must-have methods:
- GetTaskTags(ctx, taskID) - returns map[tagID]tagName
- SetTaskTags(ctx, projectID, taskID, tags) - replaces all tags

Nice-to-have methods:
- GetAllTags(ctx) - list all tags in system
- GetTagsByProject(ctx, projectID) - list project tags
- CreateTag(ctx, projectID, name, colorID) - create new tag
- UpdateTag(ctx, tagID, name, colorID) - update existing tag
- RemoveTag(ctx, tagID) - delete tag

Note: setTaskTags REPLACES all tags. Individual add/remove
requires read-modify-write pattern (to be implemented in TaskScope).

Closes: kanboard-api-16r
2026-01-15 18:20:23 +01:00
a38e62e77a Implement entity structs for Kanboard API responses
Add all entity structs matching Kanboard's JSON-RPC API format:

Entity structs:
- Project, Task, Column, Category, Comment
- TaskLink, TaskFile, Tag
- TaskStatus enum (StatusActive, StatusInactive)

Request structs:
- CreateTaskRequest with omitempty for optional fields
- UpdateTaskRequest with pointer fields for zero-value distinction

Custom JSON types for Kanboard's string-encoded values:
- StringBool - handles "0"/"1" string booleans
- StringInt - handles string-encoded integers
- StringInt64 - handles string-encoded int64 values

All structs properly handle Kanboard's quirky JSON format where
numeric fields are often returned as quoted strings.

Closes: kanboard-api-cyc
2026-01-15 18:18:47 +01:00
dbac08ac1e Implement Timestamp type for Unix timestamp JSON handling
Add custom Timestamp type that wraps time.Time for Kanboard's
Unix timestamp format:

UnmarshalJSON supports:
- Unix timestamps as integers
- Empty strings and "0" strings as zero time
- Null values as zero time
- Numeric strings (e.g., "1609459200")

MarshalJSON returns:
- 0 for zero time
- Unix timestamp for non-zero time

Includes comprehensive tests for round-trip marshaling
and struct embedding scenarios.

Closes: kanboard-api-25y
2026-01-15 18:15:33 +01:00
a56456cc00 Complete Client struct with fluent configuration
Add full client configuration with fluent builder pattern:

- WithTimeout(duration) - configurable request timeout
- WithLogger(slog.Logger) - optional debug logging
- DefaultTimeout constant (30 seconds)
- Default HTTP client with timeout on construction

All fluent methods return same client instance for chaining.
Client is thread-safe for concurrent use.

Closes: kanboard-api-uls
2026-01-15 18:14:22 +01:00
79385df87b Implement comprehensive error types and handling
Add complete error handling system for Kanboard API client:

Sentinel errors:
- Network: ErrConnectionFailed, ErrTimeout
- Auth: ErrUnauthorized, ErrForbidden
- Resources: ErrNotFound, ErrProjectNotFound, ErrTaskNotFound,
  ErrColumnNotFound, ErrCommentNotFound
- Logic: ErrAlreadyInLastColumn, ErrAlreadyInFirstColumn,
  ErrTaskClosed, ErrTaskOpen
- Validation: ErrEmptyTitle, ErrInvalidProjectID

Helper functions:
- IsNotFound() - checks all not-found error variants
- IsUnauthorized() - checks auth errors
- IsAPIError() - checks for API errors via errors.As

All errors support errors.Is/errors.As for proper error
wrapping and context preservation.

Closes: kanboard-api-s7k
2026-01-15 18:13:09 +01:00
ba942f3b52 Add authentication system tests
Add comprehensive tests for HTTP Basic Auth support:
- API token authentication (jsonrpc + token)
- Username/password authentication
- Verify no auth header when unconfigured
- Fluent configuration method chaining
- Auth overwrite behavior

The auth implementation was completed in the previous commit
as a dependency for JSON-RPC client.

Closes: kanboard-api-k33
2026-01-15 18:11:48 +01:00
a486a73ce1 Implement JSON-RPC client foundation
Add core JSON-RPC 2.0 protocol implementation for Kanboard API:

- JSONRPCRequest/Response/Error structs with proper JSON tags
- Generic call() method for sending requests and parsing responses
- Thread-safe request ID generation using atomic.Int64
- Automatic /jsonrpc.php path appending to baseURL
- Support for subdirectory installations
- HTTP Basic Auth support (API token and username/password)
- Error handling for unauthorized/forbidden responses

Includes comprehensive tests with httptest mock server.

Closes: kanboard-api-2g1
2026-01-15 18:10:35 +01:00
347fb75f11 Initial commit 2026-01-15 17:48:46 +01:00