Files
summercms/modules/cabana/admin_openapi.go
Jakub Zych 6af88f9df6 feat(cabana): widget action payload and data channel (quick-261006-eyj)
- pact.AdminActionInput.Payload (json.RawMessage) carries the widget's own
  JSON value untouched; pact.AdminActionResult.Data is passed through as data
- cabana decodes payload with a 64 KiB cap (422 on body), refuses it on the
  toolbar and record routes, and embeds Data once encoded with a 256 KiB cap
  (opaque 500 when larger or unencodable); fill stays filtered
- root .swaggo overrides json.RawMessage so swag keeps record_id and values;
  admin.json and schema.d.ts regenerated (payload?: unknown, data?: unknown)
- TestWidgetPayloadAndData covers pass-through, cap, refusal and data 500
- cabana and pact READMEs, partials-and-widgets and admin-spa docs updated
2026-10-06 11:13:16 +02:00

1181 lines
55 KiB
Go

package cabana
// @title SummerCMS Admin API
// @version 1
// @description Framework admin API consumed by the embedded admin SPA. Every path is relative to {backend.uri}/api/v1 (for example /backend/api/v1). The SPA authenticates with the HttpOnly summer_admin cookie set by a login that sends X-Requested-With: XMLHttpRequest, and sends that header on every request; CLI clients and tests send the BackendBearer Authorization header instead.
// @BasePath /
// @securityDefinitions.apikey BackendBearer
// @in header
// @name Authorization
// @description Backend admin bearer token. Send "Bearer {access_token}".
// Admin API annotations. scripts/check-admin-openapi.sh reads them with swag
// to produce admin/openapi/admin.json, the document the SPA's TypeScript types
// are generated from (D-15). The functions are not mounted; service.mount in
// http.go is the runtime route table, and TestPhase09PermissionMatrix plus
// TestPhase09ContractInventory fail if the two lists diverge.
import "encoding/json"
// ErrorBody is one D-10 error object.
type ErrorBody struct {
Code string `json:"code"`
Message string `json:"message"`
Details map[string]any `json:"details"`
}
// ErrorEnvelope is the D-10 error envelope.
type ErrorEnvelope struct {
Error ErrorBody `json:"error"`
}
// SuccessMeta is the D-10 meta object.
type SuccessMeta struct {
Locale string `json:"locale,omitempty"`
Page int `json:"page,omitempty"`
PerPage int `json:"per_page,omitempty"`
Total int `json:"total,omitempty"`
LastPage int `json:"last_page,omitempty"`
}
// AdminLogoutData is the POST /auth/logout payload.
type AdminLogoutData struct {
Status string `json:"status"`
}
// AdminLoginData is the admin login and refresh payload. Bearer transport
// carries access_token; cookie transport (X-Requested-With: XMLHttpRequest)
// carries token_type "cookie" and expires_in, never the token.
type AdminLoginData struct {
AccessToken string `json:"access_token,omitempty"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in,omitempty"`
}
// Envelope is the typed D-10 success envelope.
type Envelope[T any] struct {
Data T `json:"data"`
Meta SuccessMeta `json:"meta"`
}
// ListEnvelope is the typed D-10 paginated envelope (Phase 9 D-11 meta).
type ListEnvelope[T any] struct {
Data T `json:"data"`
Meta ListMeta `json:"meta"`
}
// AdminRecord is one admin record: a string-keyed map read through its
// list or form schema (D-16).
type AdminRecord map[string]any
// AdminIDsRequest is the body of the id-list writes: bulk delete, relation
// unlink and relation child delete.
type AdminIDsRequest struct {
IDs []uint64 `json:"ids"`
}
// AdminRelationLinkRequest is the body of the relation link route: the
// related ids and, on a belongsToMany relation with a pivot form, the pivot
// form values of exactly one linked id. Unknown keys are refused.
type AdminRelationLinkRequest struct {
IDs []uint64 `json:"ids"`
Pivot map[string]any `json:"pivot,omitempty"`
}
// AdminLoginRequest is the admin login body. Either login or email
// identifies the backend user.
type AdminLoginRequest struct {
Login string `json:"login,omitempty"`
Email string `json:"email,omitempty"`
Password string `json:"password"`
}
// AdminRoleSummary is the role attached to an admin profile.
type AdminRoleSummary struct {
ID uint `json:"id"`
Code string `json:"code"`
Name string `json:"name"`
}
// AdminProfile is the GET /auth/me payload.
type AdminProfile struct {
ID uint `json:"id"`
Login string `json:"login"`
Email string `json:"email"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
IsSuperuser bool `json:"is_superuser"`
Role *AdminRoleSummary `json:"role,omitempty"`
}
// AdminLogin documents POST /auth/login.
//
// @Summary Admin login
// @Tags admin
// @Accept json
// @Produce json
// @Param body body AdminLoginRequest true "Credentials"
// @Param X-Requested-With header string false "XMLHttpRequest selects cookie transport"
// @Success 200 {object} Envelope[AdminLoginData]
// @Failure 401 {object} ErrorEnvelope
// @Router /auth/login [post]
func AdminLogin() {}
// AdminRefresh documents POST /auth/refresh.
//
// @Summary Refresh an admin token
// @Tags admin
// @Accept json
// @Produce json
// @Param X-Requested-With header string false "XMLHttpRequest; required unless a Bearer token is sent"
// @Success 200 {object} Envelope[AdminLoginData]
// @Failure 403 {object} ErrorEnvelope
// @Failure 401 {object} ErrorEnvelope
// @Router /auth/refresh [post]
func AdminRefresh() {}
// LangBundle is the public string bundle: full backend::lang key to CLDR
// forms (D-20).
type LangBundle map[string]MessageForms
// AdminLang documents GET /lang.
//
// @Summary Admin UI strings
// @Description Every backend::lang key as CLDR plural forms for the Accept-Language locale, over the fallback locale's keys. Public: the login screen loads it before signing in. meta.locale is the locale the bundle resolved to.
// @Tags admin
// @Produce json
// @Success 200 {object} Envelope[LangBundle]
// @Router /lang [get]
func AdminLang() {}
// AdminLogout documents POST /auth/logout.
//
// @Summary Admin logout
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Success 200 {object} Envelope[AdminLogoutData]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /auth/logout [post]
func AdminLogout() {}
// AdminMe documents GET /auth/me.
//
// @Summary Current admin
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Success 200 {object} Envelope[AdminProfile]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /auth/me [get]
func AdminMe() {}
// AdminNavigation documents GET /navigation.
//
// @Summary Admin navigation
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Success 200 {object} Envelope[[]NavigationEntry]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /navigation [get]
func AdminNavigation() {}
// AdminSettingsList documents GET /settings.
//
// @Summary List admin settings
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Success 200 {object} Envelope[[]SettingsEntry]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /settings [get]
func AdminSettingsList() {}
// AdminSettingsSchema documents GET /settings/{code}/schema.
//
// @Summary Admin settings schema
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param code path string true "Settings code"
// @Success 200 {object} Envelope[FormView]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /settings/{code}/schema [get]
func AdminSettingsSchema() {}
// AdminSettingsGet documents GET /settings/{code}.
//
// @Summary Read admin settings
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param code path string true "Settings code"
// @Success 200 {object} Envelope[SettingsResult]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /settings/{code} [get]
func AdminSettingsGet() {}
// AdminSettingsPut documents PUT /settings/{code}.
//
// @Summary Update admin settings
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param code path string true "Settings code"
// @Param body body AdminRecord true "Setting values keyed by field name"
// @Success 200 {object} Envelope[SettingsResult]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /settings/{code} [put]
func AdminSettingsPut() {}
// AdminListSchema documents the list schema route.
//
// @Summary Admin list schema
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Success 200 {object} Envelope[ListSchema]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/schema/list [get]
func AdminListSchema() {}
// AdminFormSchema documents the form schema route.
//
// @Summary Admin form schema
// @Description The form of a controller, localized. `preview` is present when config_form.yaml declares a preview block: the form then has a read-only preview screen, which shows the fields whose context allows preview, the record actions and, when preview.headerPartial is set, that partial as a status hint. A `type: password` field and every other field the controller lists as virtual is sent in a save body and never has a value in a record response. `preset` on a text field names the field it follows on the create form (type slug or exact) until the administrator edits it. A `type: permissioneditor` field carries `permissionOptions`, the permissions the controller offers the requesting administrator; its value in a record response and in a save body is an object of permission code to integer (radio mode 1 or -1, checkbox mode 1). A `type: relation` field over a protected foreign key is `readOnly` unless its contract declares the key writable.
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Success 200 {object} Envelope[FormView]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/schema/form [get]
func AdminFormSchema() {}
// AdminRelationSchema documents the relation schema route.
//
// @Summary Admin relation schema
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param name path string true "Relation name"
// @Success 200 {object} Envelope[RelationSchema]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/schema/relation/{name} [get]
func AdminRelationSchema() {}
// AdminFieldOptions documents the relation field options route (D-17).
//
// @Summary Relation field options
// @Description Choices for a writable `type: relation` field: value is the related id, label its nameFrom column. Read-only and non-relation fields answer 404.
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param field path string true "Relation field name"
// @Param search query string false "Case-insensitive label search"
// @Param page query integer false "Page"
// @Param per_page query integer false "Options per page (1-100, default 20)"
// @Success 200 {object} ListEnvelope[[]RelationOption]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/fields/{field}/options [get]
func AdminFieldOptions() {}
// AdminFilterOptions documents the model-backed filter options route (D-27).
//
// @Summary Filter scope options
// @Description Choices of a declared scope filter of the controller's list, from the model's FilterOptions. {scope} is the filter name used as filter[<scope>]; labels are localized.
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param scope path string true "Filter name"
// @Success 200 {object} Envelope[[]FilterOption]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/filters/{scope}/options [get]
func AdminFilterOptions() {}
// AdminList documents the record list route.
//
// @Summary List admin records
// @Description meta.row_states carries the states of the page's rows keyed by row id, each a subset of deleted, negative and disabled; it is absent when the controller reports no state.
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param search query string false "Search term"
// @Param sort query string false "Sort column"
// @Param dir query string false "Sort direction (asc or desc)"
// @Param page query integer false "Page"
// @Param per_page query integer false "Records per page"
// @Param filter query object false "Filter values keyed by filter name, sent as filter[<name>]=<value>"
// @Success 200 {object} ListEnvelope[[]AdminRecord]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller} [get]
func AdminList() {}
// AdminCreate documents the record create route.
//
// @Summary Create an admin record
// @Description Relation fields are sent by field name with ids ({"genre": 3, "artists": [4, 9]}); the response carries the same shape plus meta.labels.
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param body body AdminRecord true "Field values keyed by field name; relation fields carry ids"
// @Param X-Session-Key header string false "Form session key: the save attaches the files uploaded under it"
// @Success 201 {object} RecordEnvelope
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope "also returned when controller code refuses the write; details may name fields"
// @Failure 422 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller} [post]
func AdminCreate() {}
// AdminBulkDelete documents the bulk delete route.
//
// @Summary Bulk-delete admin records
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param body body AdminIDsRequest true "Record ids"
// @Success 200 {object} Envelope[BulkResult]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope "also returned when controller code refuses the write; details may name fields"
// @Failure 422 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 409 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/bulk-delete [post]
func AdminBulkDelete() {}
// AdminBulkAction documents the declared bulk action route.
//
// @Summary Run a declared bulk action
// @Description Runs a bulk action the controller registers and the list's bulkActions declares. The ids are resolved and row-locked through the controller's list scope in one transaction before the action runs: a selection that matches no scoped row answers affected 0 without running the action, and a partial selection is a 409 that changes nothing.
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param action path string true "Bulk action name"
// @Param body body AdminIDsRequest true "Record ids"
// @Success 200 {object} Envelope[BulkActionResult]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope "also returned when controller code refuses the write; details may name fields"
// @Failure 404 {object} ErrorEnvelope
// @Failure 409 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/bulk/{action} [post]
func AdminBulkAction() {}
// AdminRecordAction documents the declared record action route.
//
// @Summary Run a declared record action
// @Description Runs a record action the controller registers and the form's recordActions declares. The record is loaded and row-locked through the controller's form scope in one transaction (404 when missing or out of scope); an action that does not apply to the record's current state answers 409. The body must be {}: record_id, values and payload are all refused, and the answer's fill is always empty.
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Record id"
// @Param action path string true "Record action name"
// @Param body body AdminActionRequest true "Empty object"
// @Success 200 {object} Envelope[AdminActionResult]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope "also returned when controller code refuses the write; details may name fields"
// @Failure 404 {object} ErrorEnvelope
// @Failure 409 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/actions/{action} [post]
func AdminRecordAction() {}
// AdminActionRequest is the body of a widget or toolbar action. record_id is
// the record a widget on the update form belongs to (absent on create and
// always absent for a toolbar action); values is the widget's snapshot of its
// fill fields; payload is the widget's own JSON value.
type AdminActionRequest struct {
RecordID *uint64 `json:"record_id,omitempty"`
Values map[string]any `json:"values,omitempty"`
// Payload is the widget's own JSON value (the summer-action event's
// detail.payload): any JSON, at most 64 KiB, handed to the action as-is.
// Toolbar and record routes refuse it.
Payload json.RawMessage `json:"payload,omitempty"`
}
// AdminActionResult is an action's answer: a localized message for the toast
// and the widget write-back, holding only the field's declared fill keys with
// scalar values. fill is always an object.
type AdminActionResult struct {
Message string `json:"message"`
Fill map[string]any `json:"fill"`
// Data is the action's structured answer for the widget: any JSON value,
// not filtered by fill, absent when the action returned none.
Data any `json:"data,omitempty"`
}
// AdminWidgetAction documents the widget action route.
//
// @Summary Run a widget action
// @Description Runs the controller action a `type: widget` field declares. The record is loaded through the controller's form scope (404 when out of scope); only the field's fill keys with scalar values reach the action and the response. An optional payload (any JSON value, at most 64 KiB) is accepted and handed to the action as-is; the response may carry data, the action's own JSON answer, which is not subject to the fill filter.
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param field path string true "Widget field name"
// @Param body body AdminActionRequest true "Record id, fill snapshot and optional payload"
// @Success 200 {object} Envelope[AdminActionResult]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/widgets/{field} [post]
func AdminWidgetAction() {}
// AdminToolbarAction documents the toolbar action route.
//
// @Summary Run a toolbar action
// @Description Runs a controller-registered action that the list's toolbar.buttons declares. The body must be {}: record_id, values and payload are all refused, and the answer's fill is always empty.
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param action path string true "Action name"
// @Param body body AdminActionRequest true "Empty object"
// @Success 200 {object} Envelope[AdminActionResult]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/toolbar/{action} [post]
func AdminToolbarAction() {}
// AdminPartial documents the controller partial route.
//
// @Summary Render a controller partial
// @Description Renders a declared header partial or form partial with html/template against the controller's view model and returns it as an allowlisted node tree: no HTML string. Without id the view model gets no record; id is accepted only for form partials and is loaded through the controller's form scope.
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param name path string true "Partial name"
// @Param id query integer false "Record id for a form partial"
// @Success 200 {object} Envelope[PartialView]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/partials/{name} [get]
func AdminPartial() {}
// AdminShow documents the record show route.
//
// @Summary Show an admin record
// @Description meta.labels carries the display labels of relation fields. meta.actions lists the declared record actions the requesting admin may run and that apply to the record's current state; it is absent when none is offered.
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Record id"
// @Success 200 {object} RecordEnvelope
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id} [get]
func AdminShow() {}
// AdminUpdate documents the record update route.
//
// @Summary Update an admin record
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Record id"
// @Param body body AdminRecord true "Field values keyed by field name; relation fields carry ids"
// @Param X-Session-Key header string false "Form session key: the save applies the file uploads and removals held against it"
// @Success 200 {object} RecordEnvelope
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope "also returned when controller code refuses the write; details may name fields"
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id} [put]
func AdminUpdate() {}
// AdminDelete documents the record delete route.
//
// @Summary Delete an admin record
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Record id"
// @Success 200 {object} Envelope[BulkResult]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope "also returned when controller code refuses the write; details may name fields"
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id} [delete]
func AdminDelete() {}
// AdminRelationLinked documents the linked-relation route.
//
// @Summary List linked relation records
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param search query string false "Search term over the panel's searchable columns"
// @Param sort query string false "Sort column (a sortable panel column)"
// @Param dir query string false "Sort direction (asc or desc)"
// @Param page query integer false "Page"
// @Param per_page query integer false "Records per page (1-100, default 20)"
// @Param X-Session-Key header string false "Form session key; with it, owner id 0 is the record being created in that session"
// @Success 200 {object} ListEnvelope[[]AdminRecord]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name} [get]
func AdminRelationLinked() {}
// AdminRelationCandidates documents the relation candidate route.
//
// @Summary List relation candidates
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param search query string false "Search term over the panel's searchable columns"
// @Param sort query string false "Sort column (a sortable panel column)"
// @Param dir query string false "Sort direction (asc or desc)"
// @Param page query integer false "Page"
// @Param per_page query integer false "Records per page (1-100, default 20)"
// @Param X-Session-Key header string false "Form session key; with it, owner id 0 is the record being created in that session"
// @Success 200 {object} ListEnvelope[[]AdminRecord]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/candidates [get]
func AdminRelationCandidates() {}
// AdminRelationLink documents the relation link route.
//
// @Summary Link relation records
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param body body AdminRelationLinkRequest true "Related record ids and optional pivot form values"
// @Param X-Session-Key header string false "Form session key; with it, owner id 0 is the record being created in that session"
// @Success 200 {object} Envelope[RelationMutationResult]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/link [post]
func AdminRelationLink() {}
// AdminRelationUnlink documents the relation unlink route.
//
// @Summary Unlink relation records
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param body body AdminIDsRequest true "Related record ids"
// @Param X-Session-Key header string false "Form session key; with it, owner id 0 is the record being created in that session"
// @Success 200 {object} Envelope[RelationMutationResult]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/unlink [post]
func AdminRelationUnlink() {}
// AdminRelationChildCreate documents the relation child create route.
//
// @Summary Create a related record
// @Description Creates a record through the relation's manage form (manage.form, or the top-level form of config_relation.yaml) and attaches it to the owner: a hasMany child gets the owner's key in its foreign key (the server sets it; the body cannot), a belongsToMany record gets a pivot row. The view panel must declare the create toolbar button, otherwise 403. The owner is scoped like the record show route.
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param body body AdminRecord true "Field values of the manage form keyed by field name"
// @Param X-Session-Key header string false "Form session key; with it, owner id 0 is the record being created in that session"
// @Param X-Child-Session-Key header string false "Child form session key: the save attaches the child files uploaded under it"
// @Success 201 {object} RecordEnvelope
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 413 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/records [post]
func AdminRelationChildCreate() {}
// AdminRelationChildShow documents the relation child show route.
//
// @Summary Show a related record
// @Description One child of the owner, projected through the manage form when the relation declares the update button, else through the view form (view.form, or the top-level form). A record that is not a child of this owner (hasMany: its foreign key; belongsToMany: a pivot row) is 404. Without either form the route answers 403.
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param child path integer true "Related record id"
// @Param X-Session-Key header string false "Form session key; with it, owner id 0 is the record being created in that session"
// @Success 200 {object} RecordEnvelope
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/records/{child} [get]
func AdminRelationChildShow() {}
// AdminRelationChildUpdate documents the relation child update route.
//
// @Summary Update a related record
// @Description Saves one child of the owner through the manage form, with the related model's rules and hooks. The view panel must declare the update toolbar button, otherwise 403. A record that is not a child of this owner is 404.
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param child path integer true "Related record id"
// @Param body body AdminRecord true "Field values of the manage form keyed by field name"
// @Param X-Session-Key header string false "Form session key; with it, owner id 0 is the record being created in that session"
// @Param X-Child-Session-Key header string false "Child form session key: the save attaches the child files uploaded under it"
// @Success 200 {object} RecordEnvelope
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 413 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/records/{child} [put]
func AdminRelationChildUpdate() {}
// AdminRelationChildDelete documents the relation child delete route.
//
// @Summary Delete related records
// @Description Deletes children of the owner through their model: a hasMany child is deleted (hooks and soft delete run); a belongsToMany record loses this owner's pivot row and is then deleted. Every id must be a child of this owner, otherwise the whole request is 404 and nothing is deleted. The view panel must declare the delete toolbar button, otherwise 403.
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param body body AdminIDsRequest true "Related record ids"
// @Param X-Session-Key header string false "Form session key; with it, owner id 0 is the record being created in that session"
// @Success 200 {object} Envelope[BulkResult]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 413 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/delete [post]
func AdminRelationChildDelete() {}
// AdminRelationPivotShow documents the pivot show route.
//
// @Summary Show the pivot values of a link
// @Description The pivot form (pivot.form) values of the pivot row linking the owner and one related record, keyed by field name; id is the related record's id. Needs a pivot form and the link or update toolbar button (403 otherwise); a record not linked to this owner is 404.
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param child path integer true "Related record id"
// @Param X-Session-Key header string false "Form session key; with it, owner id 0 is the record being created in that session"
// @Success 200 {object} Envelope[AdminRecord]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/pivot/{child} [get]
func AdminRelationPivotShow() {}
// AdminRelationPivotUpdate documents the pivot update route.
//
// @Summary Update the pivot values of a link
// @Description Saves pivot form values on the pivot row linking the owner and one related record. Only pivot form fields are accepted (422 per unknown key); the pivot foreign keys, timestamps and hook columns can never be set. Gated and scoped like the pivot show route.
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param child path integer true "Related record id"
// @Param body body AdminRecord true "Pivot form values keyed by field name"
// @Param X-Session-Key header string false "Form session key; with it, owner id 0 is the record being created in that session"
// @Success 200 {object} Envelope[AdminRecord]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 413 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/pivot/{child} [put]
func AdminRelationPivotUpdate() {}
// AdminRelationChildFileList documents the file list of a relation child
// form's fileupload field.
//
// @Summary List the files of a related record's fileupload field
// @Description The child-form counterpart of the record file list: the files attached to the related record minus the X-Child-Session-Key session's pending removals, plus its pending uploads. The related record is scoped to the owner like the child show route; child 0 needs the create toolbar button and the child key, a saved child the update button or a view form (403 otherwise).
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param child path integer true "Related record id (0 for the child being created)"
// @Param field path string true "fileupload field of the relation's manage form"
// @Param X-Session-Key header string false "Owner form session key; needed when the owner id is 0"
// @Param X-Child-Session-Key header string false "Child form session key (32-128 characters of A-Z a-z 0-9 _ -); needed for child 0 and for pending uploads"
// @Success 200 {object} Envelope[[]FileItem]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/records/{child}/files/{field} [get]
func AdminRelationChildFileList() {}
// AdminRelationChildFileUpload documents an upload to a relation child
// form's fileupload field.
//
// @Summary Upload a file to a related record's fileupload field
// @Description Stores one multipart file_data part and binds it to the X-Child-Session-Key session; the child's create or update save with the same key attaches it. Limits and errors as on the record upload route. Writes to a saved child need the update toolbar button (403 otherwise).
// @Tags admin
// @Accept multipart/form-data
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param child path integer true "Related record id (0 for the child being created)"
// @Param field path string true "fileupload field of the relation's manage form"
// @Param X-Session-Key header string false "Owner form session key; needed when the owner id is 0"
// @Param X-Child-Session-Key header string true "Child form session key (32-128 characters of A-Z a-z 0-9 _ -)"
// @Param file_data formData file true "The file"
// @Success 201 {object} Envelope[FileItem]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 413 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/records/{child}/files/{field} [post]
func AdminRelationChildFileUpload() {}
// AdminRelationChildFileUpdate documents the caption route of a relation
// child form's fileupload field.
//
// @Summary Save a related record file's title and description
// @Description As the record caption route, for a file of the related record or of the child session. The field must declare useCaption (403 otherwise).
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param child path integer true "Related record id (0 for the child being created)"
// @Param field path string true "fileupload field of the relation's manage form"
// @Param file path integer true "File id"
// @Param X-Session-Key header string false "Owner form session key; needed when the owner id is 0"
// @Param X-Child-Session-Key header string false "Child form session key (32-128 characters of A-Z a-z 0-9 _ -); needed for child 0 and for pending uploads"
// @Param body body AdminFileCaptionRequest true "Title and description"
// @Success 200 {object} Envelope[FileItem]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 413 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/records/{child}/files/{field}/{file} [put]
func AdminRelationChildFileUpdate() {}
// AdminRelationChildFileRemove documents the removal of a file from a
// relation child form's fileupload field.
//
// @Summary Remove a related record's file
// @Description Removing an attached file is deferred to the child's next save with the same X-Child-Session-Key; removing a pending upload deletes it at once.
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param child path integer true "Related record id (0 for the child being created)"
// @Param field path string true "fileupload field of the relation's manage form"
// @Param file path integer true "File id"
// @Param X-Session-Key header string false "Owner form session key; needed when the owner id is 0"
// @Param X-Child-Session-Key header string true "Child form session key (32-128 characters of A-Z a-z 0-9 _ -)"
// @Success 200 {object} Envelope[FileMutationResult]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/records/{child}/files/{field}/{file} [delete]
func AdminRelationChildFileRemove() {}
// AdminRelationChildFileReorder documents the reorder route of a relation
// child form's attachMany field.
//
// @Summary Reorder a related record's files
// @Description As the record reorder route: ids must be exactly the field's visible files. attachMany only, otherwise 403.
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param child path integer true "Related record id (0 for the child being created)"
// @Param field path string true "fileupload field of the relation's manage form"
// @Param X-Session-Key header string false "Owner form session key; needed when the owner id is 0"
// @Param X-Child-Session-Key header string false "Child form session key (32-128 characters of A-Z a-z 0-9 _ -); needed for child 0 and for pending uploads"
// @Param body body AdminIDsRequest true "File ids in the new order"
// @Success 200 {object} Envelope[[]FileItem]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 413 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/records/{child}/files/{field}/reorder [post]
func AdminRelationChildFileReorder() {}
// AdminRelationChildFileDownload documents the download of a related
// record's protected file.
//
// @Summary Download a related record's protected file
// @Description As the record download route, for a protected file of the related record or of the child session, with the same headers.
// @Tags admin
// @Produce octet-stream
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param child path integer true "Related record id (0 for the child being created)"
// @Param field path string true "fileupload field of the relation's manage form"
// @Param file path integer true "File id"
// @Param X-Session-Key header string false "Owner form session key; needed when the owner id is 0"
// @Param X-Child-Session-Key header string false "Child form session key (32-128 characters of A-Z a-z 0-9 _ -); needed for child 0 and for pending uploads"
// @Success 200 {file} file
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/records/{child}/files/{field}/{file}/download [get]
func AdminRelationChildFileDownload() {}
// AdminRelationChildFileThumb documents the thumbnail of a related
// record's protected image.
//
// @Summary Thumbnail of a related record's protected image
// @Description As the record thumb route, for a protected image of the related record or of the child session.
// @Tags admin
// @Produce octet-stream
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param name path string true "Relation name"
// @Param child path integer true "Related record id (0 for the child being created)"
// @Param field path string true "fileupload field of the relation's manage form"
// @Param file path integer true "File id"
// @Param X-Session-Key header string false "Owner form session key; needed when the owner id is 0"
// @Param X-Child-Session-Key header string false "Child form session key (32-128 characters of A-Z a-z 0-9 _ -); needed for child 0 and for pending uploads"
// @Success 200 {file} file
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/relations/{name}/records/{child}/files/{field}/{file}/thumb [get]
func AdminRelationChildFileThumb() {}
// FileMutationResult is the payload of a file removal: the number of files
// removed (always 1 on success).
type FileMutationResult struct {
Removed int `json:"removed"`
}
// AdminFileList documents the file list of a fileupload field.
//
// @Summary List the files of a fileupload field
// @Description The files attached to the record minus the session's pending removals, plus the session's pending uploads, in sort_order. id 0 is the record being created in the X-Session-Key session (the key is then required). url and thumb_url are set only for a public relation.
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param field path string true "fileupload field name"
// @Param X-Session-Key header string false "Form session key (32-128 characters of A-Z a-z 0-9 _ -)"
// @Success 200 {object} Envelope[[]FileItem]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/files/{field} [get]
func AdminFileList() {}
// AdminFileUpload documents the upload of one file to a fileupload field.
//
// @Summary Upload a file to a fileupload field
// @Description Stores one multipart file_data part and binds it to the X-Session-Key session; the record's next create or update save with the same key attaches it. id 0 is the record being created. A body over the upload cap answers 413 payload_too_large; a file over maxFilesize, of a type the field does not allow, or that fails the image check answers 422 on the field.
// @Tags admin
// @Accept multipart/form-data
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param field path string true "fileupload field name"
// @Param X-Session-Key header string true "Form session key (32-128 characters of A-Z a-z 0-9 _ -)"
// @Param file_data formData file true "The file"
// @Success 201 {object} Envelope[FileItem]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 413 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/files/{field} [post]
func AdminFileUpload() {}
// AdminFileUpdate documents the caption route of a fileupload field.
//
// @Summary Save a file's title and description
// @Description Saves at once (not deferred). The field must declare useCaption, otherwise 403. Omitted keys are left unchanged; unknown keys are refused.
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param field path string true "fileupload field name"
// @Param file path integer true "File id"
// @Param X-Session-Key header string false "Form session key; needed for a pending upload"
// @Param body body AdminFileCaptionRequest true "Title and description"
// @Success 200 {object} Envelope[FileItem]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 413 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/files/{field}/{file} [put]
func AdminFileUpdate() {}
// AdminFileRemove documents the removal of a file from a fileupload field.
//
// @Summary Remove a file
// @Description Removing an attached file is deferred to the record's next save with the same X-Session-Key; removing a pending upload deletes it at once.
// @Tags admin
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param field path string true "fileupload field name"
// @Param file path integer true "File id"
// @Param X-Session-Key header string true "Form session key"
// @Success 200 {object} Envelope[FileMutationResult]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/files/{field}/{file} [delete]
func AdminFileRemove() {}
// AdminFileReorder documents the reorder route of an attachMany field.
//
// @Summary Reorder the files of a field
// @Description ids must be exactly the field's visible files (attached minus pending removals plus pending uploads); they receive the existing sort_order values in the submitted order, at once. attachMany only, otherwise 403.
// @Tags admin
// @Accept json
// @Produce json
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param field path string true "fileupload field name"
// @Param X-Session-Key header string false "Form session key; needed for pending uploads"
// @Param body body AdminIDsRequest true "File ids in the new order"
// @Success 200 {object} Envelope[[]FileItem]
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 413 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/files/{field}/reorder [post]
func AdminFileReorder() {}
// AdminFileDownload documents the download of a protected file.
//
// @Summary Download a protected file
// @Description Streams a file of a protected (Public false) relation that belongs to a record the admin may load, or is pending in the admin's own session. Public files are 404. JPEG, PNG, GIF and WebP are served inline with their type; everything else as an application/octet-stream attachment. Responses carry X-Content-Type-Options nosniff, Cache-Control private, no-store and a sandboxing Content-Security-Policy.
// @Tags admin
// @Produce octet-stream
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param field path string true "fileupload field name"
// @Param file path integer true "File id"
// @Param X-Session-Key header string false "Form session key; needed for a pending upload"
// @Success 200 {file} file
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/files/{field}/{file}/download [get]
func AdminFileDownload() {}
// AdminFileThumb documents the thumbnail of a protected image.
//
// @Summary Thumbnail of a protected image
// @Description The preview thumbnail (imageWidth by imageHeight, 240 by 240 by default, in thumbOptions.mode) of a protected image file, scoped like the download route. A file that is not a JPEG, PNG, GIF or WebP image is 404.
// @Tags admin
// @Produce octet-stream
// @Security BackendBearer
// @Param vendor path string true "Vendor"
// @Param plugin path string true "Plugin"
// @Param controller path string true "Controller"
// @Param id path integer true "Owner id (0 for the record being created)"
// @Param field path string true "fileupload field name"
// @Param file path integer true "File id"
// @Param X-Session-Key header string false "Form session key; needed for a pending upload"
// @Success 200 {file} file
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 422 {object} ErrorEnvelope
// @Router /{vendor}/{plugin}/{controller}/{id}/files/{field}/{file}/thumb [get]
func AdminFileThumb() {}