Documentation
¶
Index ¶
- func BadRequest(w http.ResponseWriter, message string)
- func Cors(next http.Handler) http.Handler
- func Error(w http.ResponseWriter, err error)
- func GenerateFaviconSVG(cfg *model.FaviconConfig) string
- func JSON(w http.ResponseWriter, status int, data any)
- func Logging(next http.Handler) http.Handler
- func NotFound(w http.ResponseWriter, resourceType, identifier string)
- type AllBoardsResponse
- type BoardEntry
- type CardResponse
- type CommentResponse
- type CreateCardRequest
- type CreateCardResponse
- type CreateColumnRequest
- type CreateCommentRequest
- type DeleteBoardResponse
- type DeleteColumnResponse
- type EditCommentRequest
- type FileChange
- type FileChangeKind
- type FileChangeType
- type FileWatcher
- type FileWatcherSubscriber
- type Handler
- func (h *Handler) CreateCard(w http.ResponseWriter, r *http.Request)
- func (h *Handler) CreateColumn(w http.ResponseWriter, r *http.Request)
- func (h *Handler) CreateComment(w http.ResponseWriter, r *http.Request)
- func (h *Handler) DeleteBoard(w http.ResponseWriter, r *http.Request)
- func (h *Handler) DeleteCard(w http.ResponseWriter, r *http.Request)
- func (h *Handler) DeleteColumn(w http.ResponseWriter, r *http.Request)
- func (h *Handler) DeleteComment(w http.ResponseWriter, r *http.Request)
- func (h *Handler) EditComment(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetBoard(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetCard(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetFavicon(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GetProject(w http.ResponseWriter, r *http.Request)
- func (h *Handler) ListAllBoards(w http.ResponseWriter, r *http.Request)
- func (h *Handler) ListBoards(w http.ResponseWriter, r *http.Request)
- func (h *Handler) ListCards(w http.ResponseWriter, r *http.Request)
- func (h *Handler) MoveCard(w http.ResponseWriter, r *http.Request)
- func (h *Handler) RegisterRoutes(mux *http.ServeMux)
- func (h *Handler) ReorderColumns(w http.ResponseWriter, r *http.Request)
- func (h *Handler) SetOnProjectSwitch(fn func(newKanRoot string))
- func (h *Handler) StaticHandler() http.Handler
- func (h *Handler) SwitchProject(w http.ResponseWriter, r *http.Request)
- func (h *Handler) UpdateCard(w http.ResponseWriter, r *http.Request)
- func (h *Handler) UpdateColumn(w http.ResponseWriter, r *http.Request)
- type HookInfo
- type MissingWantedFieldInfo
- type MissingWantedOptionInfo
- type MoveCardRequest
- type ProjectContext
- type ProjectResponse
- type ReorderColumnsRequest
- type Server
- type SkippedProject
- type SwitchProjectRequest
- type SwitchProjectResponse
- type UpdateCardRequest
- type UpdateColumnRequest
- type WebSocketClient
- type WebSocketHub
- type WebSocketMessage
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BadRequest ¶
func BadRequest(w http.ResponseWriter, message string)
BadRequest writes a 400 error with the given message.
func Error ¶
func Error(w http.ResponseWriter, err error)
Error writes an error response, mapping domain errors to HTTP status codes.
func GenerateFaviconSVG ¶ added in v0.8.0
func GenerateFaviconSVG(cfg *model.FaviconConfig) string
GenerateFaviconSVG creates an SVG favicon from the favicon config.
func JSON ¶
func JSON(w http.ResponseWriter, status int, data any)
JSON writes a JSON response with the given status code.
func NotFound ¶ added in v0.2.0
func NotFound(w http.ResponseWriter, resourceType, identifier string)
NotFound writes a 404 error for a missing resource.
Types ¶
type AllBoardsResponse ¶ added in v0.9.0
type AllBoardsResponse struct {
Boards []BoardEntry `json:"boards"`
CurrentProjectPath string `json:"current_project_path"`
Skipped []SkippedProject `json:"skipped,omitempty"`
}
AllBoardsResponse is the JSON response for listing all boards across projects.
type BoardEntry ¶ added in v0.9.0
type BoardEntry struct {
ProjectName string `json:"project_name"`
ProjectPath string `json:"project_path"`
BoardName string `json:"board_name"`
}
BoardEntry represents a single board across all registered projects.
type CardResponse ¶ added in v0.3.0
type CardResponse struct {
ID string `json:"id"`
Alias string `json:"alias"`
AliasExplicit bool `json:"alias_explicit"`
Title string `json:"title"`
Description string `json:"description,omitempty"`
Column string `json:"column"`
Parent string `json:"parent,omitempty"`
Creator string `json:"creator"`
CreatedAtMillis int64 `json:"created_at_millis"`
UpdatedAtMillis int64 `json:"updated_at_millis"`
Comments []model.Comment `json:"comments,omitempty"`
CustomFields map[string]any `json:"-"` // Flattened into top level by MarshalJSON
MissingWantedFields []MissingWantedFieldInfo `json:"missing_wanted_fields,omitempty"`
}
CardResponse wraps a Card for JSON API responses, including the Column field which is computed (from board config) and not persisted to card files. Custom fields are flattened into the top level to match the card JSON storage format.
func (CardResponse) MarshalJSON ¶ added in v0.3.0
func (c CardResponse) MarshalJSON() ([]byte, error)
MarshalJSON flattens custom fields into the top level of the JSON output.
type CommentResponse ¶ added in v0.7.1
type CommentResponse struct {
ID string `json:"id"`
Body string `json:"body"`
Author string `json:"author"`
CreatedAtMillis int64 `json:"created_at_millis"`
UpdatedAtMillis int64 `json:"updated_at_millis,omitempty"`
}
CommentResponse is the JSON response for a comment.
type CreateCardRequest ¶
type CreateCardRequest struct {
Title string `json:"title"`
Description string `json:"description,omitempty"`
Column string `json:"column,omitempty"`
Parent string `json:"parent,omitempty"`
CustomFields map[string]any `json:"custom_fields,omitempty"`
}
CreateCardRequest is the JSON body for creating a card.
type CreateCardResponse ¶ added in v0.10.0
type CreateCardResponse struct {
Card CardResponse `json:"card"`
HookResults []HookInfo `json:"hook_results,omitempty"`
MissingWantedFields []MissingWantedFieldInfo `json:"missing_wanted_fields,omitempty"`
}
CreateCardResponse is the JSON response for creating a card.
type CreateColumnRequest ¶ added in v0.5.0
type CreateColumnRequest struct {
Name string `json:"name"`
Color string `json:"color,omitempty"`
Description string `json:"description,omitempty"`
Limit *int `json:"limit,omitempty"` // Column limit (0 = no limit)
Position *int `json:"position,omitempty"` // Optional: insert position (-1 or omit for end)
}
CreateColumnRequest is the JSON body for creating a column.
type CreateCommentRequest ¶ added in v0.7.1
type CreateCommentRequest struct {
Body string `json:"body"`
}
CreateCommentRequest is the JSON body for creating a comment.
type DeleteBoardResponse ¶ added in v0.16.0
type DeleteBoardResponse struct {
DeletedCards int `json:"deleted_cards"`
}
DeleteBoardResponse is returned when a board is deleted.
type DeleteColumnResponse ¶ added in v0.5.0
type DeleteColumnResponse struct {
DeletedCards int `json:"deleted_cards"`
}
DeleteColumnResponse is returned when a column is deleted.
type EditCommentRequest ¶ added in v0.7.1
type EditCommentRequest struct {
Body string `json:"body"`
}
EditCommentRequest is the JSON body for editing a comment.
type FileChange ¶ added in v0.10.0
type FileChange struct {
Type FileChangeType `json:"type"`
Kind FileChangeKind `json:"kind"`
BoardName string `json:"board_name,omitempty"` // For card/board changes
CardID string `json:"card_id,omitempty"` // For card changes
Path string `json:"path"` // Relative path from .kan/
}
FileChange represents a file system change notification.
type FileChangeKind ¶ added in v0.10.0
type FileChangeKind string
FileChangeKind indicates what kind of file changed.
const ( FileChangeKindCard FileChangeKind = "card" FileChangeKindBoard FileChangeKind = "board" FileChangeKindProject FileChangeKind = "project" FileChangeKindUnknown FileChangeKind = "unknown" )
type FileChangeType ¶ added in v0.10.0
type FileChangeType string
FileChangeType indicates what type of change occurred.
const ( FileChangeCreated FileChangeType = "created" FileChangeModified FileChangeType = "modified" FileChangeDeleted FileChangeType = "deleted" )
type FileWatcher ¶ added in v0.10.0
type FileWatcher struct {
// contains filtered or unexported fields
}
FileWatcher watches the .kan directory for changes and notifies subscribers.
func NewFileWatcher ¶ added in v0.10.0
func NewFileWatcher(kanRoot string) (*FileWatcher, error)
NewFileWatcher creates a new file watcher for the given kan data directory. kanRoot should be the resolved .kan/ path (e.g., from Paths.KanRoot()).
func (*FileWatcher) Start ¶ added in v0.10.0
func (fw *FileWatcher) Start() error
Start begins watching the .kan directory for changes.
func (*FileWatcher) Stop ¶ added in v0.10.0
func (fw *FileWatcher) Stop() error
Stop stops watching for changes.
func (*FileWatcher) Subscribe ¶ added in v0.10.0
func (fw *FileWatcher) Subscribe(sub FileWatcherSubscriber)
Subscribe adds a subscriber to receive file change notifications.
func (*FileWatcher) Unsubscribe ¶ added in v0.10.0
func (fw *FileWatcher) Unsubscribe(sub FileWatcherSubscriber)
Unsubscribe removes a subscriber.
type FileWatcherSubscriber ¶ added in v0.10.0
type FileWatcherSubscriber interface {
OnFileChange(change FileChange)
}
FileWatcherSubscriber receives file change notifications.
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler contains all HTTP handlers for the API.
Design: single-user, single-session. The Handler holds one active ProjectContext that is shared by all requests. SwitchProject swaps it atomically. This is intentional — `kan serve` is a local development tool, not a multi-tenant server. All connected clients (browser tabs) see the same project.
Lifecycle: globalStore is read fresh on each ListAllBoards/SwitchProject call (never cached), so external changes to ~/.config/kan/config.toml are picked up immediately.
func NewHandler ¶
func NewHandler(globalStore store.GlobalStore, ctx *ProjectContext) *Handler
NewHandler creates a new handler with the given dependencies.
func (*Handler) CreateCard ¶
func (h *Handler) CreateCard(w http.ResponseWriter, r *http.Request)
CreateCard creates a new card.
func (*Handler) CreateColumn ¶ added in v0.5.0
func (h *Handler) CreateColumn(w http.ResponseWriter, r *http.Request)
CreateColumn creates a new column on a board.
func (*Handler) CreateComment ¶ added in v0.7.1
func (h *Handler) CreateComment(w http.ResponseWriter, r *http.Request)
CreateComment creates a new comment on a card.
func (*Handler) DeleteBoard ¶ added in v0.16.0
func (h *Handler) DeleteBoard(w http.ResponseWriter, r *http.Request)
DeleteBoard deletes a board and all its cards.
func (*Handler) DeleteCard ¶
func (h *Handler) DeleteCard(w http.ResponseWriter, r *http.Request)
DeleteCard deletes a card.
func (*Handler) DeleteColumn ¶ added in v0.5.0
func (h *Handler) DeleteColumn(w http.ResponseWriter, r *http.Request)
DeleteColumn deletes a column and all its cards.
func (*Handler) DeleteComment ¶ added in v0.7.1
func (h *Handler) DeleteComment(w http.ResponseWriter, r *http.Request)
DeleteComment removes a comment from a card.
func (*Handler) EditComment ¶ added in v0.7.1
func (h *Handler) EditComment(w http.ResponseWriter, r *http.Request)
EditComment updates an existing comment's body.
func (*Handler) GetBoard ¶
func (h *Handler) GetBoard(w http.ResponseWriter, r *http.Request)
GetBoard returns a board's configuration.
func (*Handler) GetCard ¶
func (h *Handler) GetCard(w http.ResponseWriter, r *http.Request)
GetCard returns a single card by ID.
func (*Handler) GetFavicon ¶ added in v0.8.0
func (h *Handler) GetFavicon(w http.ResponseWriter, r *http.Request)
GetFavicon serves the favicon, checking for a custom file first.
func (*Handler) GetProject ¶ added in v0.8.0
func (h *Handler) GetProject(w http.ResponseWriter, r *http.Request)
GetProject returns the project metadata.
func (*Handler) ListAllBoards ¶ added in v0.9.0
func (h *Handler) ListAllBoards(w http.ResponseWriter, r *http.Request)
ListAllBoards returns all boards across all registered projects.
func (*Handler) ListBoards ¶
func (h *Handler) ListBoards(w http.ResponseWriter, r *http.Request)
ListBoards returns all board names.
func (*Handler) ListCards ¶
func (h *Handler) ListCards(w http.ResponseWriter, r *http.Request)
ListCards returns all cards for a board, optionally filtered by column.
func (*Handler) MoveCard ¶
func (h *Handler) MoveCard(w http.ResponseWriter, r *http.Request)
MoveCard moves a card to a different column.
func (*Handler) RegisterRoutes ¶
RegisterRoutes sets up all API routes on the given mux.
func (*Handler) ReorderColumns ¶ added in v0.5.0
func (h *Handler) ReorderColumns(w http.ResponseWriter, r *http.Request)
ReorderColumns reorders all columns according to the provided order.
func (*Handler) SetOnProjectSwitch ¶ added in v0.10.0
SetOnProjectSwitch sets a callback that's called when the active project changes. Used by Server to update the file watcher when projects are switched.
func (*Handler) StaticHandler ¶
StaticHandler returns a handler that serves the embedded frontend files.
func (*Handler) SwitchProject ¶ added in v0.9.0
func (h *Handler) SwitchProject(w http.ResponseWriter, r *http.Request)
SwitchProject switches the handler's active project context.
func (*Handler) UpdateCard ¶
func (h *Handler) UpdateCard(w http.ResponseWriter, r *http.Request)
UpdateCard updates an existing card.
func (*Handler) UpdateColumn ¶ added in v0.5.0
func (h *Handler) UpdateColumn(w http.ResponseWriter, r *http.Request)
UpdateColumn updates a column's properties (rename, color).
type HookInfo ¶ added in v0.10.0
type HookInfo struct {
Name string `json:"name"`
Success bool `json:"success"`
Output string `json:"output,omitempty"`
Error string `json:"error,omitempty"`
}
HookInfo contains information about a hook execution for API response.
type MissingWantedFieldInfo ¶ added in v0.11.0
type MissingWantedFieldInfo struct {
Name string `json:"name"`
Type string `json:"type"`
Description string `json:"description,omitempty"`
Options []MissingWantedOptionInfo `json:"options,omitempty"`
}
MissingWantedFieldInfo describes a wanted field that is missing from a card.
type MissingWantedOptionInfo ¶ added in v0.14.0
type MissingWantedOptionInfo struct {
Value string `json:"value"`
Description string `json:"description,omitempty"`
}
MissingWantedOptionInfo describes a valid option for a missing wanted field.
type MoveCardRequest ¶
type MoveCardRequest struct {
Column string `json:"column"`
Position *int `json:"position,omitempty"` // Optional: position in target column (-1 or omit for end)
}
MoveCardRequest is the JSON body for moving a card.
type ProjectContext ¶ added in v0.9.0
type ProjectContext struct {
Paths *config.Paths
BoardStore store.BoardStore
CardStore store.CardStore
ProjectStore store.ProjectStore
CardService *service.CardService
BoardService *service.BoardService
Creator string
ProjectRoot string
}
ProjectContext bundles all per-project dependencies needed by the HTTP handlers. The Handler holds one of these and can swap it out on project switch.
func BuildProjectContext ¶ added in v0.9.0
func BuildProjectContext(projectRoot, dataLocation, creator string) (*ProjectContext, error)
BuildProjectContext creates a fully-wired ProjectContext from a project root path and optional data location override (empty string means default .kan/).
This is a pure construction function — it validates the path exists and wires up stores/services but does not perform any disk writes. Callers are responsible for any initialization (e.g., EnsureInitialized) before or after calling this.
type ProjectResponse ¶ added in v0.8.0
type ProjectResponse struct {
Name string `json:"name"`
Favicon model.FaviconConfig `json:"favicon"`
ProjectPath string `json:"project_path"`
}
ProjectResponse is the JSON response for project metadata.
type ReorderColumnsRequest ¶ added in v0.5.0
type ReorderColumnsRequest struct {
Columns []string `json:"columns"`
}
ReorderColumnsRequest is the JSON body for reordering columns.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server wraps the HTTP server for the web frontend.
func NewServer ¶
NewServer creates a new server with the given handler, port, and kan root. kanRoot is the resolved .kan/ directory path. If empty, file watching is disabled.
type SkippedProject ¶ added in v0.9.0
type SkippedProject struct {
Name string `json:"name"`
Path string `json:"path"`
Reason string `json:"reason"`
}
SkippedProject describes a registered project that couldn't be listed.
type SwitchProjectRequest ¶ added in v0.9.0
type SwitchProjectRequest struct {
ProjectPath string `json:"project_path"`
}
SwitchProjectRequest is the JSON body for switching projects.
type SwitchProjectResponse ¶ added in v0.9.0
type SwitchProjectResponse struct {
ProjectName string `json:"project_name"`
Boards []string `json:"boards"`
}
SwitchProjectResponse is the JSON response after switching projects.
type UpdateCardRequest ¶
type UpdateCardRequest struct {
Title *string `json:"title,omitempty"`
Description *string `json:"description,omitempty"`
Column *string `json:"column,omitempty"`
CustomFields map[string]any `json:"custom_fields,omitempty"`
}
UpdateCardRequest is the JSON body for updating a card.
type UpdateColumnRequest ¶ added in v0.5.0
type UpdateColumnRequest struct {
Name *string `json:"name,omitempty"` // New name (rename)
Color *string `json:"color,omitempty"` // New color
Description *string `json:"description,omitempty"` // New description
Limit *int `json:"limit,omitempty"` // Column limit (0 = clear)
}
UpdateColumnRequest is the JSON body for updating a column.
type WebSocketClient ¶ added in v0.10.0
type WebSocketClient struct {
// contains filtered or unexported fields
}
WebSocketClient represents a connected WebSocket client.
type WebSocketHub ¶ added in v0.10.0
type WebSocketHub struct {
// contains filtered or unexported fields
}
WebSocketHub manages WebSocket connections and broadcasts file changes.
func NewWebSocketHub ¶ added in v0.10.0
func NewWebSocketHub() *WebSocketHub
NewWebSocketHub creates a new WebSocket hub.
func (*WebSocketHub) ClientCount ¶ added in v0.10.0
func (h *WebSocketHub) ClientCount() int
ClientCount returns the number of connected clients.
func (*WebSocketHub) OnFileChange ¶ added in v0.10.0
func (h *WebSocketHub) OnFileChange(change FileChange)
OnFileChange implements FileWatcherSubscriber.
func (*WebSocketHub) ServeWS ¶ added in v0.10.0
func (h *WebSocketHub) ServeWS(w http.ResponseWriter, r *http.Request)
ServeWS handles WebSocket connection requests.
type WebSocketMessage ¶ added in v0.10.0
type WebSocketMessage struct {
Type string `json:"type"`
Data interface{} `json:"data"`
}
WebSocketMessage is the JSON message sent to clients.