feat(10-02): filter choices and a fully typed admin API proven on the wire

- pact.FilterOptions on the model serves a scope filter's choices; a scope
  filter whose model lacks it fails activation (D-27)
- GET /{vendor}/{plugin}/{controller}/filters/{scope}/options answers a
  declared scope filter behind the controller permission with localized
  {value, label} choices, 404 otherwise
- Every admin route documents a typed success schema, and protected routes
  document 401, 403 and 404 (422 on writes); SuccessEnvelope is gone and
  logout writes a typed AdminLogoutData
- jsonScalar and fieldContext decode their served shapes
- TestPhase10OpenAPIConformance calls every inventoried route through the
  assembled router on PostgreSQL and decodes each body into its documented
  type with unknown fields disallowed, checking admin.json's schema ref
- The SPA aliases every new schema type; Tailwind no longer scans the
  generated API files, so API changes do not churn boardwalk/dist
This commit is contained in:
Jakub Zych
2026-09-27 16:27:42 +02:00
parent c87148a34f
commit 9f296b0484
16 changed files with 1653 additions and 49 deletions

View File

@@ -35,6 +35,17 @@
],
"type": "object"
},
"cabana.AdminLogoutData": {
"properties": {
"status": {
"type": "string"
}
},
"required": [
"status"
],
"type": "object"
},
"cabana.AdminProfile": {
"properties": {
"email": {
@@ -106,6 +117,35 @@
],
"type": "object"
},
"cabana.BulkResult": {
"properties": {
"deleted": {
"type": "integer"
}
},
"required": [
"deleted"
],
"type": "object"
},
"cabana.Envelope-array_cabana_FilterOption": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/cabana.FilterOption"
},
"type": "array"
},
"meta": {
"$ref": "#/components/schemas/cabana.SuccessMeta"
}
},
"required": [
"data",
"meta"
],
"type": "object"
},
"cabana.Envelope-array_cabana_NavigationEntry": {
"properties": {
"data": {
@@ -124,6 +164,24 @@
],
"type": "object"
},
"cabana.Envelope-array_cabana_SettingsEntry": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/cabana.SettingsEntry"
},
"type": "array"
},
"meta": {
"$ref": "#/components/schemas/cabana.SuccessMeta"
}
},
"required": [
"data",
"meta"
],
"type": "object"
},
"cabana.Envelope-cabana_AdminLoginData": {
"properties": {
"data": {
@@ -139,6 +197,21 @@
],
"type": "object"
},
"cabana.Envelope-cabana_AdminLogoutData": {
"properties": {
"data": {
"$ref": "#/components/schemas/cabana.AdminLogoutData"
},
"meta": {
"$ref": "#/components/schemas/cabana.SuccessMeta"
}
},
"required": [
"data",
"meta"
],
"type": "object"
},
"cabana.Envelope-cabana_AdminProfile": {
"properties": {
"data": {
@@ -154,6 +227,21 @@
],
"type": "object"
},
"cabana.Envelope-cabana_BulkResult": {
"properties": {
"data": {
"$ref": "#/components/schemas/cabana.BulkResult"
},
"meta": {
"$ref": "#/components/schemas/cabana.SuccessMeta"
}
},
"required": [
"data",
"meta"
],
"type": "object"
},
"cabana.Envelope-cabana_FormView": {
"properties": {
"data": {
@@ -199,6 +287,21 @@
],
"type": "object"
},
"cabana.Envelope-cabana_RelationMutationResult": {
"properties": {
"data": {
"$ref": "#/components/schemas/cabana.RelationMutationResult"
},
"meta": {
"$ref": "#/components/schemas/cabana.SuccessMeta"
}
},
"required": [
"data",
"meta"
],
"type": "object"
},
"cabana.Envelope-cabana_RelationSchema": {
"properties": {
"data": {
@@ -214,6 +317,21 @@
],
"type": "object"
},
"cabana.Envelope-cabana_SettingsResult": {
"properties": {
"data": {
"$ref": "#/components/schemas/cabana.SettingsResult"
},
"meta": {
"$ref": "#/components/schemas/cabana.SuccessMeta"
}
},
"required": [
"data",
"meta"
],
"type": "object"
},
"cabana.ErrorBody": {
"properties": {
"code": {
@@ -245,6 +363,21 @@
],
"type": "object"
},
"cabana.FilterOption": {
"properties": {
"label": {
"type": "string"
},
"value": {
"type": "string"
}
},
"required": [
"label",
"value"
],
"type": "object"
},
"cabana.FormField": {
"properties": {
"attributes": {
@@ -893,6 +1026,17 @@
],
"type": "object"
},
"cabana.RelationMutationResult": {
"properties": {
"linked": {
"type": "integer"
},
"removed": {
"type": "integer"
}
},
"type": "object"
},
"cabana.RelationOption": {
"properties": {
"label": {
@@ -979,16 +1123,61 @@
],
"type": "object"
},
"cabana.SuccessEnvelope": {
"cabana.SettingsEntry": {
"properties": {
"data": {},
"meta": {
"$ref": "#/components/schemas/cabana.SuccessMeta"
"category": {
"type": "string"
},
"code": {
"type": "string"
},
"description": {
"type": "string"
},
"icon": {
"type": "string"
},
"keywords": {
"items": {
"type": "string"
},
"type": "array"
},
"label": {
"type": "string"
},
"model": {
"type": "string"
},
"order": {
"type": "integer"
}
},
"required": [
"category",
"code",
"description",
"icon",
"keywords",
"label",
"model",
"order"
],
"type": "object"
},
"cabana.SettingsResult": {
"properties": {
"data": {
"additionalProperties": {},
"type": "object"
},
"exists": {
"type": "boolean"
}
},
"required": [
"data",
"meta"
"exists"
],
"type": "object"
},
@@ -1115,7 +1304,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.SuccessEnvelope"
"$ref": "#/components/schemas/cabana.Envelope-cabana_AdminLogoutData"
}
}
},
@@ -1130,6 +1319,26 @@
}
},
"description": "Unauthorized"
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Forbidden"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Not Found"
}
},
"security": [
@@ -1165,6 +1374,26 @@
}
},
"description": "Unauthorized"
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Forbidden"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Not Found"
}
},
"security": [
@@ -1281,6 +1510,16 @@
}
},
"description": "Forbidden"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Not Found"
}
},
"security": [
@@ -1301,7 +1540,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.SuccessEnvelope"
"$ref": "#/components/schemas/cabana.Envelope-array_cabana_SettingsEntry"
}
}
},
@@ -1326,6 +1565,16 @@
}
},
"description": "Forbidden"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Not Found"
}
},
"security": [
@@ -1357,7 +1606,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.SuccessEnvelope"
"$ref": "#/components/schemas/cabana.Envelope-cabana_SettingsResult"
}
}
},
@@ -1421,7 +1670,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.SuccessEnvelope"
"$ref": "#/components/schemas/cabana.Envelope-cabana_SettingsResult"
}
}
},
@@ -1447,6 +1696,16 @@
},
"description": "Forbidden"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/json": {
@@ -1487,7 +1746,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.SuccessEnvelope"
"$ref": "#/components/schemas/cabana.Envelope-cabana_FormView"
}
}
},
@@ -1637,6 +1896,16 @@
},
"description": "Forbidden"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/json": {
@@ -1720,6 +1989,16 @@
},
"description": "Forbidden"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/json": {
@@ -1778,7 +2057,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.SuccessEnvelope"
"$ref": "#/components/schemas/cabana.Envelope-cabana_BulkResult"
}
}
},
@@ -1804,6 +2083,26 @@
},
"description": "Forbidden"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Not Found"
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Conflict"
},
"422": {
"content": {
"application/json": {
@@ -1954,6 +2253,100 @@
]
}
},
"/{vendor}/{plugin}/{controller}/filters/{scope}/options": {
"get": {
"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[\u003cscope\u003e]; labels are localized.",
"parameters": [
{
"description": "Vendor",
"in": "path",
"name": "vendor",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "Plugin",
"in": "path",
"name": "plugin",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "Controller",
"in": "path",
"name": "controller",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "Filter name",
"in": "path",
"name": "scope",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.Envelope-array_cabana_FilterOption"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Unauthorized"
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Forbidden"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Not Found"
}
},
"security": [
{
"BackendBearer": []
}
],
"summary": "Filter scope options",
"tags": [
"admin"
]
}
},
"/{vendor}/{plugin}/{controller}/schema/form": {
"get": {
"parameters": [
@@ -2260,7 +2653,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.SuccessEnvelope"
"$ref": "#/components/schemas/cabana.Envelope-cabana_BulkResult"
}
}
},
@@ -2295,6 +2688,16 @@
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Unprocessable Entity"
}
},
"security": [
@@ -2554,7 +2957,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.SuccessEnvelope"
"$ref": "#/components/schemas/cabana.ListEnvelope-array_cabana_AdminRecord"
}
}
},
@@ -2579,6 +2982,26 @@
}
},
"description": "Forbidden"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Unprocessable Entity"
}
},
"security": [
@@ -2646,7 +3069,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.SuccessEnvelope"
"$ref": "#/components/schemas/cabana.ListEnvelope-array_cabana_AdminRecord"
}
}
},
@@ -2671,6 +3094,26 @@
}
},
"description": "Forbidden"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Unprocessable Entity"
}
},
"security": [
@@ -2738,7 +3181,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.SuccessEnvelope"
"$ref": "#/components/schemas/cabana.Envelope-cabana_RelationMutationResult"
}
}
},
@@ -2764,6 +3207,16 @@
},
"description": "Forbidden"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/json": {
@@ -2840,7 +3293,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.SuccessEnvelope"
"$ref": "#/components/schemas/cabana.Envelope-cabana_RelationMutationResult"
}
}
},
@@ -2866,6 +3319,16 @@
},
"description": "Forbidden"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/cabana.ErrorEnvelope"
}
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/json": {

View File

@@ -82,7 +82,7 @@ export interface paths {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.SuccessEnvelope"];
"application/json": components["schemas"]["cabana.Envelope-cabana_AdminLogoutData"];
};
};
/** @description Unauthorized */
@@ -94,6 +94,24 @@ export interface paths {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Forbidden */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
};
};
delete?: never;
@@ -137,6 +155,24 @@ export interface paths {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Forbidden */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
};
};
put?: never;
@@ -287,6 +323,15 @@ export interface paths {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
};
};
put?: never;
@@ -320,7 +365,7 @@ export interface paths {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.SuccessEnvelope"];
"application/json": components["schemas"]["cabana.Envelope-array_cabana_SettingsEntry"];
};
};
/** @description Unauthorized */
@@ -341,6 +386,15 @@ export interface paths {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
};
};
put?: never;
@@ -377,7 +431,7 @@ export interface paths {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.SuccessEnvelope"];
"application/json": components["schemas"]["cabana.Envelope-cabana_SettingsResult"];
};
};
/** @description Unauthorized */
@@ -428,7 +482,7 @@ export interface paths {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.SuccessEnvelope"];
"application/json": components["schemas"]["cabana.Envelope-cabana_SettingsResult"];
};
};
/** @description Unauthorized */
@@ -449,6 +503,15 @@ export interface paths {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Unprocessable Entity */
422: {
headers: {
@@ -493,7 +556,7 @@ export interface paths {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.SuccessEnvelope"];
"application/json": components["schemas"]["cabana.Envelope-cabana_FormView"];
};
};
/** @description Unauthorized */
@@ -595,6 +658,15 @@ export interface paths {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Unprocessable Entity */
422: {
headers: {
@@ -654,6 +726,15 @@ export interface paths {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Unprocessable Entity */
422: {
headers: {
@@ -703,7 +784,7 @@ export interface paths {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.SuccessEnvelope"];
"application/json": components["schemas"]["cabana.Envelope-cabana_BulkResult"];
};
};
/** @description Unauthorized */
@@ -724,6 +805,24 @@ export interface paths {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Conflict */
409: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Unprocessable Entity */
422: {
headers: {
@@ -832,6 +931,81 @@ export interface paths {
patch?: never;
trace?: never;
};
"/{vendor}/{plugin}/{controller}/filters/{scope}/options": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* 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.
*/
get: {
parameters: {
query?: never;
header?: never;
path: {
/** @description Vendor */
vendor: string;
/** @description Plugin */
plugin: string;
/** @description Controller */
controller: string;
/** @description Filter name */
scope: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.Envelope-array_cabana_FilterOption"];
};
};
/** @description Unauthorized */
401: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Forbidden */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
};
};
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/{vendor}/{plugin}/{controller}/schema/form": {
parameters: {
query?: never;
@@ -1200,7 +1374,7 @@ export interface paths {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.SuccessEnvelope"];
"application/json": components["schemas"]["cabana.Envelope-cabana_BulkResult"];
};
};
/** @description Unauthorized */
@@ -1230,6 +1404,15 @@ export interface paths {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Unprocessable Entity */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
};
};
options?: never;
@@ -1271,7 +1454,7 @@ export interface paths {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.SuccessEnvelope"];
"application/json": components["schemas"]["cabana.ListEnvelope-array_cabana_AdminRecord"];
};
};
/** @description Unauthorized */
@@ -1292,6 +1475,24 @@ export interface paths {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Unprocessable Entity */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
};
};
put?: never;
@@ -1336,7 +1537,7 @@ export interface paths {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.SuccessEnvelope"];
"application/json": components["schemas"]["cabana.ListEnvelope-array_cabana_AdminRecord"];
};
};
/** @description Unauthorized */
@@ -1357,6 +1558,24 @@ export interface paths {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Unprocessable Entity */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
};
};
put?: never;
@@ -1403,7 +1622,7 @@ export interface paths {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.SuccessEnvelope"];
"application/json": components["schemas"]["cabana.Envelope-cabana_RelationMutationResult"];
};
};
/** @description Unauthorized */
@@ -1424,6 +1643,15 @@ export interface paths {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Unprocessable Entity */
422: {
headers: {
@@ -1477,7 +1705,7 @@ export interface paths {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.SuccessEnvelope"];
"application/json": components["schemas"]["cabana.Envelope-cabana_RelationMutationResult"];
};
};
/** @description Unauthorized */
@@ -1498,6 +1726,15 @@ export interface paths {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Not Found */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["cabana.ErrorEnvelope"];
};
};
/** @description Unprocessable Entity */
422: {
headers: {
@@ -1529,6 +1766,9 @@ export interface components {
login?: string;
password: string;
};
"cabana.AdminLogoutData": {
status: string;
};
"cabana.AdminProfile": {
email: string;
first_name: string;
@@ -1550,18 +1790,37 @@ export interface components {
label?: string;
name: string;
};
"cabana.BulkResult": {
deleted: number;
};
"cabana.Envelope-array_cabana_FilterOption": {
data: components["schemas"]["cabana.FilterOption"][];
meta: components["schemas"]["cabana.SuccessMeta"];
};
"cabana.Envelope-array_cabana_NavigationEntry": {
data: components["schemas"]["cabana.NavigationEntry"][];
meta: components["schemas"]["cabana.SuccessMeta"];
};
"cabana.Envelope-array_cabana_SettingsEntry": {
data: components["schemas"]["cabana.SettingsEntry"][];
meta: components["schemas"]["cabana.SuccessMeta"];
};
"cabana.Envelope-cabana_AdminLoginData": {
data: components["schemas"]["cabana.AdminLoginData"];
meta: components["schemas"]["cabana.SuccessMeta"];
};
"cabana.Envelope-cabana_AdminLogoutData": {
data: components["schemas"]["cabana.AdminLogoutData"];
meta: components["schemas"]["cabana.SuccessMeta"];
};
"cabana.Envelope-cabana_AdminProfile": {
data: components["schemas"]["cabana.AdminProfile"];
meta: components["schemas"]["cabana.SuccessMeta"];
};
"cabana.Envelope-cabana_BulkResult": {
data: components["schemas"]["cabana.BulkResult"];
meta: components["schemas"]["cabana.SuccessMeta"];
};
"cabana.Envelope-cabana_FormView": {
data: components["schemas"]["cabana.FormView"];
meta: components["schemas"]["cabana.SuccessMeta"];
@@ -1574,10 +1833,18 @@ export interface components {
data: components["schemas"]["cabana.ListSchema"];
meta: components["schemas"]["cabana.SuccessMeta"];
};
"cabana.Envelope-cabana_RelationMutationResult": {
data: components["schemas"]["cabana.RelationMutationResult"];
meta: components["schemas"]["cabana.SuccessMeta"];
};
"cabana.Envelope-cabana_RelationSchema": {
data: components["schemas"]["cabana.RelationSchema"];
meta: components["schemas"]["cabana.SuccessMeta"];
};
"cabana.Envelope-cabana_SettingsResult": {
data: components["schemas"]["cabana.SettingsResult"];
meta: components["schemas"]["cabana.SuccessMeta"];
};
"cabana.ErrorBody": {
code: string;
details: {
@@ -1588,6 +1855,10 @@ export interface components {
"cabana.ErrorEnvelope": {
error: components["schemas"]["cabana.ErrorBody"];
};
"cabana.FilterOption": {
label: string;
value: string;
};
"cabana.FormField": {
attributes?: {
[key: string]: components["schemas"]["cabana.jsonScalar"];
@@ -1766,6 +2037,10 @@ export interface components {
unlinkSelected: components["schemas"]["cabana.MessageForms"];
unlinked: components["schemas"]["cabana.MessageForms"];
};
"cabana.RelationMutationResult": {
linked?: number;
removed?: number;
};
"cabana.RelationOption": {
label: string;
value: number;
@@ -1791,9 +2066,21 @@ export interface components {
name: string;
url?: string;
};
"cabana.SuccessEnvelope": {
data: unknown;
meta: components["schemas"]["cabana.SuccessMeta"];
"cabana.SettingsEntry": {
category: string;
code: string;
description: string;
icon: string;
keywords: string[];
label: string;
model: string;
order: number;
};
"cabana.SettingsResult": {
data: {
[key: string]: unknown;
};
exists: boolean;
};
"cabana.SuccessMeta": {
last_page?: number;

View File

@@ -6,11 +6,33 @@ type Schemas = components['schemas']
export type AdminLoginData = Schemas['cabana.AdminLoginData']
export type AdminLoginRequest = Schemas['cabana.AdminLoginRequest']
export type AdminLogoutData = Schemas['cabana.AdminLogoutData']
export type AdminProfile = Schemas['cabana.AdminProfile']
export type NavigationEntry = Schemas['cabana.NavigationEntry']
export type SettingsEntry = Schemas['cabana.SettingsEntry']
export type SettingsResult = Schemas['cabana.SettingsResult']
export type ListSchema = Schemas['cabana.ListSchema']
export type ListColumn = Schemas['cabana.ListColumn']
export type ListFilter = Schemas['cabana.ListFilter']
export type ListMeta = Schemas['cabana.ListMeta']
export type ListMessages = Schemas['cabana.ListMessages']
export type FormView = Schemas['cabana.FormView']
export type FormField = Schemas['cabana.FormField']
export type FormOption = Schemas['cabana.FormOption']
export type FormMessages = Schemas['cabana.FormMessages']
export type FormRedirects = Schemas['cabana.FormRedirects']
export type RelationSchema = Schemas['cabana.RelationSchema']
export type RelationMessages = Schemas['cabana.RelationMessages']
export type RelationMutationResult = Schemas['cabana.RelationMutationResult']
export type RelationOption = Schemas['cabana.RelationOption']
export type FilterOption = Schemas['cabana.FilterOption']
export type RecordMeta = Schemas['cabana.RecordMeta']
export type RecordEnvelope = Schemas['cabana.RecordEnvelope']
export type BulkResult = Schemas['cabana.BulkResult']
/** One message as CLDR plural forms; "other" is always present (D-13). */
export type MessageForms = Schemas['cabana.MessageForms']
/** The public backend::lang bundle: full key to CLDR forms (D-20). */
export type LangBundle = Schemas['cabana.LangBundle']
export type ErrorEnvelope = Schemas['cabana.ErrorEnvelope']
/** One record: a string-keyed map read through its list or form schema. */
export type AdminRecord = Schemas['cabana.ListEnvelope-array_cabana_AdminRecord']['data'][number]
export type AdminRecord = Schemas['cabana.AdminRecord']

View File

@@ -1,5 +1,11 @@
@import "tailwindcss";
/* The generated API document and types carry prose, not classes: keep them
out of the class scan so an admin API change does not churn the built CSS
in boardwalk/dist (D-04 drift check). */
@source not "../api/schema.d.ts";
@source not "../../openapi";
/* Self-hosted fonts (D-07). Whole-weight files carry latin and latin-ext with
unicode-range, so Polish diacritics and basic Latin both resolve. */
@import "@fontsource/dm-sans/400.css";