Documentation
¶
Overview ¶
Package tool defines the public contract every tool module must satisfy. Downstream projects implement Module to register a tool with wick via wick/app.RegisterTool.
A module exposes metadata via Meta() and wires its handlers via Register(r Router). Wick owns the HTTP mux, the page renderer, and the static-asset mount — the module only declares routes through the Router and reacts to requests via *Ctx.
Index ¶
- func StaticHandler(prefix string, fsys fs.FS) http.Handler
- func ValidateModules(modules []Module) error
- type ConfigReader
- type Ctx
- func (c *Ctx) Base() string
- func (c *Ctx) BindJSON(v any) error
- func (c *Ctx) Cfg(key string) string
- func (c *Ctx) CfgBool(key string) bool
- func (c *Ctx) CfgInt(key string) int
- func (c *Ctx) CfgOf(owner, key string) string
- func (c *Ctx) ConfigReader() ConfigReader
- func (c *Ctx) Context() context.Context
- func (c *Ctx) Error(status int, msg string)
- func (c *Ctx) Form(key string) string
- func (c *Ctx) HTML(body templ.Component)
- func (c *Ctx) JSON(status int, v any)
- func (c *Ctx) Meta() Tool
- func (c *Ctx) Missing() []string
- func (c *Ctx) NotFound()
- func (c *Ctx) PathValue(key string) string
- func (c *Ctx) Query(key string) string
- func (c *Ctx) Redirect(url string, code int)
- type DefaultTag
- type HandlerFunc
- type Module
- type RegisterFunc
- type RenderFunc
- type Router
- type Tool
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func StaticHandler ¶
StaticHandler serves files from fsys under the given URL prefix. Directory listings return 404 so embedded asset trees don't leak. Wick uses this internally for Router.Static; modules never call it directly.
func ValidateModules ¶
ValidateModules is called by wick at boot. It checks that every module's Meta has the minimum required fields (Key, Name, Icon) and that no two modules share the same Key. A non-nil error means the process should refuse to start.
Path is derived by wick from Key ("/tools/{Key}") after validation; registrations must leave Tool.Path zero.
Types ¶
type ConfigReader ¶
ConfigReader is the narrow slice of the config service wick exposes to tool handlers. Scoping by owner happens in Ctx — handlers see only their own tool's values. Implementations live in internal/ configs; this interface keeps pkg/tool free of internal imports.
type Ctx ¶
type Ctx struct {
W http.ResponseWriter
R *http.Request
// contains filtered or unexported fields
}
Ctx is the per-request handle passed to every HandlerFunc. It bundles the raw http.ResponseWriter and *http.Request with wick-supplied helpers for the things a tool handler does constantly: read form values, decode JSON bodies, render HTML, write JSON, redirect.
Drop down to Ctx.W / Ctx.R when you need something a helper does not expose — the helpers are shortcuts, not a wall.
func NewCtx ¶
func NewCtx(w http.ResponseWriter, r *http.Request, render RenderFunc, meta Tool, cfg ConfigReader) *Ctx
NewCtx is used by wick when mounting handlers. Modules never call it directly — they receive a *Ctx ready to use.
func (*Ctx) Base ¶
Base returns the absolute mount path for this tool ("/tools/{Key}"). Use it for form actions, script src, and redirect targets so HTML works regardless of how many instances of the module are registered.
func (*Ctx) BindJSON ¶
BindJSON decodes the request body into v. Returns the decoder error verbatim so the caller can surface it.
func (*Ctx) Cfg ¶
Cfg returns the current value of a Spec declared by this tool. The lookup is scoped to the active instance's Key — reading another tool's config requires CfgOf. Returns "" when the key is not declared or the config service is unavailable.
func (*Ctx) CfgBool ¶
CfgBool returns c.Cfg(key) parsed as bool. "true"/"1"/"yes"/"on" (case-insensitive) count as true; anything else is false.
func (*Ctx) CfgInt ¶
CfgInt returns c.Cfg(key) parsed as int. Unparseable or empty values return 0 — handlers that need to distinguish "unset" from "zero" should mark the field Required and check c.Missing() first.
func (*Ctx) CfgOf ¶
CfgOf reads a config value from another owner (another tool or a job key). Intentionally verbose — reserved for cross-tool integrations that need a neighbor's endpoint or shared identifier. Prefer Cfg for the common case.
func (*Ctx) ConfigReader ¶ added in v0.13.4
func (c *Ctx) ConfigReader() ConfigReader
ConfigReader returns the underlying ConfigReader so callers that need to capture it for use outside the request lifecycle (e.g. background workers) can store it. Returns nil when no config service is wired.
func (*Ctx) Context ¶
Context is a shortcut for c.R.Context(); use it for cancellation- aware calls into services and repositories.
func (*Ctx) Error ¶
Error writes an error response with the given status code and message. Messages are plain text; use JSON for structured errors.
func (*Ctx) Form ¶
Form returns r.FormValue(key). Works for both url-encoded bodies and multipart forms. Empty string when the key is missing.
func (*Ctx) HTML ¶
HTML renders body inside wick's page shell and writes the full HTML response. Use for any tool page that lives under /tools/...
func (*Ctx) Meta ¶
Meta returns the tool.Tool this route was mounted under. Handlers use it to read display metadata (Name, Icon) or ExternalURL without threading anything through closures.
func (*Ctx) Missing ¶
Missing returns the names of Required Specs this tool declared that have no stored value yet. Handlers call it at the top of a request to decide whether to render the real view or a "setup required" banner. Returns nil when nothing is required or the config service is unavailable.
type DefaultTag ¶
type DefaultTag struct {
Name string
Description string
IsGroup bool
IsFilter bool
IsSystem bool
SortOrder int
}
DefaultTag is the spec used by Tool.DefaultTags to seed tags on startup.
IsSystem marks the tag as code-owned — see entity.Tag godoc for the admin-UI implications (cannot be assigned to users from the picker).
type HandlerFunc ¶
type HandlerFunc func(c *Ctx)
HandlerFunc is the tool-side handler signature. A handler receives a *Ctx that exposes request helpers (Form, Query, BindJSON) and response helpers (HTML, JSON, Redirect). Write to Ctx.W only when a helper doesn't fit — the helpers handle the render shell, content types, and status codes for you.
type Module ¶
type Module struct {
Meta Tool
Configs []entity.Config
Register RegisterFunc
}
Module is the internal, fully-resolved registration record wick keeps for every tool. It is produced by app.RegisterTool from a meta, a typed Config value (reflected into Configs at register time), and a RegisterFunc — downstream code does not construct Module directly.
type RegisterFunc ¶
type RegisterFunc func(r Router)
RegisterFunc wires a tool's routes on the Router wick passes in. It is the handler-side half of module registration — paired with a Tool meta and a typed Config struct at app.RegisterTool time.
Handlers declared inside RegisterFunc stay stateless: per-instance metadata is read via c.Meta(), runtime-editable config values via c.Cfg(...). There is no per-module struct to carry private state.
type RenderFunc ¶
RenderFunc wraps a body fragment in wick's page shell (navbar, layout, theme) and writes the full HTML response. Wick injects it into *Ctx; modules call it indirectly via Ctx.HTML. The *Ctx hand- off lets the renderer reach c.Missing() / c.Meta() without extra threading from the router.
type Router ¶
type Router interface {
GET(path string, h HandlerFunc)
POST(path string, h HandlerFunc)
PUT(path string, h HandlerFunc)
DELETE(path string, h HandlerFunc)
PATCH(path string, h HandlerFunc)
Static(prefix string, fsys fs.FS)
// HandleRaw mounts a raw http.Handler at a subtree prefix relative
// to the tool's /tools/{Key} base. The prefix must end with "/".
// Use sparingly — only when the handler owns its own sub-routing
// (e.g. a reverse-proxy that serves many paths under one mount).
// fn receives the ConfigReader so callers can gate on runtime config.
HandleRaw(prefix string, fn func(cfg ConfigReader) http.Handler)
Meta() Tool
}
Router is the surface wick exposes to a module's Register method. Modules declare their HTTP routes through these Echo/Gin-style verb methods; wick owns the underlying mux, validates that no two modules claim the same `METHOD PATH`, and mounts each handler with the page renderer already injected into *Ctx.
Paths passed to GET/POST/... are relative to the meta's /tools/{Key} base; wick prefixes them at mount time. Static mounts a read-only fs.FS at prefix — typically "/static/" for the module's embed.FS of js/css assets. Directory listings are blocked.
Meta returns the tool.Tool currently being registered. Register is invoked once per Meta entry; use this when a handler needs the base URL (form actions, script src) or the tool's display metadata.
type Tool ¶
type Tool struct {
// Key is the path segment that identifies this instance. Must be
// unique across every Tool returned by every module — wick derives
// the mount path from it as "/tools/{Key}". Lowercase slug, no
// slashes. Multi-instance modules emit one Tool per Key.
Key string `json:"key"`
Name string `json:"name"`
Description string `json:"description"`
// Icon is a short label (e.g. "Aa", "{}") shown inside the icon box.
Icon string `json:"icon"`
// Path is the fully resolved mount path ("/tools/{Key}"). Wick fills
// this in at boot — modules must leave it zero.
Path string `json:"path"`
Category string `json:"category,omitempty"`
// DefaultVisibility is the visibility used when no DB override exists.
// Defaults to VisibilityPrivate if not set.
DefaultVisibility entity.ToolVisibility `json:"-"`
// ExternalURL marks the tool as an external link. When set, the home
// card and palette open this URL in a new tab instead of navigating
// to Path. Direct hits to Path still resolve (the module redirects)
// so the link can be shared, bookmarked, and gated by the visibility
// middleware.
ExternalURL string `json:"external_url,omitempty"`
// DefaultTags are seeded on startup. Each tag is created globally by
// name if missing (existing tags keep their flags untouched). The
// tags are also linked to this tool on the *first* registration only
// — once any tool_tag row exists for the tool path, the seed step
// skips linking so an admin who unlinks a tag won't see it return on
// the next restart.
DefaultTags []DefaultTag `json:"-"`
// FullScreen opts this tool into full-viewport layout: the ToolHeader
// title bar is hidden, the content area expands edge-to-edge (no
// max-w-container padding), and the tool owns its own internal
// navigation. All other tools keep the standard constrained layout.
FullScreen bool `json:"-"`
}
Tool describes a tool entry shown on the home page.