@appaflytech/zeyrek-ai-mcp 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +46 -0
- package/README.md +260 -0
- package/dist/config.js +128 -0
- package/dist/index.js +88 -0
- package/dist/knowledge/componentCatalog.js +438 -0
- package/dist/knowledge/componentEvents.js +164 -0
- package/dist/knowledge/coverage.js +60 -0
- package/dist/knowledge/normalize.js +1309 -0
- package/dist/knowledge/outlines.js +167 -0
- package/dist/knowledge/policy.js +44 -0
- package/dist/knowledge/reservedTables.js +75 -0
- package/dist/knowledge/rules.js +1725 -0
- package/dist/observability/trace.js +337 -0
- package/dist/platform/errors.js +132 -0
- package/dist/platform/http.js +169 -0
- package/dist/platform/responses.js +94 -0
- package/dist/platform/token.js +79 -0
- package/dist/resources/examples/entity-pair-m2m.json +105 -0
- package/dist/resources/examples/flow-list-to-form.json +65 -0
- package/dist/resources/examples/flow-load-table.json +178 -0
- package/dist/resources/examples/microservice-table-list.json +49 -0
- package/dist/resources/examples/middleware-authenticate.json +194 -0
- package/dist/resources/examples/page-detail-profile.json +95 -0
- package/dist/resources/examples/page-dynamic-form.json +221 -0
- package/dist/resources/examples/page-form-upsert.json +279 -0
- package/dist/resources/examples/page-html-embed.json +106 -0
- package/dist/resources/examples/page-sign-in.json +194 -0
- package/dist/resources/examples/workflow-basic.json +94 -0
- package/dist/resources/guides/component.md +108 -0
- package/dist/resources/guides/entity.md +348 -0
- package/dist/resources/guides/expressions.md +139 -0
- package/dist/resources/guides/getting-started.md +109 -0
- package/dist/resources/guides/html.md +106 -0
- package/dist/resources/guides/microservice.md +313 -0
- package/dist/resources/guides/middleware.md +271 -0
- package/dist/resources/guides/modify-existing.md +35 -0
- package/dist/resources/guides/page.md +1574 -0
- package/dist/resources/guides/view.md +89 -0
- package/dist/resources/guides/workflow.md +359 -0
- package/dist/resources/knowledge.js +44 -0
- package/dist/resources/schemas/CreateDatasourceCommand.json +54 -0
- package/dist/resources/schemas/CreateDiscoveredEntitiesCommand.json +133 -0
- package/dist/resources/schemas/CreateEntityCommand.json +387 -0
- package/dist/resources/schemas/CreateMicroserviceCommand.json +528 -0
- package/dist/resources/schemas/CreateQueryCommand.json +43 -0
- package/dist/resources/schemas/CreateViewCommand.json +158 -0
- package/dist/resources/schemas/CreateWorkflowCommand.json +1719 -0
- package/dist/resources/schemas/Filter.json +124 -0
- package/dist/resources/schemas/GetRowsQuery.json +122 -0
- package/dist/resources/schemas/PreviewMicroserviceCommand.json +565 -0
- package/dist/resources/schemas/PreviewQueryCommand.json +74 -0
- package/dist/resources/schemas/PreviewWorkflowCommand.json +981 -0
- package/dist/resources/schemas/StepDto.json +900 -0
- package/dist/resources/schemas/UpdateDatasourceCommand.json +58 -0
- package/dist/resources/schemas/UpdateEntityCommand.json +679 -0
- package/dist/resources/schemas/UpdateMicroserviceCommand.json +512 -0
- package/dist/resources/schemas/UpdateQueryCommand.json +86 -0
- package/dist/resources/schemas/UpdateViewCommand.json +153 -0
- package/dist/resources/schemas/UpdateWorkflowCommand.json +1719 -0
- package/dist/resources/schemas.js +40 -0
- package/dist/server.js +63 -0
- package/dist/tools/access.js +27 -0
- package/dist/tools/applications.js +59 -0
- package/dist/tools/automations.js +103 -0
- package/dist/tools/common.js +18 -0
- package/dist/tools/components.js +280 -0
- package/dist/tools/datasources.js +82 -0
- package/dist/tools/dependencies.js +17 -0
- package/dist/tools/deployments.js +17 -0
- package/dist/tools/dtos.js +54 -0
- package/dist/tools/entities.js +166 -0
- package/dist/tools/files.js +138 -0
- package/dist/tools/flows.js +226 -0
- package/dist/tools/folders.js +51 -0
- package/dist/tools/layouts.js +105 -0
- package/dist/tools/microservices.js +198 -0
- package/dist/tools/organizations.js +65 -0
- package/dist/tools/pages.js +597 -0
- package/dist/tools/platformInfo.js +44 -0
- package/dist/tools/projects.js +152 -0
- package/dist/tools/queries.js +48 -0
- package/dist/tools/rows.js +115 -0
- package/dist/tools/screens.js +97 -0
- package/dist/tools/templates.js +65 -0
- package/dist/tools/variables.js +94 -0
- package/dist/tools/views.js +58 -0
- package/dist/tools/workflows.js +196 -0
- package/package.json +49 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { guid, projectParam, environmentParam, pagingParams, readOnly, writes, updates, destructive } from './common.js';
|
|
2
|
+
import { projectCoverageGaps } from '../knowledge/coverage.js';
|
|
3
|
+
import { handle } from '../platform/responses.js';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
function pick(entry, keys) {
|
|
6
|
+
if (!entry || typeof entry !== 'object')
|
|
7
|
+
return {};
|
|
8
|
+
return Object.fromEntries(keys
|
|
9
|
+
.map(key => [key, entry[key]])
|
|
10
|
+
.filter(([, value]) => value !== undefined && value !== null));
|
|
11
|
+
}
|
|
12
|
+
function rows(payload) {
|
|
13
|
+
const data = payload?.data;
|
|
14
|
+
return Array.isArray(data) ? data : [];
|
|
15
|
+
}
|
|
16
|
+
const applicationInput = z.object({
|
|
17
|
+
slug: z.string().min(1),
|
|
18
|
+
name: z.string().min(1),
|
|
19
|
+
color: z.string().optional(),
|
|
20
|
+
dns: z.string().optional(),
|
|
21
|
+
type: z.string().optional().describe('ApplicationType; varsayılan Web')
|
|
22
|
+
});
|
|
23
|
+
const templateOptionsInput = z.object({
|
|
24
|
+
templateId: guid,
|
|
25
|
+
templateReceiveUpdates: z.boolean().optional()
|
|
26
|
+
});
|
|
27
|
+
export function registerProjectTools(server, platform) {
|
|
28
|
+
const config = platform.config;
|
|
29
|
+
server.registerTool('project_list', {
|
|
30
|
+
title: 'Projeleri listele',
|
|
31
|
+
description: 'Organizasyondaki projeleri arar ve sayfalı listeler.',
|
|
32
|
+
inputSchema: { searchTerm: z.string().optional(), ...pagingParams },
|
|
33
|
+
annotations: readOnly
|
|
34
|
+
}, handle(config, args => platform.org('GET', '/projects', { query: args })));
|
|
35
|
+
server.registerTool('project_get', {
|
|
36
|
+
title: 'Proje getir',
|
|
37
|
+
description: 'Tek projeyi id ya da slug ile getirir; environment listesi de yanıttadır.',
|
|
38
|
+
inputSchema: { id: guid.optional(), slug: z.string().optional().describe('id verilmediyse zorunlu') },
|
|
39
|
+
annotations: readOnly
|
|
40
|
+
}, handle(config, args => {
|
|
41
|
+
if (args.id)
|
|
42
|
+
return platform.org('GET', `/projects/${args.id}`);
|
|
43
|
+
if (args.slug)
|
|
44
|
+
return platform.org('GET', `/p/${args.slug}`);
|
|
45
|
+
throw new Error("'id' ya da 'slug' parametrelerinden biri zorunlu.");
|
|
46
|
+
}));
|
|
47
|
+
server.registerTool('project_create', {
|
|
48
|
+
title: 'Proje oluştur',
|
|
49
|
+
description: "Yeni proje oluşturur. templateOptions verilmezse 'application' zorunludur (ilk application projeyle birlikte açılır). LoaderImage bu tool'da desteklenmez.",
|
|
50
|
+
inputSchema: {
|
|
51
|
+
name: z.string().min(1),
|
|
52
|
+
slug: z.string().min(1),
|
|
53
|
+
theme: z.string().optional().describe('Tema JSON\'u string olarak'),
|
|
54
|
+
application: applicationInput.optional(),
|
|
55
|
+
templateOptions: templateOptionsInput.optional().describe('Verilirse proje template\'ten kurulur (asenkron); sonucu project_list ile izleyin')
|
|
56
|
+
},
|
|
57
|
+
annotations: writes
|
|
58
|
+
}, handle(config, args => {
|
|
59
|
+
const form = new URLSearchParams({ Name: args.name, Slug: args.slug });
|
|
60
|
+
if (args.theme)
|
|
61
|
+
form.set('Theme', args.theme);
|
|
62
|
+
if (args.application) {
|
|
63
|
+
form.set('Application.Slug', args.application.slug);
|
|
64
|
+
form.set('Application.Name', args.application.name);
|
|
65
|
+
if (args.application.color)
|
|
66
|
+
form.set('Application.Color', args.application.color);
|
|
67
|
+
if (args.application.dns)
|
|
68
|
+
form.set('Application.Dns', args.application.dns);
|
|
69
|
+
if (args.application.type)
|
|
70
|
+
form.set('Application.Type', args.application.type);
|
|
71
|
+
}
|
|
72
|
+
if (args.templateOptions) {
|
|
73
|
+
form.set('TemplateOptions.TemplateId', args.templateOptions.templateId);
|
|
74
|
+
if (args.templateOptions.templateReceiveUpdates !== undefined) {
|
|
75
|
+
form.set('TemplateOptions.TemplateReceiveUpdates', String(args.templateOptions.templateReceiveUpdates));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return platform.org('POST', '/projects', { form });
|
|
79
|
+
}));
|
|
80
|
+
server.registerTool('project_update', {
|
|
81
|
+
title: 'Proje güncelle',
|
|
82
|
+
description: 'Proje adını, slug\'ını ve temasını günceller. LoaderImage bu tool\'da desteklenmez.',
|
|
83
|
+
inputSchema: {
|
|
84
|
+
id: guid,
|
|
85
|
+
name: z.string().min(1),
|
|
86
|
+
slug: z.string().optional(),
|
|
87
|
+
theme: z.string().optional()
|
|
88
|
+
},
|
|
89
|
+
annotations: updates
|
|
90
|
+
}, handle(config, args => {
|
|
91
|
+
const form = new URLSearchParams({ Name: args.name });
|
|
92
|
+
if (args.slug)
|
|
93
|
+
form.set('Slug', args.slug);
|
|
94
|
+
if (args.theme)
|
|
95
|
+
form.set('Theme', args.theme);
|
|
96
|
+
return platform.org('PUT', `/projects/${args.id}`, { form });
|
|
97
|
+
}));
|
|
98
|
+
server.registerTool('project_delete', {
|
|
99
|
+
title: 'Proje sil',
|
|
100
|
+
description: 'Projeyi tüm environment\'larıyla birlikte kalıcı olarak siler.',
|
|
101
|
+
inputSchema: { id: guid },
|
|
102
|
+
annotations: destructive
|
|
103
|
+
}, handle(config, args => platform.org('DELETE', `/projects/${args.id}`)));
|
|
104
|
+
server.registerTool('project_overview', {
|
|
105
|
+
title: 'Proje haritası',
|
|
106
|
+
description: 'Projenin kompakt envanteri: application\'lar, datasource+entity ağacı, microservice/workflow/query/SAYFA listeleri (yalnız id/ad/tip) + tutarlılık boşlukları (coverageGaps: kimlik var ama giriş sayfası yok, yazma ucu var ama sayfa yok). Var olan bir projede çalışmaya HER ZAMAN buradan başlayın; detay için ilgili *_get tool\'unu kullanın.',
|
|
107
|
+
inputSchema: { project: projectParam, environment: environmentParam },
|
|
108
|
+
annotations: readOnly
|
|
109
|
+
}, handle(config, async ({ project, environment }) => {
|
|
110
|
+
const projectSlug = platform.resolveProject(project);
|
|
111
|
+
const projectPayload = await platform.org('GET', `/p/${projectSlug}`);
|
|
112
|
+
const projectData = (projectPayload?.data ?? {});
|
|
113
|
+
const applicationsPayload = projectData.id
|
|
114
|
+
? await platform.org('GET', '/applications', { query: { projectId: projectData.id, pageLength: 100 } })
|
|
115
|
+
: { data: [] };
|
|
116
|
+
const datasourceTreePayload = await platform.tenant('GET', projectSlug, '/datasources/tree', { environment });
|
|
117
|
+
const queriesPayload = await platform.tenant('GET', projectSlug, '/queries', { environment, query: { pageLength: 200 } });
|
|
118
|
+
const applications = [];
|
|
119
|
+
for (const applicationEntry of rows(applicationsPayload)) {
|
|
120
|
+
const applicationId = applicationEntry.id;
|
|
121
|
+
const [microservicesPayload, workflowsPayload, pagesPayload] = await Promise.all([
|
|
122
|
+
platform.tenant('GET', projectSlug, `/microservices/${applicationId}`, { environment, query: { pageLength: 200 } }).catch(() => undefined),
|
|
123
|
+
platform.tenant('GET', projectSlug, `/workflows/${applicationId}`, { environment, query: { pageLength: 200 } }).catch(() => undefined),
|
|
124
|
+
platform.tenant('GET', projectSlug, `/pages/${applicationId}`, { environment, query: { pageIndex: 0, pageLength: 200 } }).catch(() => undefined)
|
|
125
|
+
]);
|
|
126
|
+
const microservices = rows(microservicesPayload).map(entry => pick(entry, ['id', 'slug', 'name', 'type', 'httpMethod', 'source', 'entityId', 'workflowId']));
|
|
127
|
+
const workflows = rows(workflowsPayload).map(entry => pick(entry, ['id', 'slug', 'name', 'type', 'entityId']));
|
|
128
|
+
const pages = rows(pagesPayload).map(entry => pick(entry, ['id', 'slug', 'name']));
|
|
129
|
+
const gaps = projectCoverageGaps({ pages, microservices, workflows });
|
|
130
|
+
applications.push({
|
|
131
|
+
...pick(applicationEntry, ['id', 'slug', 'name', 'type']),
|
|
132
|
+
microservices,
|
|
133
|
+
workflows,
|
|
134
|
+
pages,
|
|
135
|
+
...(gaps.length > 0 ? { coverageGaps: gaps } : {})
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
project: pick(projectData, ['id', 'slug', 'name']),
|
|
140
|
+
environments: (Array.isArray(projectData.environments) ? projectData.environments : []).map(entry => pick(entry, ['id', 'name'])),
|
|
141
|
+
environment: platform.resolveEnvironment(environment),
|
|
142
|
+
applications,
|
|
143
|
+
datasources: rows(datasourceTreePayload).map(datasourceEntry => ({
|
|
144
|
+
...pick(datasourceEntry, ['id', 'name', 'type']),
|
|
145
|
+
entities: (Array.isArray(datasourceEntry.entities) ? datasourceEntry.entities : [])
|
|
146
|
+
.map(entry => pick(entry, ['id', 'slug', 'name']))
|
|
147
|
+
})),
|
|
148
|
+
queries: rows(queriesPayload).map(entry => pick(entry, ['id', 'name', 'datasourceId'])),
|
|
149
|
+
hint: 'Detay: entity_get/microservice_get/workflow_get (büyük kayıtlarda view:\'outline\'); değişiklik: *_patch.'
|
|
150
|
+
};
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { guid, projectParam, environmentParam, definitionParam, pagingParams, readOnly, writes, updates, destructive } from './common.js';
|
|
2
|
+
import { handle } from '../platform/responses.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
export function registerQueryTools(server, platform) {
|
|
5
|
+
const config = platform.config;
|
|
6
|
+
server.registerTool('query_list', {
|
|
7
|
+
title: 'Query listele',
|
|
8
|
+
description: 'Projedeki query tanımlarını listeler.',
|
|
9
|
+
inputSchema: { project: projectParam, environment: environmentParam, searchTerm: z.string().optional(), ...pagingParams },
|
|
10
|
+
annotations: readOnly
|
|
11
|
+
}, handle(config, ({ project, environment, ...query }) => platform.tenant('GET', project, '/queries', { environment, query })));
|
|
12
|
+
server.registerTool('query_get', {
|
|
13
|
+
title: 'Query getir',
|
|
14
|
+
description: 'Tek query tanımını getirir; query_create için en iyi gövde şablonudur.',
|
|
15
|
+
inputSchema: { project: projectParam, environment: environmentParam, id: guid },
|
|
16
|
+
annotations: readOnly
|
|
17
|
+
}, handle(config, ({ project, environment, id }) => platform.tenant('GET', project, `/queries/${id}`, { environment })));
|
|
18
|
+
server.registerTool('query_create', {
|
|
19
|
+
title: 'Query oluştur',
|
|
20
|
+
description: 'Yeni query tanımlar. definition = CreateQueryCommand gövdesi.',
|
|
21
|
+
inputSchema: { project: projectParam, environment: environmentParam, definition: definitionParam },
|
|
22
|
+
annotations: writes
|
|
23
|
+
}, handle(config, ({ project, environment, definition }) => platform.tenant('POST', project, '/queries', { environment, body: definition })));
|
|
24
|
+
server.registerTool('query_update', {
|
|
25
|
+
title: 'Query güncelle',
|
|
26
|
+
description: 'Query tanımını günceller. definition = UpdateQueryCommand gövdesi.',
|
|
27
|
+
inputSchema: { project: projectParam, environment: environmentParam, id: guid, definition: definitionParam },
|
|
28
|
+
annotations: updates
|
|
29
|
+
}, handle(config, ({ project, environment, id, definition }) => platform.tenant('PUT', project, `/queries/${id}`, { environment, body: definition })));
|
|
30
|
+
server.registerTool('query_delete', {
|
|
31
|
+
title: 'Query sil',
|
|
32
|
+
description: 'Query tanımını siler.',
|
|
33
|
+
inputSchema: { project: projectParam, environment: environmentParam, id: guid },
|
|
34
|
+
annotations: destructive
|
|
35
|
+
}, handle(config, ({ project, environment, id }) => platform.tenant('DELETE', project, `/queries/${id}`, { environment })));
|
|
36
|
+
server.registerTool('query_clone', {
|
|
37
|
+
title: 'Query klonla',
|
|
38
|
+
description: 'Query\'nin kopyasını oluşturur.',
|
|
39
|
+
inputSchema: { project: projectParam, environment: environmentParam, id: guid },
|
|
40
|
+
annotations: writes
|
|
41
|
+
}, handle(config, ({ project, environment, id }) => platform.tenant('POST', project, `/queries/${id}/clone`, { environment })));
|
|
42
|
+
server.registerTool('query_preview', {
|
|
43
|
+
title: 'Query önizle',
|
|
44
|
+
description: 'Kaydedilmemiş query tanımını datasource üzerinde çalıştırır. definition = PreviewQueryCommand gövdesi.',
|
|
45
|
+
inputSchema: { project: projectParam, environment: environmentParam, datasourceId: guid, definition: definitionParam },
|
|
46
|
+
annotations: writes
|
|
47
|
+
}, handle(config, ({ project, environment, datasourceId, definition }) => platform.tenant('POST', project, `/queries/${datasourceId}/preview`, { environment, body: definition })));
|
|
48
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { guid, projectParam, environmentParam, pagingParams, readOnly, writes, updates, destructive } from './common.js';
|
|
2
|
+
import { handle } from '../platform/responses.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
const rowValues = z.record(z.unknown()).describe("Alan SLUG'ı → değer sözlüğü; anahtarlar entity_get çıktısındaki field SLUG'larıdır (name değil — name kullanmak 'Please enter a valid value' hatası verir)");
|
|
5
|
+
export function registerRowTools(server, platform) {
|
|
6
|
+
const config = platform.config;
|
|
7
|
+
server.registerTool('row_list', {
|
|
8
|
+
title: 'Satırları listele',
|
|
9
|
+
description: 'Entity satırlarını filtre/sıralama/sayfalama ile listeler; selectedFields verilirse satırlar bu alanlara indirgenir (id her zaman dahil).',
|
|
10
|
+
inputSchema: {
|
|
11
|
+
project: projectParam,
|
|
12
|
+
environment: environmentParam,
|
|
13
|
+
entityId: guid,
|
|
14
|
+
selectedFields: z.array(z.string()).optional().describe('Dönen satırlar bu alan adlarına indirgenir, id her zaman dahildir; platform tam satırı hesapladığı için kırpma gateway tarafında yapılır'),
|
|
15
|
+
filters: z.array(z.record(z.unknown())).optional().describe('Platform Filter dizisi; biçim için row_list\'i filtresiz çağırıp Studio\'daki bir filtreyi referans alın'),
|
|
16
|
+
...pagingParams
|
|
17
|
+
},
|
|
18
|
+
annotations: readOnly
|
|
19
|
+
}, handle(config, async ({ project, environment, entityId, ...body }) => {
|
|
20
|
+
const payload = await platform.tenant('POST', project, `/entities/${entityId}/row/list`, { environment, body });
|
|
21
|
+
const wanted = body.selectedFields ?? [];
|
|
22
|
+
if (!wanted.length || !payload || typeof payload !== 'object' || Array.isArray(payload))
|
|
23
|
+
return payload;
|
|
24
|
+
const rows = payload.data;
|
|
25
|
+
if (!Array.isArray(rows))
|
|
26
|
+
return payload;
|
|
27
|
+
const keep = new Set([...wanted.map(field => field.toLowerCase()), 'id']);
|
|
28
|
+
return {
|
|
29
|
+
...payload,
|
|
30
|
+
data: rows.map(row => row && typeof row === 'object' && !Array.isArray(row)
|
|
31
|
+
? Object.fromEntries(Object.entries(row).filter(([key]) => keep.has(key.toLowerCase())))
|
|
32
|
+
: row)
|
|
33
|
+
};
|
|
34
|
+
}));
|
|
35
|
+
server.registerTool('row_get', {
|
|
36
|
+
title: 'Satır getir',
|
|
37
|
+
description: 'Tek satırı id ile getirir.',
|
|
38
|
+
inputSchema: { project: projectParam, environment: environmentParam, entityId: guid, id: z.string().min(1) },
|
|
39
|
+
annotations: readOnly
|
|
40
|
+
}, handle(config, ({ project, environment, entityId, id }) => platform.tenant('GET', project, `/entities/${entityId}/row/${encodeURIComponent(id)}`, { environment })));
|
|
41
|
+
server.registerTool('row_create', {
|
|
42
|
+
title: 'Satır ekle',
|
|
43
|
+
description: "Tek satır için 'row', çoklu ekleme için 'rows' verin (ikisi birden verilmez).",
|
|
44
|
+
inputSchema: {
|
|
45
|
+
project: projectParam,
|
|
46
|
+
environment: environmentParam,
|
|
47
|
+
entityId: guid,
|
|
48
|
+
row: rowValues.optional(),
|
|
49
|
+
rows: z.array(z.record(z.unknown())).optional()
|
|
50
|
+
},
|
|
51
|
+
annotations: writes
|
|
52
|
+
}, handle(config, ({ project, environment, entityId, row, rows }) => {
|
|
53
|
+
if (row && rows)
|
|
54
|
+
throw new Error("'row' ve 'rows' birlikte verilemez.");
|
|
55
|
+
if (rows)
|
|
56
|
+
return platform.tenant('POST', project, `/entities/${entityId}/row/bulk`, { environment, body: { rows } });
|
|
57
|
+
if (row)
|
|
58
|
+
return platform.tenant('POST', project, `/entities/${entityId}/row`, { environment, body: { row } });
|
|
59
|
+
throw new Error("'row' ya da 'rows' parametrelerinden biri zorunlu.");
|
|
60
|
+
}));
|
|
61
|
+
server.registerTool('row_update', {
|
|
62
|
+
title: 'Satır güncelle',
|
|
63
|
+
description: "Tek satır için 'row', çoklu güncelleme için 'rows' verin; satır id alanı gövdede olmalıdır.",
|
|
64
|
+
inputSchema: {
|
|
65
|
+
project: projectParam,
|
|
66
|
+
environment: environmentParam,
|
|
67
|
+
entityId: guid,
|
|
68
|
+
row: rowValues.optional(),
|
|
69
|
+
rows: z.array(z.record(z.unknown())).optional()
|
|
70
|
+
},
|
|
71
|
+
annotations: updates
|
|
72
|
+
}, handle(config, ({ project, environment, entityId, row, rows }) => {
|
|
73
|
+
if (row && rows)
|
|
74
|
+
throw new Error("'row' ve 'rows' birlikte verilemez.");
|
|
75
|
+
if (rows)
|
|
76
|
+
return platform.tenant('PUT', project, `/entities/${entityId}/row/bulk`, { environment, body: { rows } });
|
|
77
|
+
if (row)
|
|
78
|
+
return platform.tenant('PUT', project, `/entities/${entityId}/row`, { environment, body: { row } });
|
|
79
|
+
throw new Error("'row' ya da 'rows' parametrelerinden biri zorunlu.");
|
|
80
|
+
}));
|
|
81
|
+
server.registerTool('row_delete', {
|
|
82
|
+
title: 'Satır sil',
|
|
83
|
+
description: "Tek satır için 'id', çoklu silme için 'ids' verin.",
|
|
84
|
+
inputSchema: {
|
|
85
|
+
project: projectParam,
|
|
86
|
+
environment: environmentParam,
|
|
87
|
+
entityId: guid,
|
|
88
|
+
id: z.string().optional(),
|
|
89
|
+
ids: z.array(z.union([z.string(), z.number()])).optional()
|
|
90
|
+
},
|
|
91
|
+
annotations: destructive
|
|
92
|
+
}, handle(config, ({ project, environment, entityId, id, ids }) => {
|
|
93
|
+
if (id && ids)
|
|
94
|
+
throw new Error("'id' ve 'ids' birlikte verilemez.");
|
|
95
|
+
if (ids)
|
|
96
|
+
return platform.tenant('POST', project, `/entities/${entityId}/row/bulk/delete`, { environment, body: { rowIds: ids } });
|
|
97
|
+
if (id)
|
|
98
|
+
return platform.tenant('DELETE', project, `/entities/${entityId}/row/${encodeURIComponent(id)}`, { environment });
|
|
99
|
+
throw new Error("'id' ya da 'ids' parametrelerinden biri zorunlu.");
|
|
100
|
+
}));
|
|
101
|
+
server.registerTool('row_next_code', {
|
|
102
|
+
title: 'Sıradaki kodu üret',
|
|
103
|
+
description: 'Incremental tipli alan için sıradaki kodu döner.',
|
|
104
|
+
inputSchema: {
|
|
105
|
+
project: projectParam,
|
|
106
|
+
environment: environmentParam,
|
|
107
|
+
entityId: guid,
|
|
108
|
+
fieldId: guid,
|
|
109
|
+
prefix: z.string().optional(),
|
|
110
|
+
separator: z.string().optional(),
|
|
111
|
+
digitCount: z.number().int().optional()
|
|
112
|
+
},
|
|
113
|
+
annotations: readOnly
|
|
114
|
+
}, handle(config, ({ project, environment, entityId, ...body }) => platform.tenant('POST', project, `/entities/${entityId}/row/next-code`, { environment, body })));
|
|
115
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { PlatformApiError } from '../platform/errors.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export const hostParam = z.enum(['page', 'layout', 'component'])
|
|
4
|
+
.describe("Akışın barındırıcısı: page | layout | component (widget de component'tir)");
|
|
5
|
+
export const schemaParam = z.array(z.record(z.unknown()))
|
|
6
|
+
.describe('Komponent ağacı (DesignComponentManagementSchema listesi); verilmezse mevcut şema korunur');
|
|
7
|
+
export const eventsParam = z.array(z.record(z.unknown()))
|
|
8
|
+
.describe("Sayfa/layout düzeyi olaylar: [{ name, value }] — value bir flow id'sidir");
|
|
9
|
+
function asArray(value) {
|
|
10
|
+
return Array.isArray(value) ? value : [];
|
|
11
|
+
}
|
|
12
|
+
function identifiers(value) {
|
|
13
|
+
return asArray(value)
|
|
14
|
+
.map(entry => (entry && typeof entry === 'object' ? entry.id : entry))
|
|
15
|
+
.filter((id) => typeof id === 'string');
|
|
16
|
+
}
|
|
17
|
+
export function unwrap(payload) {
|
|
18
|
+
const data = payload?.data;
|
|
19
|
+
return ((data ?? payload) ?? {});
|
|
20
|
+
}
|
|
21
|
+
export function hostPath(host, applicationId, hostId) {
|
|
22
|
+
if (host === 'page')
|
|
23
|
+
return `/pages/${applicationId}/${hostId}`;
|
|
24
|
+
if (host === 'layout')
|
|
25
|
+
return `/layouts/${applicationId}/${hostId}`;
|
|
26
|
+
return `/components/${applicationId}/${hostId}`;
|
|
27
|
+
}
|
|
28
|
+
export function flowPath(host, applicationId, hostId, flowId) {
|
|
29
|
+
const root = host === 'page'
|
|
30
|
+
? `/pages/${hostId}/flows`
|
|
31
|
+
: host === 'layout'
|
|
32
|
+
? `/layouts/${hostId}/flows`
|
|
33
|
+
: `/components/${applicationId}/${hostId}/flows`;
|
|
34
|
+
return flowId ? `${root}/${flowId}` : root;
|
|
35
|
+
}
|
|
36
|
+
export function pageUpdateBody(page, overrides = {}) {
|
|
37
|
+
const layout = (page.layout ?? {});
|
|
38
|
+
return {
|
|
39
|
+
id: page.id,
|
|
40
|
+
applicationId: page.applicationId,
|
|
41
|
+
name: page.name,
|
|
42
|
+
slug: page.slug,
|
|
43
|
+
browserTitle: page.browserTitle ?? '',
|
|
44
|
+
schema: page.schema ?? [],
|
|
45
|
+
events: asArray(page.events).filter(event => event?.value),
|
|
46
|
+
middlewareIds: page.middlewareIds ?? [],
|
|
47
|
+
roleIds: Array.isArray(page.roleIds) ? page.roleIds : identifiers(page.roles),
|
|
48
|
+
layoutId: page.layoutId ?? layout.id ?? null,
|
|
49
|
+
...overrides
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export function layoutUpdateBody(layout, overrides = {}) {
|
|
53
|
+
return {
|
|
54
|
+
id: layout.id,
|
|
55
|
+
applicationId: layout.applicationId,
|
|
56
|
+
name: layout.name,
|
|
57
|
+
parameters: layout.parameters ?? null,
|
|
58
|
+
views: layout.views ?? [],
|
|
59
|
+
events: asArray(layout.events).filter(event => event?.value),
|
|
60
|
+
...overrides
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export function componentUpdateBody(component, overrides = {}) {
|
|
64
|
+
return {
|
|
65
|
+
applicationId: component.applicationId,
|
|
66
|
+
type: component.type ?? 'web',
|
|
67
|
+
widgetType: component.widgetType ?? null,
|
|
68
|
+
slug: component.slug,
|
|
69
|
+
name: component.name,
|
|
70
|
+
description: component.description ?? '',
|
|
71
|
+
icon: component.icon ?? '',
|
|
72
|
+
categories: component.categories ?? [],
|
|
73
|
+
definition: component.definition ?? {},
|
|
74
|
+
schema: component.schema ?? [],
|
|
75
|
+
isHide: component.isHide ?? false,
|
|
76
|
+
isDroppable: component.isDroppable ?? false,
|
|
77
|
+
isSticky: component.isSticky ?? false,
|
|
78
|
+
isDeletable: component.isDeletable ?? true,
|
|
79
|
+
isDefaultAutoHeight: component.isDefaultAutoHeight ?? false,
|
|
80
|
+
...overrides
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
export async function fetchHost(platform, host, project, environment, applicationId, hostId) {
|
|
84
|
+
const payload = await platform.tenant('GET', project, hostPath(host, applicationId, hostId), { environment });
|
|
85
|
+
const record = unwrap(payload);
|
|
86
|
+
if (!record.id) {
|
|
87
|
+
throw new PlatformApiError(`${host} kaydı okunamadı (${hostId}); id doğru mu, application eşleşiyor mu kontrol edin.`);
|
|
88
|
+
}
|
|
89
|
+
return record;
|
|
90
|
+
}
|
|
91
|
+
export function hostUpdateBody(host, record, overrides = {}) {
|
|
92
|
+
if (host === 'page')
|
|
93
|
+
return pageUpdateBody(record, overrides);
|
|
94
|
+
if (host === 'layout')
|
|
95
|
+
return layoutUpdateBody(record, overrides);
|
|
96
|
+
return componentUpdateBody(record, overrides);
|
|
97
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { guid, pagingParams, readOnly, writes, updates } from './common.js';
|
|
2
|
+
import { handle } from '../platform/responses.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
export function registerTemplateTools(server, platform) {
|
|
5
|
+
const config = platform.config;
|
|
6
|
+
server.registerTool('template_list', {
|
|
7
|
+
title: 'Şablonları listele',
|
|
8
|
+
description: "Organizasyonun proje şablonlarını listeler. project_create'in templateOptions.templateId parametresi buradan gelir.",
|
|
9
|
+
inputSchema: {
|
|
10
|
+
searchTerm: z.string().optional(),
|
|
11
|
+
sourceModule: z.string().optional().describe("Module filtresi, ör. 'project'"),
|
|
12
|
+
...pagingParams
|
|
13
|
+
},
|
|
14
|
+
annotations: readOnly
|
|
15
|
+
}, handle(config, query => platform.org('GET', '/templates', { query })));
|
|
16
|
+
server.registerTool('template_get', {
|
|
17
|
+
title: 'Şablon getir',
|
|
18
|
+
description: 'Tek şablonun künyesini getirir (sürüm, changelog, görseller).',
|
|
19
|
+
inputSchema: { id: guid },
|
|
20
|
+
annotations: readOnly
|
|
21
|
+
}, handle(config, ({ id }) => platform.org('GET', `/templates/${id}`)));
|
|
22
|
+
server.registerTool('template_items', {
|
|
23
|
+
title: 'Şablon içeriğini listele',
|
|
24
|
+
description: "Şablonun bir modüldeki kayıtlarını listeler (project_create'in templateOptions.filters'ını doldurmak için).",
|
|
25
|
+
inputSchema: {
|
|
26
|
+
id: guid,
|
|
27
|
+
module: z.string().describe("Module değeri: entity | microservice | workflow | page | layout | component | query | view …")
|
|
28
|
+
},
|
|
29
|
+
annotations: readOnly
|
|
30
|
+
}, handle(config, ({ id, module }) => platform.org('GET', `/templates/${id}/items`, { query: { module } })));
|
|
31
|
+
server.registerTool('template_create', {
|
|
32
|
+
title: 'Projeyi şablon olarak yayımla',
|
|
33
|
+
description: 'Mevcut projeden yeni bir şablon sürümü üretir. Görsel yükleme bu tool\'da desteklenmez (ikili aktarım kapsam dışı).',
|
|
34
|
+
inputSchema: {
|
|
35
|
+
projectId: guid,
|
|
36
|
+
name: z.string().min(1),
|
|
37
|
+
version: z.string().min(1).describe("Sürüm etiketi, ör. '1.0.0'"),
|
|
38
|
+
description: z.string().optional(),
|
|
39
|
+
changeLog: z.string().optional(),
|
|
40
|
+
environmentId: guid.optional().describe('Hangi environment\'ın içeriği paketlenecek; boşsa varsayılan')
|
|
41
|
+
},
|
|
42
|
+
annotations: writes
|
|
43
|
+
}, handle(config, ({ projectId, name, version, description, changeLog, environmentId }) => {
|
|
44
|
+
const form = new URLSearchParams({ Name: name, Version: version });
|
|
45
|
+
if (description)
|
|
46
|
+
form.set('Description', description);
|
|
47
|
+
if (changeLog)
|
|
48
|
+
form.set('ChangeLog', changeLog);
|
|
49
|
+
if (environmentId)
|
|
50
|
+
form.set('EnvironmentId', environmentId);
|
|
51
|
+
return platform.org('POST', `/projects/${projectId}/templates`, { form });
|
|
52
|
+
}));
|
|
53
|
+
server.registerTool('template_check_updates', {
|
|
54
|
+
title: 'Şablon güncellemesi var mı',
|
|
55
|
+
description: 'Şablondan kurulmuş projenin kaynak şablonunda yeni sürüm var mı kontrol eder.',
|
|
56
|
+
inputSchema: { projectId: guid },
|
|
57
|
+
annotations: readOnly
|
|
58
|
+
}, handle(config, ({ projectId }) => platform.org('GET', `/projects/${projectId}/templates/check-for-updates`)));
|
|
59
|
+
server.registerTool('template_receive_updates', {
|
|
60
|
+
title: 'Şablon güncellemelerini al',
|
|
61
|
+
description: 'Kaynak şablondaki güncellemeleri projeye uygular; önce template_check_updates ile neyin geleceğini görün. Proje içeriğini değiştirir.',
|
|
62
|
+
inputSchema: { projectId: guid },
|
|
63
|
+
annotations: updates
|
|
64
|
+
}, handle(config, ({ projectId }) => platform.org('POST', `/projects/${projectId}/templates/receive-updates`)));
|
|
65
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { parseVariableEntries, mergeVariableEntries, withNormalization } from '../knowledge/normalize.js';
|
|
2
|
+
import { guid, projectParam, environmentParam, readOnly, writes, updates, destructive } from './common.js';
|
|
3
|
+
import { handle } from '../platform/responses.js';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
const variablePath = (applicationId, pageId) => pageId ? `/variables/${applicationId}/${pageId}` : `/variables/${applicationId}`;
|
|
6
|
+
const variablesParam = z.array(z.object({
|
|
7
|
+
key: z.string().min(1).describe("Değişken adı; sayfada state.page.<key> ile okunur"),
|
|
8
|
+
value: z.unknown().describe('Herhangi bir JSON değeri; nesne verirseniz alanlarına state.page.<key>.<alan> ile erişilir')
|
|
9
|
+
})).min(1).describe("Değişken listesi: [{ key: 'MyTest', value: { isActive: true } }]. Gateway bunu platformun beklediği JSON string'e çevirir.");
|
|
10
|
+
const replaceParam = z.boolean().optional()
|
|
11
|
+
.describe('true: seti komple bunlarla değiştir (diğer değişkenler silinir). Varsayılan false — gateway mevcut setle birleştirir.');
|
|
12
|
+
export function registerVariableTools(server, platform) {
|
|
13
|
+
const config = platform.config;
|
|
14
|
+
const readEntries = async (project, environment, applicationId, pageId) => {
|
|
15
|
+
try {
|
|
16
|
+
const payload = await platform.tenant('GET', project, variablePath(applicationId, pageId), { environment });
|
|
17
|
+
const record = (payload?.data ?? payload);
|
|
18
|
+
return parseVariableEntries(record?.data);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
const write = async (method, { project, environment, applicationId, pageId, variables, replace }) => {
|
|
25
|
+
const incoming = variables.map(entry => ({ key: entry.key, value: entry.value ?? null }));
|
|
26
|
+
const existing = replace === true ? [] : await readEntries(project, environment, applicationId, pageId);
|
|
27
|
+
const merged = mergeVariableEntries(existing, incoming, replace === true);
|
|
28
|
+
const response = await platform.tenant(method, project, variablePath(applicationId, pageId), {
|
|
29
|
+
environment,
|
|
30
|
+
body: {
|
|
31
|
+
applicationId,
|
|
32
|
+
...(pageId ? { pageId } : {}),
|
|
33
|
+
data: JSON.stringify(merged.entries)
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return withNormalization({
|
|
37
|
+
scope: pageId ? 'page' : 'application',
|
|
38
|
+
variables: merged.entries.map(entry => entry.key),
|
|
39
|
+
response
|
|
40
|
+
}, [
|
|
41
|
+
...merged.fixes,
|
|
42
|
+
`data alanı JSON string'e çevrildi (platform sözleşmesi: "[{\\"key\\":…,\\"value\\":…}]") — dizi olarak gönderilse Studio çalışma zamanı okuyamaz`
|
|
43
|
+
]);
|
|
44
|
+
};
|
|
45
|
+
server.registerTool('variable_list', {
|
|
46
|
+
title: 'Değişkenleri getir',
|
|
47
|
+
description: "Application (pageId verilirse sayfa) değişken setini getirir. Platform seti tek kayıtta ve JSON STRING olarak tutar; gateway çözüp [{key, value}] dizisi döndürür. Sayfada okuma yolu: state.page.<key> (uygulama düzeyinde state.app.<key>).",
|
|
48
|
+
inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid, pageId: guid.optional() },
|
|
49
|
+
annotations: readOnly
|
|
50
|
+
}, handle(config, async ({ project, environment, applicationId, pageId }) => ({
|
|
51
|
+
scope: pageId ? 'page' : 'application',
|
|
52
|
+
applicationId,
|
|
53
|
+
...(pageId ? { pageId } : {}),
|
|
54
|
+
variables: await readEntries(project, environment, applicationId, pageId)
|
|
55
|
+
})));
|
|
56
|
+
server.registerTool('variable_pages', {
|
|
57
|
+
title: 'Sayfa değişkenlerini listele',
|
|
58
|
+
description: 'Application altında sayfa bazlı tanımlanmış değişken setlerini listeler.',
|
|
59
|
+
inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid },
|
|
60
|
+
annotations: readOnly
|
|
61
|
+
}, handle(config, ({ project, environment, applicationId }) => platform.tenant('GET', project, `/variables/${applicationId}/pages`, { environment })));
|
|
62
|
+
server.registerTool('variable_create', {
|
|
63
|
+
title: 'Değişken tanımla',
|
|
64
|
+
description: "Application (pageId verilirse sayfa) değişkeni tanımlar. Platform uygulama/sayfa başına TEK kayıt tutar ve seti komple değiştirir; gateway mevcut setle birleştirir (replace: true ile ezersiniz). Sayfada kullanım: prop { type:'code', ref:\"{{ state.page.<key>.<alan> }}\" } ya da flow'da value { type:'state', ref:'<key>' }.",
|
|
65
|
+
inputSchema: {
|
|
66
|
+
project: projectParam,
|
|
67
|
+
environment: environmentParam,
|
|
68
|
+
applicationId: guid,
|
|
69
|
+
pageId: guid.optional().describe('Verilirse sayfa düzeyi (state.page), verilmezse uygulama düzeyi (state.app)'),
|
|
70
|
+
variables: variablesParam,
|
|
71
|
+
replace: replaceParam
|
|
72
|
+
},
|
|
73
|
+
annotations: writes
|
|
74
|
+
}, handle(config, input => write('POST', input)));
|
|
75
|
+
server.registerTool('variable_update', {
|
|
76
|
+
title: 'Değişken güncelle',
|
|
77
|
+
description: "Var olan değişken setini günceller (variable_create zaten kayıt varsa update'e düşer; ikisi de aynı sonucu verir). Anahtar bazında birleştirir, replace: true ile seti komple değiştirir.",
|
|
78
|
+
inputSchema: {
|
|
79
|
+
project: projectParam,
|
|
80
|
+
environment: environmentParam,
|
|
81
|
+
applicationId: guid,
|
|
82
|
+
pageId: guid.optional(),
|
|
83
|
+
variables: variablesParam,
|
|
84
|
+
replace: replaceParam
|
|
85
|
+
},
|
|
86
|
+
annotations: updates
|
|
87
|
+
}, handle(config, input => write('PUT', input)));
|
|
88
|
+
server.registerTool('variable_delete', {
|
|
89
|
+
title: 'Değişken setini sil',
|
|
90
|
+
description: "Application (pageId verilirse sayfa) değişken setinin TAMAMINI siler — tek değişken silmek için variable_update'e kalan listeyi replace: true ile gönderin.",
|
|
91
|
+
inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid, pageId: guid.optional() },
|
|
92
|
+
annotations: destructive
|
|
93
|
+
}, handle(config, ({ project, environment, applicationId, pageId }) => platform.tenant('DELETE', project, variablePath(applicationId, pageId), { environment })));
|
|
94
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { normalizeViewDefinition, viewAliasNote, withNormalization } from '../knowledge/normalize.js';
|
|
2
|
+
import { guid, projectParam, environmentParam, definitionParam, pagingParams, readOnly, writes, updates, destructive } from './common.js';
|
|
3
|
+
import { PlatformApiError } from '../platform/errors.js';
|
|
4
|
+
import { handle } from '../platform/responses.js';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
export function registerViewTools(server, platform) {
|
|
7
|
+
const config = platform.config;
|
|
8
|
+
const normalizeSource = (definition) => {
|
|
9
|
+
const { fixes, errors } = normalizeViewDefinition(definition);
|
|
10
|
+
if (errors.length > 0)
|
|
11
|
+
throw new PlatformApiError(errors.join(' · '), 400);
|
|
12
|
+
return fixes;
|
|
13
|
+
};
|
|
14
|
+
server.registerTool('view_list', {
|
|
15
|
+
title: 'View listele',
|
|
16
|
+
description: 'Projedeki view arama indekslerini listeler. DİKKAT: view modülü RAPORLAMA/özet için DEĞİL, tam metin (global) ARAMA içindir.',
|
|
17
|
+
inputSchema: { project: projectParam, environment: environmentParam, searchTerm: z.string().optional(), ...pagingParams },
|
|
18
|
+
annotations: readOnly
|
|
19
|
+
}, handle(config, ({ project, environment, ...query }) => platform.tenant('GET', project, '/views', { environment, query })));
|
|
20
|
+
server.registerTool('view_get', {
|
|
21
|
+
title: 'View getir',
|
|
22
|
+
description: 'Tek view tanımını getirir; view_create için en iyi gövde şablonudur.',
|
|
23
|
+
inputSchema: { project: projectParam, environment: environmentParam, id: guid },
|
|
24
|
+
annotations: readOnly
|
|
25
|
+
}, handle(config, ({ project, environment, id }) => platform.tenant('GET', project, `/views/${id}`, { environment })));
|
|
26
|
+
server.registerTool('view_create', {
|
|
27
|
+
title: 'View oluştur',
|
|
28
|
+
description: "TAM METİN ARAMA indeksi tanımlar (definition = CreateViewCommand; gövde şeması ngapps://schemas/CreateViewCommand, analizör sözlüğü platform_guide('view')) — raporlama/agregasyon aracı DEĞİLDİR. Seçilen tablo/alanlar analizörden (tokenizer/dil) geçirilip slug adlı projeksiyon tablosuna indekslenir; tüketimi source:'view' microservice'idir ve o uç ZORUNLU 'searchText' parametresi ister (+limit/offset). Rapor/özet için raw query (query_create) + query kaynaklı microservice kullanın. Birden çok entity verilebilir (entities: [{entityId, alias}], fields alias'la bağlanır: viewEntityAlias) ama bu JOIN DEĞİLDİR: her tablo ayrı ayrı indekslenir, aralarında ilişki tanımı yoktur ve eşleşme hangi tablodan geldiyse dönen kayıt o tablonun satırıdır. İlişkili içeriği tek kayıtta aratmak için denormalize bir alan kullanın (yorum metnini talebe yazan automation + tek entity'li view).",
|
|
29
|
+
inputSchema: { project: projectParam, environment: environmentParam, definition: definitionParam },
|
|
30
|
+
annotations: writes
|
|
31
|
+
}, handle(config, async ({ project, environment, definition }) => {
|
|
32
|
+
const fixes = normalizeSource(definition);
|
|
33
|
+
const response = await platform.tenant('POST', project, '/views', { environment, body: definition });
|
|
34
|
+
return withNormalization(response, viewAliasNote(fixes));
|
|
35
|
+
}));
|
|
36
|
+
server.registerTool('view_update', {
|
|
37
|
+
title: 'View güncelle',
|
|
38
|
+
description: "View tanımını günceller (definition = UpdateViewCommand, şema ngapps://schemas/UpdateViewCommand); mevcut hâli view_get ile alın. UpdateViewCommand'da datasourceId YOKTUR (create'te bağlanır). DİKKAT: view_get alanları 'viewEntityId' ile döndürür, yazma tarafı 'viewEntityAlias' ister — okuduğunuzu birebir geri yazarsanız gateway id'yi alias'a çevirir, çeviremezse isteği reddeder.",
|
|
39
|
+
inputSchema: { project: projectParam, environment: environmentParam, id: guid, definition: definitionParam },
|
|
40
|
+
annotations: updates
|
|
41
|
+
}, handle(config, async ({ project, environment, id, definition }) => {
|
|
42
|
+
const fixes = normalizeSource(definition);
|
|
43
|
+
const response = await platform.tenant('PUT', project, `/views/${id}`, { environment, body: definition });
|
|
44
|
+
return withNormalization(response, viewAliasNote(fixes));
|
|
45
|
+
}));
|
|
46
|
+
server.registerTool('view_delete', {
|
|
47
|
+
title: 'View sil',
|
|
48
|
+
description: 'View projeksiyonunu siler.',
|
|
49
|
+
inputSchema: { project: projectParam, environment: environmentParam, id: guid },
|
|
50
|
+
annotations: destructive
|
|
51
|
+
}, handle(config, ({ project, environment, id }) => platform.tenant('DELETE', project, `/views/${id}`, { environment })));
|
|
52
|
+
server.registerTool('view_rebuild', {
|
|
53
|
+
title: 'View yeniden kur',
|
|
54
|
+
description: 'View projeksiyon tablosunu yeniden inşa eder (veri değişikliklerinden sonra senkron için).',
|
|
55
|
+
inputSchema: { project: projectParam, environment: environmentParam, id: guid },
|
|
56
|
+
annotations: writes
|
|
57
|
+
}, handle(config, ({ project, environment, id }) => platform.tenant('POST', project, `/views/${id}/rebuild`, { environment })));
|
|
58
|
+
}
|