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) RestoreCard(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 RestoreCardRequest
- 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"`
History []model.HistoryEntry `json:"history,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. 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) RestoreCard ¶ added in v0.21.0
func (h *Handler) RestoreCard(w http.ResponseWriter, r *http.Request)
RestoreCard re-creates a previously deleted card from a full snapshot.
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/).
Auto-migrates board/card schemas and ensures the project config is initialized before creating stores, since stores enforce strict schema validation on reads.
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 RestoreCardRequest ¶ added in v0.21.0
type RestoreCardRequest struct {
Card json.RawMessage `json:"card"` // Full card JSON (preserves ID, alias, timestamps, etc.)
Column string `json:"column"` // Column to restore into
Position int `json:"position"` // Position within the column
}
RestoreCardRequest is the JSON body for restoring a deleted card.
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.