api

package
v0.20.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 31, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Index

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 Cors

func Cors(next http.Handler) http.Handler

Cors wraps a handler with CORS headers for local development.

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 Logging

func Logging(next http.Handler) http.Handler

Logging wraps a handler with request logging.

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

func (h *Handler) RegisterRoutes(mux *http.ServeMux)

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

func (h *Handler) SetOnProjectSwitch(fn func(newKanRoot string))

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

func (h *Handler) StaticHandler() http.Handler

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

func NewServer(handler *Handler, port int, kanRoot string) *Server

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.

func (*Server) Addr

func (s *Server) Addr() string

Addr returns the address the server is listening on.

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

Shutdown gracefully stops the server.

func (*Server) Start

func (s *Server) Start() error

Start begins listening for HTTP requests. Blocks until shutdown.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL