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) 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) 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 ¶
DefaultTag is the spec used by Tool.DefaultTags to seed tags on startup.
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)
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:"-"`
}
Tool describes a tool entry shown on the home page.