fix(api): document request bodies for shared env create and update endpoints

Closes #12395

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2026-11-02 14:33:29 +01:00
co-authored by Claude Opus 5.5
parent 0b3ca79464
commit 6c650dd127
4 changed files with 296 additions and 62 deletions
@@ -12,6 +12,32 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use OpenApi\Attributes as OA;
#[OA\Schema(
schema: 'SharedEnvironmentVariableCreateRequest',
type: 'object',
required: ['key'],
properties: [
new OA\Property(property: 'key', type: 'string'),
new OA\Property(property: 'value', type: 'string', nullable: true),
new OA\Property(property: 'is_literal', type: 'boolean'),
new OA\Property(property: 'is_multiline', type: 'boolean'),
new OA\Property(property: 'is_shown_once', type: 'boolean', description: 'If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.'),
new OA\Property(property: 'comment', type: 'string', maxLength: 256, nullable: true),
],
)]
#[OA\Schema(
schema: 'SharedEnvironmentVariableUpdateRequest',
description: 'Send at least one field.',
type: 'object',
properties: [
new OA\Property(property: 'key', type: 'string'),
new OA\Property(property: 'value', type: 'string', nullable: true),
new OA\Property(property: 'is_literal', type: 'boolean'),
new OA\Property(property: 'is_multiline', type: 'boolean'),
new OA\Property(property: 'is_shown_once', type: 'boolean', description: 'If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.'),
new OA\Property(property: 'comment', type: 'string', maxLength: 256, nullable: true),
],
)]
class SharedEnvironmentVariablesController extends Controller
{
private const ALLOWED_FIELDS = ['key', 'value', 'is_literal', 'is_multiline', 'is_shown_once', 'comment'];
@@ -347,20 +373,7 @@ class SharedEnvironmentVariablesController extends Controller
operationId: 'create-team-shared-env',
security: [['bearerAuth' => []]],
tags: ['Shared Environment Variables'],
requestBody: new OA\RequestBody(
required: true,
content: new OA\JsonContent(
required: ['key'],
properties: [
new OA\Property(property: 'key', type: 'string'),
new OA\Property(property: 'value', type: 'string', nullable: true),
new OA\Property(property: 'is_literal', type: 'boolean'),
new OA\Property(property: 'is_multiline', type: 'boolean'),
new OA\Property(property: 'is_shown_once', type: 'boolean', description: 'If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.'),
new OA\Property(property: 'comment', type: 'string', nullable: true),
],
),
),
requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest')),
responses: [
new OA\Response(response: 201, description: 'Environment variable created.'),
new OA\Response(response: 401, ref: '#/components/responses/401'),
@@ -388,6 +401,7 @@ class SharedEnvironmentVariablesController extends Controller
parameters: [
new OA\Parameter(name: 'env_id', in: 'path', required: true, description: 'Shared env id (integer).', schema: new OA\Schema(type: 'integer')),
],
requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest')),
responses: [
new OA\Response(response: 200, description: 'Environment variable updated.'),
new OA\Response(response: 401, ref: '#/components/responses/401'),
@@ -476,6 +490,7 @@ class SharedEnvironmentVariablesController extends Controller
parameters: [
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'string')),
],
requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest')),
responses: [
new OA\Response(response: 201, description: 'Environment variable created.'),
new OA\Response(response: 401, ref: '#/components/responses/401'),
@@ -512,6 +527,7 @@ class SharedEnvironmentVariablesController extends Controller
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'string')),
new OA\Parameter(name: 'env_id', in: 'path', required: true, description: 'Shared env id (integer).', schema: new OA\Schema(type: 'integer')),
],
requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest')),
responses: [
new OA\Response(response: 200, description: 'Environment variable updated.'),
new OA\Response(response: 401, ref: '#/components/responses/401'),
@@ -633,6 +649,7 @@ class SharedEnvironmentVariablesController extends Controller
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'string')),
new OA\Parameter(name: 'environment_name_or_uuid', in: 'path', required: true, description: 'Environment name or UUID', schema: new OA\Schema(type: 'string')),
],
requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest')),
responses: [
new OA\Response(response: 201, description: 'Environment variable created.'),
new OA\Response(response: 401, ref: '#/components/responses/401'),
@@ -675,6 +692,7 @@ class SharedEnvironmentVariablesController extends Controller
new OA\Parameter(name: 'environment_name_or_uuid', in: 'path', required: true, description: 'Environment name or UUID', schema: new OA\Schema(type: 'string')),
new OA\Parameter(name: 'env_id', in: 'path', required: true, description: 'Shared env id (integer).', schema: new OA\Schema(type: 'integer')),
],
requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest')),
responses: [
new OA\Response(response: 200, description: 'Environment variable updated.'),
new OA\Response(response: 401, ref: '#/components/responses/401'),
@@ -800,6 +818,7 @@ class SharedEnvironmentVariablesController extends Controller
parameters: [
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server UUID', schema: new OA\Schema(type: 'string')),
],
requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest')),
responses: [
new OA\Response(response: 201, description: 'Environment variable created.'),
new OA\Response(response: 401, ref: '#/components/responses/401'),
@@ -836,6 +855,7 @@ class SharedEnvironmentVariablesController extends Controller
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server UUID', schema: new OA\Schema(type: 'string')),
new OA\Parameter(name: 'env_id', in: 'path', required: true, description: 'Shared env id (integer).', schema: new OA\Schema(type: 'integer')),
],
requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest')),
responses: [
new OA\Response(response: 200, description: 'Environment variable updated.'),
new OA\Response(response: 401, ref: '#/components/responses/401'),
+137 -31
View File
@@ -22230,37 +22230,7 @@
"content": {
"application\/json": {
"schema": {
"required": [
"key"
],
"properties": {
"key": {
"type": "string"
},
"value": {
"type": [
"string",
"null"
]
},
"is_literal": {
"type": "boolean"
},
"is_multiline": {
"type": "boolean"
},
"is_shown_once": {
"description": "If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.",
"type": "boolean"
},
"comment": {
"type": [
"string",
"null"
]
}
},
"type": "object"
"$ref": "#\/components\/schemas\/SharedEnvironmentVariableCreateRequest"
}
}
}
@@ -22340,6 +22310,16 @@
}
}
],
"requestBody": {
"required": true,
"content": {
"application\/json": {
"schema": {
"$ref": "#\/components\/schemas\/SharedEnvironmentVariableUpdateRequest"
}
}
}
},
"responses": {
"200": {
"description": "Environment variable updated."
@@ -22415,6 +22395,16 @@
}
}
],
"requestBody": {
"required": true,
"content": {
"application\/json": {
"schema": {
"$ref": "#\/components\/schemas\/SharedEnvironmentVariableCreateRequest"
}
}
}
},
"responses": {
"201": {
"description": "Environment variable created."
@@ -22511,6 +22501,16 @@
}
}
],
"requestBody": {
"required": true,
"content": {
"application\/json": {
"schema": {
"$ref": "#\/components\/schemas\/SharedEnvironmentVariableUpdateRequest"
}
}
}
},
"responses": {
"200": {
"description": "Environment variable updated."
@@ -22604,6 +22604,16 @@
}
}
],
"requestBody": {
"required": true,
"content": {
"application\/json": {
"schema": {
"$ref": "#\/components\/schemas\/SharedEnvironmentVariableCreateRequest"
}
}
}
},
"responses": {
"201": {
"description": "Environment variable created."
@@ -22718,6 +22728,16 @@
}
}
],
"requestBody": {
"required": true,
"content": {
"application\/json": {
"schema": {
"$ref": "#\/components\/schemas\/SharedEnvironmentVariableUpdateRequest"
}
}
}
},
"responses": {
"200": {
"description": "Environment variable updated."
@@ -22793,6 +22813,16 @@
}
}
],
"requestBody": {
"required": true,
"content": {
"application\/json": {
"schema": {
"$ref": "#\/components\/schemas\/SharedEnvironmentVariableCreateRequest"
}
}
}
},
"responses": {
"201": {
"description": "Environment variable created."
@@ -22889,6 +22919,16 @@
}
}
],
"requestBody": {
"required": true,
"content": {
"application\/json": {
"schema": {
"$ref": "#\/components\/schemas\/SharedEnvironmentVariableUpdateRequest"
}
}
}
},
"responses": {
"200": {
"description": "Environment variable updated."
@@ -24732,6 +24772,72 @@
},
"type": "object"
},
"SharedEnvironmentVariableCreateRequest": {
"required": [
"key"
],
"properties": {
"key": {
"type": "string"
},
"value": {
"type": [
"string",
"null"
]
},
"is_literal": {
"type": "boolean"
},
"is_multiline": {
"type": "boolean"
},
"is_shown_once": {
"description": "If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.",
"type": "boolean"
},
"comment": {
"type": [
"string",
"null"
],
"maxLength": 256
}
},
"type": "object"
},
"SharedEnvironmentVariableUpdateRequest": {
"description": "Send at least one field.",
"properties": {
"key": {
"type": "string"
},
"value": {
"type": [
"string",
"null"
]
},
"is_literal": {
"type": "boolean"
},
"is_multiline": {
"type": "boolean"
},
"is_shown_once": {
"description": "If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.",
"type": "boolean"
},
"comment": {
"type": [
"string",
"null"
],
"maxLength": 256
}
},
"type": "object"
},
"VolumeBackupScheduleRequest": {
"required": [
"frequency"
+88 -17
View File
@@ -14008,23 +14008,7 @@ paths:
content:
application/json:
schema:
required:
- key
properties:
key:
type: string
value:
type: [string, 'null']
is_literal:
type: boolean
is_multiline:
type: boolean
is_shown_once:
description: 'If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.'
type: boolean
comment:
type: [string, 'null']
type: object
$ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest'
responses:
'201':
description: 'Environment variable created.'
@@ -14076,6 +14060,12 @@ paths:
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest'
responses:
'200':
description: 'Environment variable updated.'
@@ -14127,6 +14117,12 @@ paths:
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest'
responses:
'201':
description: 'Environment variable created.'
@@ -14194,6 +14190,12 @@ paths:
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest'
responses:
'200':
description: 'Environment variable updated.'
@@ -14259,6 +14261,12 @@ paths:
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest'
responses:
'201':
description: 'Environment variable created.'
@@ -14340,6 +14348,12 @@ paths:
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest'
responses:
'200':
description: 'Environment variable updated.'
@@ -14391,6 +14405,12 @@ paths:
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest'
responses:
'201':
description: 'Environment variable created.'
@@ -14458,6 +14478,12 @@ paths:
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest'
responses:
'200':
description: 'Environment variable updated.'
@@ -15702,6 +15728,51 @@ components:
preview:
$ref: '#/components/schemas/ApplicationPreview'
type: object
SharedEnvironmentVariableCreateRequest:
required:
- key
properties:
key:
type: string
value:
type:
- string
- 'null'
is_literal:
type: boolean
is_multiline:
type: boolean
is_shown_once:
description: 'If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.'
type: boolean
comment:
type:
- string
- 'null'
maxLength: 256
type: object
SharedEnvironmentVariableUpdateRequest:
description: 'Send at least one field.'
properties:
key:
type: string
value:
type:
- string
- 'null'
is_literal:
type: boolean
is_multiline:
type: boolean
is_shown_once:
description: 'If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.'
type: boolean
comment:
type:
- string
- 'null'
maxLength: 256
type: object
VolumeBackupScheduleRequest:
required:
- frequency
@@ -0,0 +1,37 @@
<?php
function sharedEnvOpenApiSpec(): array
{
return json_decode(
file_get_contents(__DIR__.'/../../openapi.json'),
true,
flags: JSON_THROW_ON_ERROR,
);
}
it('documents a JSON request body on every shared env create and update endpoint', function (string $path, string $method, string $schemaName) {
$operation = sharedEnvOpenApiSpec()['paths'][$path][$method];
expect($operation['requestBody']['required'] ?? null)->toBeTrue()
->and($operation['requestBody']['content']['application/json']['schema']['$ref'] ?? null)
->toBe("#/components/schemas/{$schemaName}");
})->with([
['/team/envs', 'post', 'SharedEnvironmentVariableCreateRequest'],
['/team/envs/{env_id}', 'patch', 'SharedEnvironmentVariableUpdateRequest'],
['/projects/{uuid}/envs', 'post', 'SharedEnvironmentVariableCreateRequest'],
['/projects/{uuid}/envs/{env_id}', 'patch', 'SharedEnvironmentVariableUpdateRequest'],
['/projects/{uuid}/environments/{environment_name_or_uuid}/envs', 'post', 'SharedEnvironmentVariableCreateRequest'],
['/projects/{uuid}/environments/{environment_name_or_uuid}/envs/{env_id}', 'patch', 'SharedEnvironmentVariableUpdateRequest'],
['/servers/{uuid}/envs', 'post', 'SharedEnvironmentVariableCreateRequest'],
['/servers/{uuid}/envs/{env_id}', 'patch', 'SharedEnvironmentVariableUpdateRequest'],
]);
it('documents the fields accepted by the shared env validator', function () {
$schemas = sharedEnvOpenApiSpec()['components']['schemas'];
$fields = ['key', 'value', 'is_literal', 'is_multiline', 'is_shown_once', 'comment'];
expect(array_keys($schemas['SharedEnvironmentVariableCreateRequest']['properties']))->toBe($fields)
->and($schemas['SharedEnvironmentVariableCreateRequest']['required'])->toBe(['key'])
->and(array_keys($schemas['SharedEnvironmentVariableUpdateRequest']['properties']))->toBe($fields)
->and($schemas['SharedEnvironmentVariableUpdateRequest'])->not->toHaveKey('required');
});