- phrasebook ships the backend::lang admin strings (pl, en) with CLDR
plural maps, loads them as namespace backend, applies
pact.HasLangOverrides trees (lang/<locale>/<namespace>/<group>.yaml)
after every namespace, and fails activation when a backend key cannot
convert to plural forms
- Translator.Forms, Bundle, Resolved and Has serve keys as CLDR form maps
- Public GET /lang returns every backend::lang key for the request
locale over the fallback locale, Cache-Control no-cache
- config_list, config_form and config_relation accept a strict messages
block; omitted keys take framework defaults, schemas serve every message
as CLDR forms, and activation fails on a missing phrase key
- toolbar.buttons is an ordered [create, delete] list; the Winter string
form, duplicates, unknown actions and delete without showCheckboxes fail
at boot, and create is dropped when the controller has no form
- Form schema serves the raw Winter redirects; scaffold emits the list
syntax; form and relation schema routes are typed in the admin OpenAPI
- FieldRelationContract/FieldRelationProvider bind every type: relation
field to a belongsTo foreign key or a belongsToMany pivot; activation
fails naming plugin, controller and field on a missing or broken contract
- GET /{vendor}/{plugin}/{controller}/fields/{field}/options serves
{value, label} pages scoped by pact.RelationExtendOptionsQuery, behind
the controller permission; read-only and non-relation fields are 404
- Saves apply present relation keys after the Before hook: ids are
revalidated through the same scoped query (422 and full rollback
otherwise), belongsTo sets the foreign key, belongsToMany replaces pivot
rows in submitted order with the order column set to the index
- Show, create and update return relation values in data and meta.labels
- A belongsTo on a protected fill key is read-only (D-26)
- One six-segment GET pattern dispatches relation lists and field options,
which ServeMux cannot register side by side
- Admin OpenAPI documents the options route and RecordEnvelope
- Record routes must enforce permission before ids or bodies and return D-10 envelopes
- Create, update, and delete run Before and After hooks once inside the transaction
- Out-of-scope and missing records are indistinguishable, and hook failure rolls back
- Audience-aware mint, verify, refresh, and backend guard keep frontend tokens compatible
- Cabana mounts raw admin login, list schema, and record list behind admin.jwt.secret
- Framework migration seeds Winter backend users and developer/publisher roles
- GroupRaw plus sticky raw inheritance and registration-time house-envelope refusal via pact.HasHouseMiddleware
- Recover on raw routes writes a bare 500; non-raw keeps the house JSON body
- Router.Routes() and surf.RouteListCommand; generated main registers route:list
- Add Post/Put/Patch/Delete on pact.Router and surf Router/Group
- Resolve name:param middleware via RegisterMiddlewareFactory
- Add bouncer.Registry with Guard, CredentialGuard, UnauthorizedWriter
- Re-express jwt as NewJWTGuard without changing Middleware bodies
Render plugin.go, routes.go, leaf packages and go.mod from embedded
templates, emit empty registry accessors, and define job, admin, lang
and mail capability contracts so a new plugin compiles before artifacts.
Co-authored-by: Cursor <cursoragent@cursor.com>
Compile regex and enum constraints at route registration so malformed and unknown IDs share a 404, and named rollback errors isolate one plugin's history.
Co-authored-by: Cursor <cursoragent@cursor.com>
Named middleware resolves at boot, HS256 tokens are pinned with required
exp/sub, and both binaries expose a signal-aware serve command.
Co-authored-by: Cursor <cursoragent@cursor.com>
Open one pgx stdlib *sql.DB, hand it to GORM, and run per-plugin
gormigrate sets with isolated history tables after an ICU pl-PL check.
Co-authored-by: Cursor <cursoragent@cursor.com>
- App-scoped typed Publish/Lookup with duplicate-provider errors
- Set plugin IDs before Register so HasPlugin sees the full set
- Greeter uses pact.OptionalMessage without importing optional
- Add party plugin registry with Register-before-Boot activation
- Add backpack, compass, bonfire, and pact capability interfaces
- Add examples/hello with two compiled plugin modules