feat(scenarios,environments): add markdown description field

- add optional description to scenario and environment entities
- expose description in create/update DTOs, MCP tools, and export DTOs
- render description as markdown on detail pages
- add description editor (CodeEditor) to create/edit forms for both resources
This commit is contained in:
2026-04-14 23:53:45 +03:00
parent 4dab218b75
commit e6aacc899d
20 changed files with 206 additions and 32 deletions
+39 -9
View File
@@ -181,15 +181,20 @@ export class McpService {
name: z
.string()
.describe("Unique environment name, e.g. liquio-diia-stg"),
description: z
.string()
.optional()
.describe("Optional markdown description"),
data: z
.record(z.string(), z.string())
.describe("Map of string keys to string values"),
},
},
async ({ name, data }) => {
async ({ name, description, data }) => {
try {
const env = await this.environmentService.create({
name,
description,
data: data as EnvironmentData,
});
return {
@@ -207,20 +212,26 @@ export class McpService {
server.registerTool(
"update_environment",
{
description: "Update an existing environment (name and/or data)",
description:
"Update an existing environment (name, description, and/or data)",
inputSchema: {
id: z.uuid().describe("Environment ID to update"),
name: z.string().optional().describe("New name"),
description: z
.string()
.optional()
.describe("New markdown description"),
data: z
.record(z.string(), z.string())
.optional()
.describe("New data map"),
},
},
async ({ id, name, data }) => {
async ({ id, name, description, data }) => {
try {
const env = await this.environmentService.update(id, {
name,
description,
data: data as EnvironmentData | undefined,
});
return {
@@ -457,11 +468,18 @@ export class McpService {
description: "Create a new scenario",
inputSchema: {
name: z.string().describe("Scenario name"),
description: z
.string()
.optional()
.describe("Optional markdown description"),
},
},
async ({ name }) => {
async ({ name, description }) => {
try {
const scenario = await this.scenarioService.create({ name });
const scenario = await this.scenarioService.create({
name,
description,
});
return {
content: [
{ type: "text" as const, text: JSON.stringify(scenario) },
@@ -479,15 +497,22 @@ export class McpService {
server.registerTool(
"update_scenario",
{
description: "Update a scenario name",
description: "Update a scenario name and/or description",
inputSchema: {
id: z.uuid().describe("Scenario ID"),
name: z.string().optional().describe("New name"),
description: z
.string()
.optional()
.describe("New markdown description"),
},
},
async ({ id, name }) => {
async ({ id, name, description }) => {
try {
const scenario = await this.scenarioService.update(id, { name });
const scenario = await this.scenarioService.update(id, {
name,
description,
});
return {
content: [
{ type: "text" as const, text: JSON.stringify(scenario) },
@@ -951,6 +976,10 @@ export class McpService {
"Import a scenario from an export payload, creating a new scenario with all its steps",
inputSchema: {
name: z.string().describe("Scenario name"),
description: z
.string()
.optional()
.describe("Optional markdown description"),
steps: z
.array(
z.object({
@@ -967,10 +996,11 @@ export class McpService {
.describe("Ordered list of steps"),
},
},
async ({ name, steps }) => {
async ({ name, description, steps }) => {
try {
const scenario = await this.scenarioService.importScenario({
name,
description,
steps: steps as Parameters<
typeof this.scenarioService.importScenario
>[0]["steps"],