Documentation
¶
Overview ¶
Package entity describes tenant-owned data and derives its field metadata. It does not open a database, authorize an operation or persist a value. Embed Base and implement TableName to describe a tenant-owned entity, or use FieldsOf for a plain input struct that needs no storage identity.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var Widgets = []string{
"checkbox", "color", "date", "datetime", "email", "entity-picker", "file",
"hidden", "month", "number", "password", "search", "select", "tel", "text",
"textarea", "time", "url", "week",
}
Widgets is every name `ui:"widget:…"` may carry. It is the vocabulary, not a suggestion: the control each name draws lives in ui/forms, which cannot be imported from here, so what binds the two is a test there that names a rendered control for every entry here, and the mount-time refusal in kit/rest's Spec.check. A widget absent from this list is a compile-adjacent mistake rather than a runtime surprise: kit/entity owns the names because ui/forms owns the renderers, and a kernel below the presentation layer has no way to ask what a control is.
Two entries are aliases of what a Go type already picks — `datetime` for a time.Time and `checkbox` for a bool — kept because fifteen fields of the foundation's own entities, and of the catalog and a client, name them. They now mean the control instead of being ignored next to it, which is why a string holding a timestamp or a "true" draws the same control its time.Time and bool neighbours do.
Functions ¶
func ValidWidget ¶
ValidWidget reports whether a screen can draw the named widget. The empty string is valid: it means "pick from Type", which is most fields.
Types ¶
type Base ¶
type Base struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id" required:"false" readOnly:"true"`
TenantID uuid.UUID `gorm:"type:uuid;not null" json:"-"`
CreatedAt time.Time `json:"createdAt" required:"false" readOnly:"true"`
UpdatedAt time.Time `json:"updatedAt" required:"false" readOnly:"true"`
DeletedAt *time.Time `gorm:"index" json:"-"`
}
Base is embedded by every tenant-owned entity. The kernel sets TenantID from the transaction's scope; a module never assigns it, and never sees it in JSON either, because a tenant that a caller could send is a tenant a caller could change.
The three fields a caller may read are marked read-only for OpenAPI and not required in a request body: the server sets all of them, so a create that had to send an id would be a create that could choose one.
type Entity ¶
type Entity interface {
TableName() string
// contains filtered or unexported methods
}
Entity is a tenant-owned row: a table name and an embedded Base.
type Field ¶
type Field struct {
// Name is the JSON name, which is the only name a caller ever uses.
Name string `json:"name"`
// Column is the storage column used by the CRUD adapter. It comes from
// the struct, never from a request; deriving it executes no SQL.
Column string `json:"-"`
Type FieldType `json:"type"`
// Elem is what a TypeList holds, and empty for everything else.
Elem FieldType `json:"elem,omitempty"`
// Widget overrides the control a screen would pick from Type: `ui:"widget:select"`.
// It must be a name Widgets admits; a Spec whose entity carries any other
// name refuses to mount, because a name no renderer knows used to draw a
// plain text input in silence.
Widget string `json:"widget,omitempty"`
// Enum is the closed set of values, from `enum:"open,done"`.
Enum []string `json:"enum,omitempty"`
// Required comes from `validate:"required"`.
Required bool `json:"required,omitempty"`
// ReadOnly marks the fields Base contributes: a caller may read them and
// may not write them, so they are skipped by the PATCH merge.
ReadOnly bool `json:"readOnly,omitempty"`
// HideList keeps a field off the list screen, from `ui:"hide:list"`.
HideList bool `json:"hideList,omitempty"`
// Default is the value the entity declares for a field a caller may leave
// out, from `default:"open"` — the same tag huma reads, so the form and the
// API document agree about what happens when nothing is sent. A form
// preselects it, and a select that has one needs no "Choose a …" placeholder
// because there is no unchosen state to name.
Default string `json:"default,omitempty"`
// Doc is what the field is for, from `doc:"Lifecycle state"` — again huma's
// own tag, so the sentence in the OpenAPI document is the sentence under the
// control. It is a description and not a label: the entities here write
// "Short summary of the task", which reads under an input and not on it.
Doc string `json:"doc,omitempty"`
// Index locates the field in the struct. It is exported for one caller,
// kit/rest's PATCH merge, which decodes a body into the field this names;
// json:"-" because a screen has no use for it and a caller none at all.
Index []int `json:"-"`
}
Field is one column, as the API and a screen see it.
func FieldNamed ¶
FieldNamed finds a field by its JSON name in the caller's metadata.
type FieldType ¶
type FieldType string
FieldType is the closed set of shapes a screen knows how to render and a query knows how to compare. A field of any other Go type is left out of the schema entirely, so it is neither rendered nor sortable nor filterable — it is still stored, and still in the JSON, because that is encoding/json's business and not this package's.
const ( TypeString FieldType = "string" TypeText FieldType = "text" TypeInt FieldType = "int" TypeFloat FieldType = "float" TypeBool FieldType = "bool" TypeTime FieldType = "time" TypeUUID FieldType = "uuid" // TypeList is a slice of one of the above, which Field.Elem names. A user's // roles is the case that made it necessary: without it the field was in no // schema, so it rendered nowhere, no filter could refuse it and Immutable // could not name it — a PATCH could not reach it either, but only because // the field did not exist, which is the right answer for the wrong reason. TypeList FieldType = "list" )
type Schema ¶
type Schema struct {
Module string `json:"module"`
Entity string `json:"entity"`
Path string `json:"path"`
Fields []Field `json:"fields"`
}
Schema describes an entity for consumers that did not compile against it. An integration supplies its module, resource name and path.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package display is how a field's value reaches a person: the text a control carries, the word a screen shows, and the name a field is called by.
|
Package display is how a field's value reaches a person: the text a control carries, the word a screen shows, and the name a field is called by. |