@appaflytech/zeyrek-ai-mcp 0.0.30 → 0.0.32
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 +0 -15
- package/README.md +5 -5
- package/dist/config.js +0 -37
- package/dist/index.js +0 -2
- package/dist/knowledge/backendConstraints.js +1 -18
- package/dist/knowledge/boxSections.js +184 -0
- package/dist/knowledge/componentCatalog.js +232 -562
- package/dist/knowledge/componentEvents.js +21 -141
- package/dist/knowledge/layoutSummary.js +2 -140
- package/dist/knowledge/normalize.js +67 -236
- package/dist/knowledge/outlines.js +0 -36
- package/dist/knowledge/policy.js +4 -18
- package/dist/knowledge/reservedTables.js +0 -79
- package/dist/knowledge/rules.js +21 -319
- package/dist/knowledge/schemaGuard.js +0 -11
- package/dist/knowledge/styleResolve.js +38 -55
- package/dist/knowledge/themeResolve.js +3 -3
- package/dist/observability/trace.js +3 -6
- package/dist/platform/diagnostics.js +4 -10
- package/dist/platform/domSummary.js +1 -1
- package/dist/platform/errors.js +10 -162
- package/dist/platform/http.js +8 -29
- package/dist/platform/responses.js +5 -39
- package/dist/platform/{capture/capture.js → screenshot.js} +519 -105
- package/dist/platform/secrets.js +1 -17
- package/dist/platform/strictArguments.js +12 -68
- package/dist/platform/tokenVault.js +4 -187
- package/dist/resources/examples/layout-app-shell.json +707 -229
- package/dist/resources/examples/page-detail-profile.json +1 -2
- package/dist/resources/examples/page-dynamic-form.json +2 -3
- package/dist/resources/examples/page-flex-sections.json +1 -1
- package/dist/resources/examples/page-html-embed.json +1 -1
- package/dist/resources/examples/workflow-basic.json +2 -8
- package/dist/resources/guides/component.md +4 -91
- package/dist/resources/guides/entity.md +8 -50
- package/dist/resources/guides/expressions.md +5 -14
- package/dist/resources/guides/functions.md +1 -1
- package/dist/resources/guides/getting-started.md +1 -38
- package/dist/resources/guides/layout.md +58 -55
- package/dist/resources/guides/microservice.md +2 -81
- package/dist/resources/guides/middleware.md +2 -44
- package/dist/resources/guides/page.md +75 -454
- package/dist/resources/guides/theme.md +2 -8
- package/dist/resources/guides/translation.md +1 -1
- package/dist/resources/guides/workflow.md +1 -58
- package/dist/resources/rules.js +5 -11
- package/dist/resources/schema-fingerprint.json +5 -7
- package/dist/resources/schemas/CreateEntityCommand.json +0 -118
- package/dist/resources/schemas/CreateMicroserviceCommand.json +1 -13
- package/dist/resources/schemas/CreateQueryCommand.json +0 -4
- package/dist/resources/schemas/CreateWorkflowCommand.json +1 -143
- package/dist/resources/schemas/DataJobDto.json +1 -6
- package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +1 -21
- package/dist/resources/schemas/MicroserviceDto.json +3 -15
- package/dist/resources/schemas/PreviewMicroserviceCommand.json +1 -10
- package/dist/resources/schemas/PreviewWorkflowCommand.json +1 -22
- package/dist/resources/schemas/StepDto.json +1 -22
- package/dist/resources/schemas/UpdateEntityCommand.json +0 -118
- package/dist/resources/schemas/UpdateMicroserviceCommand.json +1 -13
- package/dist/resources/schemas/UpdateQueryCommand.json +0 -4
- package/dist/resources/schemas/UpdateViewCommand.json +2 -0
- package/dist/resources/schemas/UpdateWorkflowCommand.json +1 -143
- package/dist/server.js +1 -27
- package/dist/tools/access.js +2 -369
- package/dist/tools/applications.js +3 -60
- package/dist/tools/common.js +0 -7
- package/dist/tools/components.js +14 -118
- package/dist/tools/datasources.js +3 -3
- package/dist/tools/dependencies.js +1 -1
- package/dist/tools/deployments.js +2 -2
- package/dist/tools/designSchemaPatch.js +18 -34
- package/dist/tools/dtos.js +5 -36
- package/dist/tools/entities.js +12 -79
- package/dist/tools/externalComponents.js +5 -26
- package/dist/tools/flows.js +14 -122
- package/dist/tools/folders.js +1 -1
- package/dist/tools/imports.js +2 -5
- package/dist/tools/layouts.js +17 -50
- package/dist/tools/merges.js +1 -1
- package/dist/tools/microservices.js +25 -77
- package/dist/tools/pages.js +112 -465
- package/dist/tools/platformInfo.js +8 -27
- package/dist/tools/projects.js +9 -71
- package/dist/tools/rows.js +13 -69
- package/dist/tools/schemaOps.js +1 -61
- package/dist/tools/screenWrite.js +8 -37
- package/dist/tools/screens.js +5 -95
- package/dist/tools/templates.js +1 -26
- package/dist/tools/translations.js +1 -1
- package/dist/tools/variables.js +5 -11
- package/dist/tools/workflows.js +5 -10
- package/package.json +2 -2
- package/dist/knowledge/access.js +0 -802
- package/dist/knowledge/case.js +0 -41
- package/dist/knowledge/connectDataBind.js +0 -819
- package/dist/knowledge/connectDataDefinition.js +0 -341
- package/dist/knowledge/connectDataExecute.js +0 -93
- package/dist/knowledge/connectDataRules.js +0 -128
- package/dist/knowledge/decision.js +0 -121
- package/dist/knowledge/expressionPrelude.js +0 -59
- package/dist/knowledge/microserviceParameters.js +0 -58
- package/dist/knowledge/mining.js +0 -94
- package/dist/knowledge/mobileComponentCatalog.js +0 -859
- package/dist/knowledge/mobileComponentEvents.js +0 -239
- package/dist/knowledge/platform/lint.js +0 -385
- package/dist/knowledge/platform/mobile.js +0 -142
- package/dist/knowledge/platform/mobileLayoutLint.js +0 -324
- package/dist/knowledge/platform/mobileRules.js +0 -231
- package/dist/knowledge/platform/mobileSpacing.js +0 -82
- package/dist/knowledge/platform/mobileTabs.js +0 -108
- package/dist/knowledge/platform/nativeBoxModel.js +0 -44
- package/dist/knowledge/platform/profile.js +0 -25
- package/dist/knowledge/platform/resolve.js +0 -122
- package/dist/knowledge/platform/web.js +0 -39
- package/dist/knowledge/process.js +0 -510
- package/dist/knowledge/rowFilter.js +0 -43
- package/dist/knowledge/styleResolveNative.js +0 -527
- package/dist/platform/argumentAliases.js +0 -128
- package/dist/platform/bodyFile.js +0 -103
- package/dist/platform/capture/actions.js +0 -333
- package/dist/platform/capture/browser.js +0 -1
- package/dist/platform/capture/console-log.js +0 -122
- package/dist/platform/capture/index.js +0 -11
- package/dist/platform/capture/readiness.js +0 -103
- package/dist/platform/capture/summary.js +0 -77
- package/dist/platform/capture/target.js +0 -5
- package/dist/platform/capture/targets/studio-mobile.js +0 -15
- package/dist/platform/capture/targets/studio-web.js +0 -5
- package/dist/platform/impersonation.js +0 -45
- package/dist/platform/jsonArray.js +0 -24
- package/dist/platform/schemaReadMemory.js +0 -60
- package/dist/resources/examples/bpm-gorev-kontrol.json +0 -294
- package/dist/resources/examples/bpm-iso-dokuman.json +0 -228
- package/dist/resources/examples/bpm-satinalma.json +0 -376
- package/dist/resources/examples/connect-data-convert-verify.json +0 -107
- package/dist/resources/examples/connect-data-dropdown-roles.json +0 -66
- package/dist/resources/examples/connect-data-edit-m2m.json +0 -73
- package/dist/resources/examples/connect-data-query-params.json +0 -50
- package/dist/resources/examples/connect-data-table-entity.json +0 -147
- package/dist/resources/examples/connect-data-workflow-microservice.json +0 -65
- package/dist/resources/examples/mobile-app-shell-drawer.json +0 -243
- package/dist/resources/examples/mobile-app-shell-stack.json +0 -157
- package/dist/resources/examples/mobile-app-shell-tab.json +0 -208
- package/dist/resources/examples/mobile-form-screen.json +0 -365
- package/dist/resources/examples/mobile-list-detail-form.json +0 -672
- package/dist/resources/guides/access.md +0 -796
- package/dist/resources/guides/bpm.md +0 -686
- package/dist/resources/guides/case.md +0 -153
- package/dist/resources/guides/decision.md +0 -185
- package/dist/resources/guides/mobile-layout.md +0 -193
- package/dist/resources/guides/mobile.md +0 -495
- package/dist/resources/read.js +0 -41
- package/dist/resources/schemas/AccessExplanationDto.json +0 -144
- package/dist/resources/schemas/AccessMatrixDto.json +0 -170
- package/dist/resources/schemas/AccessPermissionDto.json +0 -57
- package/dist/resources/schemas/AccessPolicyDto.json +0 -223
- package/dist/resources/schemas/AccessResourceDto.json +0 -86
- package/dist/resources/schemas/AppSessionDto.json +0 -53
- package/dist/resources/schemas/ConnectDataDescribeDto.json +0 -344
- package/dist/resources/schemas/ConnectDataRequestModel.json +0 -202
- package/dist/resources/schemas/ConnectDataResultDto.json +0 -421
- package/dist/resources/schemas/ConnectorCredentialDto.json +0 -70
- package/dist/resources/schemas/ConvertConnectDataToMicroserviceCommand.json +0 -37
- package/dist/resources/schemas/CreateAccessPolicyCommand.json +0 -209
- package/dist/resources/schemas/CreateDecisionCommand.json +0 -221
- package/dist/resources/schemas/CreateProcessDefinitionCommand.json +0 -1337
- package/dist/resources/schemas/DecisionDto.json +0 -302
- package/dist/resources/schemas/DetachConnectDataMicroserviceCommand.json +0 -28
- package/dist/resources/schemas/ExplainAccessQuery.json +0 -33
- package/dist/resources/schemas/GenerateProcessDocumentCommand.json +0 -116
- package/dist/resources/schemas/OrganizationProjectDto.json +0 -335
- package/dist/resources/schemas/OrganizationSchemaDto.json +0 -196
- package/dist/resources/schemas/OrganizationSchemaVersionDto.json +0 -207
- package/dist/resources/schemas/PatchProcessDefinitionCommand.json +0 -76
- package/dist/resources/schemas/ProcessDefinitionDto.json +0 -1480
- package/dist/resources/schemas/ProcessSimulationDto.json +0 -96
- package/dist/resources/schemas/SaveConnectorCredentialCommand.json +0 -90
- package/dist/resources/schemas/SaveProcessEventSourceCommand.json +0 -61
- package/dist/resources/schemas/SaveProcessMailSourceCommand.json +0 -89
- package/dist/resources/schemas/SignProcessTaskCommand.json +0 -73
- package/dist/resources/schemas/SimulateProcessDefinitionQuery.json +0 -92
- package/dist/resources/schemas/UpdateAccessPolicyCommand.json +0 -209
- package/dist/resources/schemas/UpdateDecisionCommand.json +0 -216
- package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +0 -1357
- package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +0 -1339
- package/dist/tools/accessOperations.js +0 -135
- package/dist/tools/accessPolicies.js +0 -170
- package/dist/tools/accessRuntime.js +0 -203
- package/dist/tools/bpm.js +0 -343
- package/dist/tools/bpmGovernance.js +0 -266
- package/dist/tools/bpmOperations.js +0 -230
- package/dist/tools/bpmReporting.js +0 -154
- package/dist/tools/bpmRouting.js +0 -150
- package/dist/tools/bpmRuntime.js +0 -396
- package/dist/tools/case.js +0 -178
- package/dist/tools/caseRuntime.js +0 -89
- package/dist/tools/connectData.js +0 -449
- package/dist/tools/connectors.js +0 -193
- package/dist/tools/decisions.js +0 -206
- package/dist/tools/mobile.js +0 -221
- package/dist/tools/modules.js +0 -48
- package/dist/tools/organizationStructure.js +0 -137
- package/dist/tools/profileWrite.js +0 -92
package/dist/tools/entities.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { guid, entityRef, resolveEntityId, withResolved, projectParam, environmentParam, definitionParam, pagingParams, readOnly, writes, updates, destructive, microOps } from './common.js';
|
|
2
2
|
import { RefResolver, isGuid } from '../platform/refs.js';
|
|
3
|
-
import { evaluatePolicy, enforcePolicy, attachFindings
|
|
4
|
-
import { changedExistingProtections, fieldProtectionFindings, protectionMaskTypes } from '../knowledge/access.js';
|
|
5
|
-
import { PlatformApiError } from '../platform/errors.js';
|
|
3
|
+
import { evaluatePolicy, enforcePolicy, attachFindings } from '../knowledge/policy.js';
|
|
6
4
|
import { splitJunctionFields, withNormalization } from '../knowledge/normalize.js';
|
|
7
5
|
import { unmappedMembers, introducedUnmappedMembers, withUnmappedMembers } from '../knowledge/schemaGuard.js';
|
|
8
6
|
import { entityOutline, resolvePart, resolvePatchOperations, patchedSections } from '../knowledge/outlines.js';
|
|
@@ -10,11 +8,10 @@ import { patchResult, baseVersionOf } from '../platform/patch.js';
|
|
|
10
8
|
import { isJunctionField, policyRules } from '../knowledge/rules.js';
|
|
11
9
|
import { handle } from '../platform/responses.js';
|
|
12
10
|
import fastJsonPatch from 'fast-json-patch';
|
|
13
|
-
import { jsonArray } from '../platform/jsonArray.js';
|
|
14
11
|
import { z } from 'zod';
|
|
15
12
|
const policyOverrideParam = z.boolean().optional()
|
|
16
13
|
.describe('true: politika block bulgularını warn\'a indirir (bilinçli istisna; yanıtta işaretlenir)');
|
|
17
|
-
const patchOperationsParam =
|
|
14
|
+
const patchOperationsParam = z.array(z.record(z.unknown())).min(1)
|
|
18
15
|
.describe("RFC 6902 JSON Patch işlemleri; path'leri view:'outline'/'part' ile keşfedin");
|
|
19
16
|
function preserveApplicationBinding(definition) {
|
|
20
17
|
if (Array.isArray(definition.applicationIds))
|
|
@@ -116,7 +113,7 @@ export function registerEntityTools(server, platform) {
|
|
|
116
113
|
}));
|
|
117
114
|
server.registerTool('entity_create', {
|
|
118
115
|
title: 'Entity oluştur',
|
|
119
|
-
description: "Datasource altında yeni entity oluşturur (definition = CreateEntityCommand: name, fields[], applicationIds, ...). İlişkiler ve alan tipi kararı için platform_guide('entity') okuyun.
|
|
116
|
+
description: "Datasource altında yeni entity oluşturur (definition = CreateEntityCommand: name, fields[], applicationIds, ...). İlişkiler ve alan tipi kararı için platform_guide('entity') okuyun. Gövde politika kontrolünden geçer. applicationIds create'te platformca bağlanır (CreateEntityCommandHandler entityApplications'ı Entity ctor'una geçirir); satır uçları bu bağa İHTİYAÇ DUYMAZ — bağ yalnız Studio'nun application'a göre entity listesini ve bağımlılık sorgularını etkiler. `fields[].isLocalized: true` alanı ana tablodan çıkarıp companion `<slug>_localization` entity'sine taşır (yalnız düz METİN alanı; anahtar/unique/ilişki olamaz) — platform_guide('entity') §'Çoklu dilli alan'. SEÇİM LİSTESİNE (enum) TEK DEĞER: listeyi yeniden göndermeyin — ekleme `{op:'add', path:'/fields[slug=status]/valueOptions/-', value:{value:'Onayda', order:4}}`, silme `{op:'remove', path:'/fields[slug=status]/valueOptions[value=Eski]'}`, yeniden adlandırma `{op:'replace', path:'/fields[slug=status]/valueOptions[value=Eski]/value', value:'Yeni'}`; `isEnum` türetilmiştir, ayrıca yazılmaz. Silme/yeniden adlandırmadan ÖNCE o değeri taşıyan satırları taşıyın — yoksa istek reddedilir ve hiçbir şey yazılmaz ('check constraint … is violated by some row') (platform_guide('entity') §'Alan tipine karar verme').",
|
|
120
117
|
inputSchema: { project: projectParam, environment: environmentParam, datasourceId: guid, definition: definitionParam, policyOverride: policyOverrideParam },
|
|
121
118
|
annotations: writes
|
|
122
119
|
}, handle(config, async ({ project, environment, datasourceId, definition, policyOverride }) => {
|
|
@@ -131,28 +128,12 @@ export function registerEntityTools(server, platform) {
|
|
|
131
128
|
if (!createdId) {
|
|
132
129
|
throw new Error(`Entity kuruldu ama id okunamadı; m2m alanları (${deferred.map(field => field.slug ?? field.name).join(', ')}) eklenmedi — entity_get ile kaydı bulup entity_patch ile ekleyin.`);
|
|
133
130
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
let updated;
|
|
141
|
-
for (const field of deferred) {
|
|
142
|
-
const current = await platform.tenant('GET', project, `/entities/${datasourceId}/${createdId}`, { environment });
|
|
143
|
-
const full = structuredClone((current?.data ?? current));
|
|
144
|
-
full.fields = [...(Array.isArray(full.fields) ? full.fields : []), field];
|
|
145
|
-
preserveApplicationBinding(full);
|
|
146
|
-
try {
|
|
147
|
-
updated = await platform.tenant('PUT', project, `/entities/${createdId}`, { environment, body: full });
|
|
148
|
-
}
|
|
149
|
-
catch (error) {
|
|
150
|
-
const added = deferred.slice(0, deferred.indexOf(field)).map(item => item.slug ?? item.name);
|
|
151
|
-
const missing = deferred.slice(deferred.indexOf(field)).map(item => item.slug ?? item.name);
|
|
152
|
-
throw new PlatformApiError(`Entity ${createdId} kuruldu${added.length ? `, ${added.join(', ')} eklendi` : ''}; '${String(field.slug ?? field.name)}' eklenirken platform reddetti: ${error instanceof Error ? error.message : String(error)} — eklenmeyen alanlar (${missing.join(', ')}) entity_patch ile tek tek eklenebilir.`, error instanceof PlatformApiError ? error.status : 400, error instanceof PlatformApiError ? error.code : undefined);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
const note = `m2m/çoklu alanlar (${deferred.map(field => field.slug ?? field.name).join(', ')}) ayrı güncelleme turlarında TEK TEK eklendi: create yolu junction kaydını açar ama fiziksel tabloyu kurmaz (platform bug'ı P-01), update yolu kurar; çoklu enum başka bir junction alanıyla aynı güncellemede platformda düşer (38/U-15).`;
|
|
131
|
+
const current = await platform.tenant('GET', project, `/entities/${datasourceId}/${createdId}`, { environment });
|
|
132
|
+
const full = structuredClone((current?.data ?? current));
|
|
133
|
+
full.fields = [...(Array.isArray(full.fields) ? full.fields : []), ...deferred];
|
|
134
|
+
preserveApplicationBinding(full);
|
|
135
|
+
const updated = await platform.tenant('PUT', project, `/entities/${createdId}`, { environment, body: full });
|
|
136
|
+
const note = `m2m/çoklu alanlar (${deferred.map(field => field.slug ?? field.name).join(', ')}) ayrı bir güncelleme turunda eklendi: create yolu junction kaydını açar ama fiziksel tabloyu kurmaz (platform bug'ı P-01), update yolu kurar.`;
|
|
156
137
|
return attachFindings(withUnmappedMembers(withNormalization(updated, [note]), drift), findings);
|
|
157
138
|
}));
|
|
158
139
|
server.registerTool('entity_create_discovered', {
|
|
@@ -163,7 +144,7 @@ export function registerEntityTools(server, platform) {
|
|
|
163
144
|
}, handle(config, ({ project, environment, datasourceId, definition }) => platform.tenant('POST', project, `/entities/${datasourceId}/discovered`, { environment, body: definition })));
|
|
164
145
|
server.registerTool('entity_update', {
|
|
165
146
|
title: 'Entity güncelle',
|
|
166
|
-
description: "Entity tanımını günceller (tam gövde).
|
|
147
|
+
description: "Entity tanımını günceller (tam gövde). Hedefli değişiklik için entity_patch tercih edin. Gövde politika kontrolünden geçer. DİKKAT: gövdede 'indexes' YOKSA platform entity'nin bütün index'lerini siler — gateway alan verilmemişse mevcut index'leri taşır ve bunu bildirir; silmek için 'indexes: []' yazın. `fields[].isLocalized: true` alanı ana tablodan çıkarıp companion `<slug>_localization` entity'sine taşır (yalnız düz METİN alanı; anahtar/unique/ilişki olamaz) — platform_guide('entity') §'Çoklu dilli alan'.",
|
|
167
148
|
inputSchema: { project: projectParam, environment: environmentParam, datasourceId: guid.optional().describe('Verilmezse gateway datasource ağacından bulur'), id: entityRef, definition: definitionParam, policyOverride: policyOverrideParam },
|
|
168
149
|
annotations: updates
|
|
169
150
|
}, handle(config, async ({ project, environment, datasourceId, id, definition, policyOverride }) => {
|
|
@@ -178,7 +159,7 @@ export function registerEntityTools(server, platform) {
|
|
|
178
159
|
}));
|
|
179
160
|
server.registerTool('entity_patch', {
|
|
180
161
|
title: 'Entity\'ye patch uygula',
|
|
181
|
-
description: "
|
|
162
|
+
description: "Tam gövdeyi bağlama almadan hedefli değişiklik: gateway mevcut tanımı okur, yolları çözer ve op'ları platformun PATCH /entities/{id} ucuna `{ baseVersion, ops }` olarak geçirir — tam gövde PUT'u ATILMAZ, yalnız fark yazılır. Yanıt outline özetidir. YOLLARDA SEÇİCİ KULLANIN, indeks değil: '/fields[slug=email]/nullable' — indeksle yazmak alan sırası değişince SESSİZCE yanlış alanı yazar. Gateway seçiciyi indekse çevirir ve hangi kayda indiğini yanıttaki patchTargets ile söyler. `baseVersion` okunan kaydın `version` alanından gelir; kayıt bu arada değiştiyse platform 409 döner ve HİÇBİR op uygulanmaz. 'applications' → 'applicationIds' çevirisini artık platform yapar. `fields[].isLocalized: true` alanı ana tablodan çıkarıp companion `<slug>_localization` entity'sine taşır (yalnız düz METİN alanı; anahtar/unique/ilişki olamaz) — platform_guide('entity') §'Çoklu dilli alan'.",
|
|
182
163
|
inputSchema: { project: projectParam, environment: environmentParam, datasourceId: guid.optional().describe('Verilmezse gateway datasource ağacından bulur'), id: entityRef, operations: patchOperationsParam.optional(), ops: patchOperationsParam.optional().describe("'operations' ile aynı alan (eşanlamlı) — sayfa micro-op tool'larıyla aynı adı kullanabilmeniz için"), policyOverride: policyOverrideParam },
|
|
183
164
|
annotations: updates
|
|
184
165
|
}, handle(config, async ({ project, environment, datasourceId, id, operations: givenOperations, ops, policyOverride }) => {
|
|
@@ -190,10 +171,6 @@ export function registerEntityTools(server, platform) {
|
|
|
190
171
|
const resolvedOps = resolvePatchOperations(definition, operations, 'entity_get');
|
|
191
172
|
// Politika, yazmadan önce sonucu görmeli; yerel kopya YALNIZ değerlendirme için, gövde olarak gönderilmez.
|
|
192
173
|
const preview = fastJsonPatch.applyPatch(definition, resolvedOps.operations, true, false).newDocument;
|
|
193
|
-
const protectionChanges = changedExistingProtections(current?.data ?? current, preview);
|
|
194
|
-
if (protectionChanges.length > 0) {
|
|
195
|
-
throw new PlatformApiError(`entity_patch: var olan alanın korumasını değiştiriyor (${protectionChanges.join(', ')}) — platform bunu 400 ProtectionChangeNotAllowed ile reddeder, çünkü dolu satırlar arka plan işiyle dönüştürülmelidir. entity_protection_update { entityId, field: '${protectionChanges[0]}', protection } kullanın; istek gönderilmedi. Yeni bir alanı korumayla eklemek entity_patch ile serbesttir.`, 400);
|
|
196
|
-
}
|
|
197
174
|
const findings = [
|
|
198
175
|
...enforcePolicy(evaluatePolicy(config, policyRules, 'entity', preview, { operation: 'update' }, policyOverride)),
|
|
199
176
|
...inPlaceIndexEdits(current?.data ?? current, preview)
|
|
@@ -218,48 +195,6 @@ export function registerEntityTools(server, platform) {
|
|
|
218
195
|
outline: entityOutline(written.data)
|
|
219
196
|
}, resolver.resolved), drift), findings);
|
|
220
197
|
}));
|
|
221
|
-
server.registerTool('entity_protection_update', {
|
|
222
|
-
title: 'Alan korumasını değiştir',
|
|
223
|
-
description: "VAR OLAN bir alanın koruma modunu değiştirir (none · masked · encrypted · masked-encrypted): platform gizli kolonları ekler ve dolu satırları arka plan işiyle dönüştürür — yanıt 202 + jobId; ilerleme import_status { jobId } (aynı DataJobs ucu, tür protection-apply / protection-remove). entity_update / entity_patch var olan alanın korumasını DEĞİŞTİREMEZ (400 ProtectionChangeNotAllowed). İş sürerken aynı entity'ye yazım 409; iş hata verirse AYNI çağrı kaldığı yerden sürdürür. PROT-003 istek gitmeden uygulanır; kurallar platform_guide('access') §'Alan koruması'.",
|
|
224
|
-
inputSchema: {
|
|
225
|
-
project: projectParam,
|
|
226
|
-
environment: environmentParam,
|
|
227
|
-
entityId: entityRef,
|
|
228
|
-
field: z.string().min(1).describe("Alanın id'si (GUID) ya da slug'ı"),
|
|
229
|
-
protection: z.object({
|
|
230
|
-
mode: z.enum(['none', 'masked', 'encrypted', 'masked-encrypted']).describe("'none' korumayı kaldırır"),
|
|
231
|
-
mask: z.object({
|
|
232
|
-
type: z.enum(protectionMaskTypes()),
|
|
233
|
-
visible: z.number().int().min(0).optional().describe('last-n / first-n için > 0; phone varsayılanı 2 hane; first-n-last-n\'de baştan görünen karakter sayısı (> 0)'),
|
|
234
|
-
visibleEnd: z.number().int().min(0).optional().describe('Yalnız first-n-last-n: sondan görünen karakter sayısı (> 0) — 10000000146, visible 3 + visibleEnd 2 → 100******46'),
|
|
235
|
-
char: z.string().length(1).optional().describe("Varsayılan '*'; phone maskesinde ayırıcı ya da boşluk (+-()./) olamaz"),
|
|
236
|
-
pattern: z.string().optional().describe("pattern türünde: '#' açık karakter, diğerleri olduğu gibi yazılır")
|
|
237
|
-
}).optional().describe('masked ve masked-encrypted modunda zorunlu'),
|
|
238
|
-
exactSearch: z.boolean().optional().describe('Şifreli modda tam eşleşme araması için blind index (HMAC) kolonu'),
|
|
239
|
-
normalize: z.enum(['none', 'digits', 'lower', 'trim']).optional().describe('Eşleşme ve blind index öncesi değeri normalleştirir (TCKN için digits)')
|
|
240
|
-
}),
|
|
241
|
-
policyOverride: z.boolean().optional().describe('true: politika block bulgularını warn\'a indirir (bilinçli istisna; yanıtta işaretlenir)')
|
|
242
|
-
},
|
|
243
|
-
annotations: updates
|
|
244
|
-
}, handle(config, async ({ project, environment, entityId, field, protection, policyOverride }) => {
|
|
245
|
-
const resolver = new RefResolver(platform, project, environment);
|
|
246
|
-
const entity = await resolver.entity(entityId);
|
|
247
|
-
const record = await resolver.entityRecord(entity);
|
|
248
|
-
const fields = (Array.isArray(record.fields) ? record.fields : []);
|
|
249
|
-
const target = fields.find(entry => entry.id === field || entry.slug === field);
|
|
250
|
-
if (!target) {
|
|
251
|
-
throw new PlatformApiError(`entity_protection_update: '${field}' alanı '${entity.slug}' entity'sinde yok. Alanları entity_get view:'outline' ile görün.`, 404);
|
|
252
|
-
}
|
|
253
|
-
const findings = config.policyMode === 'off' ? [] : enforcePolicy(applyPolicyMode(config, fieldProtectionFindings([{ ...target, protection }]), policyOverride));
|
|
254
|
-
const payload = await platform.tenant('POST', project, `/entities/${entity.entityId}/fields/${String(target.id)}/protection`, { environment, body: { protection } });
|
|
255
|
-
const jobId = payload?.data?.jobId ?? payload?.data?.dataJobId;
|
|
256
|
-
return attachFindings(withResolved({
|
|
257
|
-
jobId,
|
|
258
|
-
field: target.slug,
|
|
259
|
-
mode: protection.mode,
|
|
260
|
-
note: `Koruma işi kuyruğa alındı. İlerleme: import_status { jobId: '${String(jobId)}' }. İş bitene kadar '${entity.slug}' entity'sine yazım 409 döner ve okumalar geçiş durumundadır (işlenmiş satırlar maskeli, işlenmemişler düz). Anahtar yapılandırılmamış ortamda iş ProtectionKeyUnavailable ile düşer.`
|
|
261
|
-
}, resolver.resolved), findings);
|
|
262
|
-
}));
|
|
263
198
|
server.registerTool('entity_delete', {
|
|
264
199
|
title: 'Entity sil',
|
|
265
200
|
description: 'Entity tanımını siler; önce entity_dependencies ile bağımlılıklarını kontrol edin.',
|
|
@@ -302,15 +237,13 @@ export function registerEntityTools(server, platform) {
|
|
|
302
237
|
}, handle(config, ({ project, environment, id }) => platform.tenant('GET', project, `/entities/${id}/dependencies`, { environment })));
|
|
303
238
|
server.registerTool('entity_audit_trails', {
|
|
304
239
|
title: 'Audit kayıtları',
|
|
305
|
-
description: 'Entity\'nin satır bazlı audit trail kayıtlarını listeler (audit trail açık olmalı).
|
|
240
|
+
description: 'Entity\'nin satır bazlı audit trail kayıtlarını listeler (audit trail açık olmalı).',
|
|
306
241
|
inputSchema: {
|
|
307
242
|
project: projectParam,
|
|
308
243
|
environment: environmentParam,
|
|
309
244
|
entityId: guid,
|
|
310
245
|
rowId: z.string().optional(),
|
|
311
246
|
userId: z.string().optional(),
|
|
312
|
-
action: z.enum(['CREATE', 'UPDATE', 'DELETE', 'REVEAL', 'UNRESTRICTED-QUERY']).optional(),
|
|
313
|
-
source: z.enum(['PLATFORM', 'APPLICATION', 'CONNECT_DATA']).optional(),
|
|
314
247
|
...pagingParams
|
|
315
248
|
},
|
|
316
249
|
annotations: readOnly
|
|
@@ -7,23 +7,6 @@ import { z } from 'zod';
|
|
|
7
7
|
import { evaluatePolicy, enforcePolicy } from '../knowledge/policy.js';
|
|
8
8
|
import { policyRules } from '../knowledge/rules.js';
|
|
9
9
|
import { EXTERNAL_COMPONENT_PROTOCOL_VERSION } from '../knowledge/backendConstraints.js';
|
|
10
|
-
import { resolveProfile } from '../knowledge/platform/resolve.js';
|
|
11
|
-
import { findingLine } from '../knowledge/platform/profile.js';
|
|
12
|
-
/**
|
|
13
|
-
* MOB-006 — harici bileşen protokolü v1 tarayıcıda koşan `.mjs` custom element'tir; mobil
|
|
14
|
-
* uygulamanın native çizeri onu yükleyemez (mobil protokol v2 Faz 3). Profil kapalı derse çağrı
|
|
15
|
-
* platforma GİTMEZ: yüklenen paket hiçbir ekranda çizilmeyecekti.
|
|
16
|
-
*/
|
|
17
|
-
async function assertExternalComponentsAllowed(platform, applicationId, tool) {
|
|
18
|
-
const resolved = await resolveProfile(platform, applicationId);
|
|
19
|
-
if (resolved.profile.externalComponents)
|
|
20
|
-
return;
|
|
21
|
-
throw new PlatformApiError(`${tool}: ${findingLine({
|
|
22
|
-
code: 'MOB-006',
|
|
23
|
-
severity: 'warn',
|
|
24
|
-
message: "harici bileşen mobil uygulamada desteklenmiyor — protokol v1 tarayıcıda koşan .mjs custom element'tir, native çizer onu yükleyemez (mobil protokol v2 Faz 3). Çağrı platforma gönderilmedi; mobil ekranı katalog bileşenleriyle kurun (component_list). Katalogda karşılığı olmayan küçük görünüm için geçici yol 'html' bileşenidir: içerik korumalı belgede tema değişkenleriyle çizilir, fireEvent/ngApps.emit ile akışa bağlanır (component_get('html'))."
|
|
25
|
-
})}`, 400);
|
|
26
|
-
}
|
|
27
10
|
/** Platformun köprü protokolü; scaffold ve publish bu sürüme göre üretir/doğrular (backend ExternalComponentRules.CurrentProtocolVersion) */
|
|
28
11
|
const PROTOCOL_VERSION = EXTERNAL_COMPONENT_PROTOCOL_VERSION;
|
|
29
12
|
/** Backend `ExternalComponentRules.MaxBundleSizeBytes` ile aynı sınır */
|
|
@@ -216,7 +199,6 @@ export function registerExternalComponentTools(server, platform) {
|
|
|
216
199
|
},
|
|
217
200
|
annotations: writes
|
|
218
201
|
}, handle(config, async ({ project, environment, applicationId, bundlePath, manifestPath, version }) => {
|
|
219
|
-
await assertExternalComponentsAllowed(platform, applicationId, 'external_component_publish');
|
|
220
202
|
const manifestFile = resolve(manifestPath);
|
|
221
203
|
const bundleFile = resolve(bundlePath);
|
|
222
204
|
let manifest;
|
|
@@ -242,7 +224,7 @@ export function registerExternalComponentTools(server, platform) {
|
|
|
242
224
|
}
|
|
243
225
|
// EXT-001: protocolVersion, definition.blocks, ayrılmış prop adları ve prop tipleri — kayıt
|
|
244
226
|
// ucu 422 dönmeden manifest'te yakalanır; paket yükleme ikinci istek olduğu için yarım kayıt kalmaz.
|
|
245
|
-
enforcePolicy(evaluatePolicy(config, policyRules, 'externalComponent', { ...manifest, slug }, { operation: 'create' })
|
|
227
|
+
enforcePolicy(evaluatePolicy(config, policyRules, 'externalComponent', { ...manifest, slug }, { operation: 'create' }));
|
|
246
228
|
const record = await platform.tenant('POST', project, `/components/${applicationId}/external`, {
|
|
247
229
|
environment,
|
|
248
230
|
body: {
|
|
@@ -280,13 +262,10 @@ export function registerExternalComponentTools(server, platform) {
|
|
|
280
262
|
acknowledgeWarnings: z.boolean().optional().describe('Doğrulama uyarılarını okuyup kabul ettiğinizi bildirir; uyarısı olan sürümlerde zorunlu')
|
|
281
263
|
},
|
|
282
264
|
annotations: updates
|
|
283
|
-
}, handle(config,
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
body: { version, acknowledgeWarnings: acknowledgeWarnings === true }
|
|
288
|
-
});
|
|
289
|
-
}));
|
|
265
|
+
}, handle(config, ({ project, environment, applicationId, slug, version, acknowledgeWarnings }) => platform.tenant('POST', project, `/components/${applicationId}/external/${slug}/activate`, {
|
|
266
|
+
environment,
|
|
267
|
+
body: { version, acknowledgeWarnings: acknowledgeWarnings === true }
|
|
268
|
+
})));
|
|
290
269
|
server.registerTool('external_component_versions', {
|
|
291
270
|
title: 'Paket sürümlerini listele',
|
|
292
271
|
description: 'Bir harici komponentin yayınlanmış paket sürümlerini, hangisinin aktif olduğunu ve her sürümün doğrulama raporunu listeler. Geri alınacak sürümü buradan seçin.',
|
package/dist/tools/flows.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { fetchHost, flowPath, hostParam, unwrap } from './screens.js';
|
|
2
2
|
import { guid, projectParam, environmentParam, readOnly, writes, updates, destructive, microOps } from './common.js';
|
|
3
|
-
import {
|
|
4
|
-
import { connectedSetterFindings } from '../knowledge/connectDataDefinition.js';
|
|
3
|
+
import { evaluatePolicy, enforcePolicy, attachFindings } from '../knowledge/policy.js';
|
|
5
4
|
import { flowBindings, normalizeFlowSteps, targetlessSetterWarnings, unknownSetterTargetWarnings, withNormalization } from '../knowledge/normalize.js';
|
|
6
5
|
import { flowBodyWarnings } from '../knowledge/coverage.js';
|
|
7
6
|
import { PlatformApiError } from '../platform/errors.js';
|
|
@@ -14,8 +13,6 @@ import { policyRules, flowExpressionSites } from '../knowledge/rules.js';
|
|
|
14
13
|
import { functionCallRefs } from '../knowledge/functionGuards.js';
|
|
15
14
|
import { existingMatch, ifExistsParam, platformRename, withRename } from '../platform/ifExists.js';
|
|
16
15
|
import { randomUUID } from 'node:crypto';
|
|
17
|
-
import { flowProfileWarnings } from './profileWrite.js';
|
|
18
|
-
import { jsonArray } from '../platform/jsonArray.js';
|
|
19
16
|
import { z } from 'zod';
|
|
20
17
|
/**
|
|
21
18
|
* Akış yazması yanıtında gövdeyi geri döndürmüyor, bu yüzden diff için akışı bir kez okuruz.
|
|
@@ -37,9 +34,9 @@ async function flowWriteDrops(platform, host, project, environment, applicationI
|
|
|
37
34
|
return emptyWriteDiff();
|
|
38
35
|
}
|
|
39
36
|
}
|
|
40
|
-
const stepsParam =
|
|
37
|
+
const stepsParam = z.array(z.record(z.unknown())).describe("Adım listesi (StepManagementSchema: { stepId, name, type, kind, args, branches }). DİKKAT: branches[].nextStepId bir GUID değil, hedef adımın stepId STRING'idir; dal ADI motorun anahtarıdır ve start/setter/code/function adımlarında 'always' olmak zorundadır. Tam şablon: ngapps://examples/flow-load-table (ya da flow_get çıktısı); adım tipleri ve setter/parameters şekli platform_guide('page') Kural 1c. Kullanıcı fonksiyonu çağırmak için 'function' adımı: { type:'function', args:{ functionId:'<function_list id>', functionName:'<ad>', parameters:[{ name:'<bildirimdeki ad>', value:{ type:'static'|'property'|'storage'|'state'|'code', ref } }] } } → çıktı Steps.<adımAdı>.data (ngapps://examples/flow-call-function, platform_guide('functions')).");
|
|
41
38
|
const policyOverrideParam = z.boolean().optional();
|
|
42
|
-
const patchOperationsParam =
|
|
39
|
+
const patchOperationsParam = z.array(z.record(z.unknown())).min(1).describe("RFC 6902 JSON Patch işlemleri; yolları flow_get çıktısıyla keşfedin. Dizi öğelerinde indeks yerine seçici kullanılabilir: '/steps[stepId=paint]/args/iteratees[element=tbl_recruiters]/mapping/source' — seçici gövde platforma gitmeden indekse çevrilir, çözülemezse istek hiç gönderilmez.");
|
|
43
40
|
const flowIdParam = guid.describe("Akış id'si; şemadaki events[].value bu id'dir");
|
|
44
41
|
function flowSummary(flow) {
|
|
45
42
|
return {
|
|
@@ -59,27 +56,6 @@ function hostNodes(record) {
|
|
|
59
56
|
return record.schema ?? record.views ?? [];
|
|
60
57
|
}
|
|
61
58
|
const BINDINGS_UNAVAILABLE = 'Barındırıcı kaydı okunamadığı için olay bağları hesaplanamadı; akış listesi yine de günceldir.';
|
|
62
|
-
/**
|
|
63
|
-
* TB-126 / S2-36 — satır aksiyonu taşıyabilen komponentler. Bu tiplerin `actions` prop'unu çoğu
|
|
64
|
-
* zaman YÜKLEME AKIŞI çalışma zamanında yazar (aksiyon role göre eklenip çıkarılıyorsa başka yolu
|
|
65
|
-
* da yoktur), yani bağ statik şemada GÖRÜNMEZ. Böyle bir sayfada "bağsız akışları temizle" refleksi
|
|
66
|
-
* canlı aksiyonu siler; `unboundFlowIds` bu yüzden dürüstçe işaretlenir.
|
|
67
|
-
*/
|
|
68
|
-
const RUNTIME_ACTION_TYPES = new Set(['table', 'datatable']);
|
|
69
|
-
const RUNTIME_BINDING_NOTE = 'Bu barındırıcıda satır aksiyonu taşıyan bir tablo var: satır aksiyonları çalışma zamanında yazılabilir, '
|
|
70
|
-
+ 'silmeden önce doğrulayın — unboundFlowIds statik şemadan hesaplanır ve çalışma zamanı bağını göremez.';
|
|
71
|
-
function hasRuntimeActionHost(nodes) {
|
|
72
|
-
for (const node of Array.isArray(nodes) ? nodes : []) {
|
|
73
|
-
if (!node || typeof node !== 'object')
|
|
74
|
-
continue;
|
|
75
|
-
const record = node;
|
|
76
|
-
if (typeof record.type === 'string' && RUNTIME_ACTION_TYPES.has(record.type))
|
|
77
|
-
return true;
|
|
78
|
-
if (hasRuntimeActionHost(record.children))
|
|
79
|
-
return true;
|
|
80
|
-
}
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
59
|
/**
|
|
84
60
|
* Akış listesine bağları ekler. `danglingBindings` ters yönü söyler: şemada id'si geçen ama
|
|
85
61
|
* barındırıcıda karşılığı olmayan akış — olay tetiklenir, hiçbir şey koşmaz.
|
|
@@ -92,12 +68,9 @@ function flowListResult(flows, record) {
|
|
|
92
68
|
const danglingBindings = [...bindings.entries()]
|
|
93
69
|
.filter(([flowId]) => !known.has(flowId))
|
|
94
70
|
.flatMap(([flowId, entries]) => entries.map(entry => ({ flowId, ...entry })));
|
|
95
|
-
const unboundFlowIds = flows.map(flow => String(flow.id)).filter(flowId => !bindings.has(flowId.toLowerCase()));
|
|
96
|
-
const mayBeBoundAtRuntime = unboundFlowIds.length > 0 && hasRuntimeActionHost(hostNodes(record));
|
|
97
71
|
return {
|
|
98
72
|
flows: flows.map(flow => ({ ...flowSummary(flow), bindings: bindings.get(String(flow.id).toLowerCase()) ?? [] })),
|
|
99
|
-
unboundFlowIds,
|
|
100
|
-
...(mayBeBoundAtRuntime ? { mayBeBoundAtRuntime: true, mayBeBoundAtRuntimeNote: RUNTIME_BINDING_NOTE } : {}),
|
|
73
|
+
unboundFlowIds: flows.map(flow => String(flow.id)).filter(flowId => !bindings.has(flowId.toLowerCase())),
|
|
101
74
|
...(danglingBindings.length > 0 ? { danglingBindings } : {})
|
|
102
75
|
};
|
|
103
76
|
}
|
|
@@ -301,7 +274,7 @@ async function functionWarnings(platform, host, project, environment, applicatio
|
|
|
301
274
|
}
|
|
302
275
|
const missing = fn.parameters.filter(parameter => parameter.required && !given.includes(parameter.name)).map(parameter => parameter.name);
|
|
303
276
|
if (missing.length > 0) {
|
|
304
|
-
warnings.add(`FLOW-024: '${label(step)}' adımında '${fn.name}' fonksiyonunun zorunlu parametresi eksik: ${missing.join(', ')} — çağrı 'Functions.${fn.name}: "${missing[0]}" is required' ile düşer, Steps.${String(step.name ?? label(step))}.error
|
|
277
|
+
warnings.add(`FLOW-024: '${label(step)}' adımında '${fn.name}' fonksiyonunun zorunlu parametresi eksik: ${missing.join(', ')} — çağrı 'Functions.${fn.name}: "${missing[0]}" is required' ile düşer, Steps.${String(step.name ?? label(step))}.error dolar ve akış hata gövdesiyle 'always' dalından devam eder.`);
|
|
305
278
|
}
|
|
306
279
|
}
|
|
307
280
|
for (const { step, origin, ref } of callSites) {
|
|
@@ -322,65 +295,11 @@ async function functionWarnings(platform, host, project, environment, applicatio
|
|
|
322
295
|
}
|
|
323
296
|
return [...warnings];
|
|
324
297
|
}
|
|
325
|
-
/**
|
|
326
|
-
* FLOW-036 (g-02, ADR 0004 — ZM-07). `microservice.ts` `.finally` üç yoldan birini dener: adımın
|
|
327
|
-
* kendi `error` dalı bağlıysa oradan sürer, yoksa flow `errorSteps`'i (`engine.onError`) devralır,
|
|
328
|
-
* ikisi de yoksa `always` koşar ve storage artık `{ data: null, headers: null, error }`'dır — hata
|
|
329
|
-
* gövdesi ARTIK `data`'da DEĞİL. İkisi de bağlı değilken bu adımın `.data`'sını okuyan bir
|
|
330
|
-
* setter/condition varsa hata anında NULL üzerinden koşar ve yazar hiç fark etmez. Aynı yürüyüş
|
|
331
|
-
* FLOW-024/025'in kullandığı `flowExpressionSites` taramasıdır; setter'ın STORAGE (kod olmayan)
|
|
332
|
-
* referansı ayrıca kendi düz alanından okunur (FLOW-008/009 deseni, `rowsTargetsByStepName`).
|
|
333
|
-
*/
|
|
334
|
-
function microserviceAlwaysDataWarnings(steps, errorSteps) {
|
|
335
|
-
const mainSteps = (Array.isArray(steps) ? steps : []).filter(isRecord);
|
|
336
|
-
const hasErrorFlow = (Array.isArray(errorSteps) ? errorSteps : []).filter(isRecord).some(step => String(step.type ?? '') !== 'start');
|
|
337
|
-
const label = (step) => String(step.stepId ?? step.name ?? '?');
|
|
338
|
-
const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
339
|
-
const warnings = new Set();
|
|
340
|
-
for (const step of mainSteps) {
|
|
341
|
-
if (String(step.type ?? '') !== 'microservice')
|
|
342
|
-
continue;
|
|
343
|
-
const name = String(step.name ?? step.stepId ?? '');
|
|
344
|
-
if (name === '')
|
|
345
|
-
continue;
|
|
346
|
-
const hasErrorBranch = (Array.isArray(step.branches) ? step.branches : [])
|
|
347
|
-
.filter(isRecord)
|
|
348
|
-
.some(branch => String(branch.name ?? '') === 'error' && Boolean(branch.nextStepId));
|
|
349
|
-
if (hasErrorBranch || hasErrorFlow)
|
|
350
|
-
continue;
|
|
351
|
-
const pattern = new RegExp(`Steps\\s*(?:\\.\\s*${escapeRegExp(name)}\\b|\\[\\s*['"]${escapeRegExp(name)}['"]\\s*\\])\\s*\\??\\.\\s*data\\b`);
|
|
352
|
-
const message = (other) => `FLOW-036: '${label(other)}' adımı 'always' dalında '${name}.data' okuyor ama '${name}' adımının ne bağlı bir 'error' dalı ne akışın 'errorSteps'i var — uç hata dönerse bu adımın 'data'sı NULL olur (eskiden hata gövdesiydi, ADR 0004) ve '${label(other)}' boş/null veriyle koşar. '${name}' adımına 'error' dalı bağlayın ya da flow'a errorSteps verin.`;
|
|
353
|
-
for (const other of mainSteps) {
|
|
354
|
-
if (other === step)
|
|
355
|
-
continue;
|
|
356
|
-
if (String(other.type ?? '') === 'setter') {
|
|
357
|
-
const iteratees = Array.isArray(other.args?.iteratees)
|
|
358
|
-
? other.args.iteratees.filter(isRecord)
|
|
359
|
-
: [];
|
|
360
|
-
for (const iteratee of iteratees) {
|
|
361
|
-
const mapping = (iteratee.mapping ?? {});
|
|
362
|
-
const value = (iteratee.value ?? {});
|
|
363
|
-
const reference = typeof mapping.source === 'string' && mapping.source.length > 0
|
|
364
|
-
? mapping.source
|
|
365
|
-
: typeof value.ref === 'string' ? value.ref : '';
|
|
366
|
-
if (value.type === 'storage' && (reference === `${name}.data` || reference.startsWith(`${name}.data.`) || reference.startsWith(`${name}.data[`))) {
|
|
367
|
-
warnings.add(message(other));
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
for (const site of flowExpressionSites(other)) {
|
|
372
|
-
if (pattern.test(site.expression))
|
|
373
|
-
warnings.add(message(other));
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
return [...warnings];
|
|
378
|
-
}
|
|
379
298
|
export function registerFlowTools(server, platform) {
|
|
380
299
|
const config = platform.config;
|
|
381
300
|
server.registerTool('flow_list', {
|
|
382
301
|
title: 'Akışları listele',
|
|
383
|
-
description: "Barındırıcının olay akışlarını, her birine bağlı olaylarla (bindings: [{ target: elementId | 'page', event }]) listeler. unboundFlowIds hiçbir olaya bağlı olmayan (sahipsiz) akışlardır; danglingBindings şemada id'si geçen ama barındırıcıda olmayan akışlardır.
|
|
302
|
+
description: "Barındırıcının olay akışlarını, her birine bağlı olaylarla (bindings: [{ target: elementId | 'page', event }]) listeler. unboundFlowIds hiçbir olaya bağlı olmayan (sahipsiz) akışlardır; danglingBindings şemada id'si geçen ama barındırıcıda olmayan akışlardır. Sayfa ve layout akışları önbelleksiz liste ucundan, widget akışları kaydın kendi gövdesinden okunur; bağlar barındırıcının şemasından hesaplanır.",
|
|
384
303
|
inputSchema: { project: projectParam, environment: environmentParam, host: hostParam, applicationId: guid, hostId: guid },
|
|
385
304
|
annotations: readOnly
|
|
386
305
|
}, handle(config, async ({ project, environment, host, applicationId, hostId }) => {
|
|
@@ -442,18 +361,14 @@ export function registerFlowTools(server, platform) {
|
|
|
442
361
|
...(host === 'page' ? { pageId: hostId } : host === 'layout' ? { layoutId: hostId } : { componentId: hostId })
|
|
443
362
|
};
|
|
444
363
|
const normalized = [...normalizeFlowSteps(flow.steps), ...normalizeFlowSteps(flow.errorSteps)];
|
|
445
|
-
const findings =
|
|
446
|
-
...enforcePolicy(evaluatePolicy(config, policyRules, 'flow', flow, { operation: 'create' }, policyOverride)),
|
|
447
|
-
...enforcePolicy(config.policyMode === 'off' ? [] : applyPolicyMode(config, connectedSetterFindings(steps, errorSteps ?? [], hostNodes(hostRecord)), policyOverride))
|
|
448
|
-
];
|
|
364
|
+
const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'flow', flow, { operation: 'create' }, policyOverride));
|
|
449
365
|
const existing = await existingFlowMatch(platform, host, project, environment, applicationId, hostId, hostRecord, name, slug, flowId, ifExists);
|
|
450
366
|
const writtenFlowId = existing === undefined ? resolvedFlowId : String(existing.id);
|
|
451
367
|
const parameterWarnings = [
|
|
452
368
|
...await requiredParameterWarnings(platform, project, environment, applicationId, steps),
|
|
453
369
|
...await functionWarnings(platform, host, project, environment, applicationId, hostId, steps),
|
|
454
370
|
...flowBodyWarnings(steps),
|
|
455
|
-
...unknownSetterTargetWarnings(steps, errorSteps ?? [], hostNodes(hostRecord))
|
|
456
|
-
...microserviceAlwaysDataWarnings(steps, errorSteps ?? [])
|
|
371
|
+
...unknownSetterTargetWarnings(steps, errorSteps ?? [], hostNodes(hostRecord))
|
|
457
372
|
];
|
|
458
373
|
// Gövde yalnız akıştır (designer-partial-update K1): barındırıcı zarfı platformda hâlâ isteğe bağlı
|
|
459
374
|
// ama gönderilirse okunan tam kaydı yeniden yazar, açık Studio designer'ının kayıtlı tabanını
|
|
@@ -467,7 +382,6 @@ export function registerFlowTools(server, platform) {
|
|
|
467
382
|
// Diff YALNIZ çağıranın yazdığı alanları kapsar; `id` ve barındırıcı bağı (`pageId` vb.)
|
|
468
383
|
// gövdeye gateway koyar, kullanıcının düzeltebileceği bir şey değildir.
|
|
469
384
|
const drops = await flowWriteDrops(platform, host, project, environment, applicationId, hostId, writtenFlowId, { name: flow.name, slug: flow.slug, steps: flow.steps, errorSteps: flow.errorSteps }, ifExists === 'duplicate');
|
|
470
|
-
const platformWarnings = await flowProfileWarnings(platform, applicationId, [...(flow.steps ?? []), ...(flow.errorSteps ?? [])]);
|
|
471
385
|
return attachFindings(withWriteDiff(withRename(withNormalization({
|
|
472
386
|
host,
|
|
473
387
|
hostId,
|
|
@@ -479,7 +393,6 @@ export function registerFlowTools(server, platform) {
|
|
|
479
393
|
steps: steps.length
|
|
480
394
|
},
|
|
481
395
|
...(parameterWarnings.length > 0 ? { parameterWarnings } : {}),
|
|
482
|
-
...(platformWarnings.length > 0 ? { platformWarnings } : {}),
|
|
483
396
|
hint: "Akışı bir olaya bağlamak için: page_schema_patch (layout'ta layout_schema_patch, widget'ta component_schema_patch) ops:[{op:'set_event', target:<elementId>, event:'<component_get events listesindeki ad>', eventValue:<flow id>}]; olayda zaten akış bağlıysa ikinciyi add_event ile ekleyin (set_event bağlı akışı değiştirir, PAGE-034). Olay adları komponente özeldir ve 'on' ÖNEKİ ALMAZ (button → 'click', form → 'submit', table → 'mount'/'select'/'sort'…); uydurma ad 200 döner ama bağ sessizce ölü kalır — gateway PAGE-008 ile yakalar."
|
|
484
397
|
}, normalized), drops.renamed), drops), findings);
|
|
485
398
|
}));
|
|
@@ -516,17 +429,13 @@ export function registerFlowTools(server, platform) {
|
|
|
516
429
|
const authored = { steps: steps ?? [], errorSteps: errorSteps ?? [] };
|
|
517
430
|
const normalized = [...normalizeFlowSteps(authored.steps), ...normalizeFlowSteps(authored.errorSteps)];
|
|
518
431
|
const findings = steps || errorSteps
|
|
519
|
-
?
|
|
520
|
-
...enforcePolicy(evaluatePolicy(config, policyRules, 'flow', authored, { operation: 'update' }, policyOverride)),
|
|
521
|
-
...enforcePolicy(config.policyMode === 'off' ? [] : applyPolicyMode(config, connectedSetterFindings(authored.steps, authored.errorSteps, hostNodes(hostRecord)), policyOverride))
|
|
522
|
-
]
|
|
432
|
+
? enforcePolicy(evaluatePolicy(config, policyRules, 'flow', authored, { operation: 'update' }, policyOverride))
|
|
523
433
|
: [];
|
|
524
434
|
const parameterWarnings = [
|
|
525
435
|
...await requiredParameterWarnings(platform, project, environment, applicationId, flow.steps),
|
|
526
436
|
...await functionWarnings(platform, host, project, environment, applicationId, hostId, flow.steps),
|
|
527
437
|
...flowBodyWarnings(flow.steps),
|
|
528
|
-
...unknownSetterTargetWarnings(flow.steps, flow.errorSteps, hostNodes(hostRecord))
|
|
529
|
-
...microserviceAlwaysDataWarnings(flow.steps, flow.errorSteps)
|
|
438
|
+
...unknownSetterTargetWarnings(flow.steps, flow.errorSteps, hostNodes(hostRecord))
|
|
530
439
|
];
|
|
531
440
|
await platform.tenant('PUT', project, flowPath(host, applicationId, hostId, flowId), { environment, body: { flow } });
|
|
532
441
|
// Kısmi güncellemede yalnız GÖNDERİLEN alanlar karşılaştırılır; verilmeyen alan için
|
|
@@ -537,9 +446,7 @@ export function registerFlowTools(server, platform) {
|
|
|
537
446
|
...(steps === undefined ? {} : { steps }),
|
|
538
447
|
...(errorSteps === undefined ? {} : { errorSteps })
|
|
539
448
|
});
|
|
540
|
-
|
|
541
|
-
return attachFindings(withWriteDiff(withNormalization({ host, hostId, flow: flowSummary(flow), ...(parameterWarnings.length > 0 ? { parameterWarnings } : {}),
|
|
542
|
-
...(platformWarnings.length > 0 ? { platformWarnings } : {}) }, normalized), drops), findings);
|
|
449
|
+
return attachFindings(withWriteDiff(withNormalization({ host, hostId, flow: flowSummary(flow), ...(parameterWarnings.length > 0 ? { parameterWarnings } : {}) }, normalized), drops), findings);
|
|
543
450
|
}));
|
|
544
451
|
server.registerTool('flow_patch', {
|
|
545
452
|
title: "Akışa patch uygula",
|
|
@@ -573,16 +480,12 @@ export function registerFlowTools(server, platform) {
|
|
|
573
480
|
...(host === 'page' ? { pageId: hostId } : host === 'layout' ? { layoutId: hostId } : { componentId: hostId })
|
|
574
481
|
};
|
|
575
482
|
const normalized = [...normalizeFlowSteps(flow.steps), ...normalizeFlowSteps(flow.errorSteps)];
|
|
576
|
-
const findings =
|
|
577
|
-
...enforcePolicy(evaluatePolicy(config, policyRules, 'flow', flow, { operation: 'update' }, policyOverride)),
|
|
578
|
-
...enforcePolicy(config.policyMode === 'off' ? [] : applyPolicyMode(config, connectedSetterFindings(flow.steps, flow.errorSteps, hostNodes(hostRecord)), policyOverride))
|
|
579
|
-
];
|
|
483
|
+
const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'flow', flow, { operation: 'update' }, policyOverride));
|
|
580
484
|
const parameterWarnings = [
|
|
581
485
|
...await requiredParameterWarnings(platform, project, environment, applicationId, flow.steps),
|
|
582
486
|
...await functionWarnings(platform, host, project, environment, applicationId, hostId, flow.steps),
|
|
583
487
|
...flowBodyWarnings(flow.steps),
|
|
584
|
-
...unknownSetterTargetWarnings(flow.steps, flow.errorSteps, hostNodes(hostRecord))
|
|
585
|
-
...microserviceAlwaysDataWarnings(flow.steps, flow.errorSteps)
|
|
488
|
+
...unknownSetterTargetWarnings(flow.steps, flow.errorSteps, hostNodes(hostRecord))
|
|
586
489
|
];
|
|
587
490
|
// Gövde değil FARK gönderilir; platform PATCH ucu akışı tek başına yazar. Net diff okunan kayıt ile son hâl arasından hesaplanır.
|
|
588
491
|
const netOps = fastJsonPatch.compare(current, flow);
|
|
@@ -592,7 +495,6 @@ export function registerFlowTools(server, platform) {
|
|
|
592
495
|
});
|
|
593
496
|
const written = patchResult(saved, flow);
|
|
594
497
|
const drops = await flowWriteDrops(platform, host, project, environment, applicationId, hostId, flowId, { steps: flow.steps, errorSteps: flow.errorSteps });
|
|
595
|
-
const platformWarnings = await flowProfileWarnings(platform, applicationId, [...(flow.steps ?? []), ...(flow.errorSteps ?? [])]);
|
|
596
498
|
return attachFindings(withWriteDiff(withNormalization({
|
|
597
499
|
host,
|
|
598
500
|
hostId,
|
|
@@ -600,8 +502,7 @@ export function registerFlowTools(server, platform) {
|
|
|
600
502
|
newVersion: written.newVersion,
|
|
601
503
|
patchTargets: resolved.targets,
|
|
602
504
|
flow: flowSummary(written.data),
|
|
603
|
-
...(parameterWarnings.length > 0 ? { parameterWarnings } : {})
|
|
604
|
-
...(platformWarnings.length > 0 ? { platformWarnings } : {})
|
|
505
|
+
...(parameterWarnings.length > 0 ? { parameterWarnings } : {})
|
|
605
506
|
}, [...normalized, ...resolved.notes.map(note => `patch yolu seçiciden indekse çözüldü: ${note}`)]), drops), findings);
|
|
606
507
|
}));
|
|
607
508
|
server.registerTool('flow_delete', {
|
|
@@ -613,13 +514,4 @@ export function registerFlowTools(server, platform) {
|
|
|
613
514
|
await platform.tenant('DELETE', project, flowPath(host, applicationId, hostId, flowId), { environment, body: { id: flowId } });
|
|
614
515
|
return { deleted: flowId, host, hostId };
|
|
615
516
|
}));
|
|
616
|
-
server.registerTool('flow_restore', {
|
|
617
|
-
title: 'Silinen akışı geri yükle',
|
|
618
|
-
description: "Silinmiş bir akışı revizyon defterindeki son içeriğiyle (ad, slug, adımlar, barındırıcı) AYNI id ile yeniden kurar. Sayfa kaydı bağı kalmayan akışı kalıcı siler (FLOW-002, allowFlowDeletion) — Studio'nun eski sekmesi boş şema kaydettiğinde de (ZM-27). Akışı olaya YENİDEN BAĞLAMAZ: geri geldikten sonra set_event ile bağlayın. SINIR: adımları sayfanın bir komponentini hedefliyorsa (tetikleyen element, iterate/parametre komponenti) o komponent de şemada olmalıdır, yoksa geri yükleme reddedilir — sayfa boşaldıysa (ZM-27) page_restore kullanın: sayfayı ve akışlarını birlikte geri kurar. Akış hâlâ varsa 409, saklama süresi dolup revizyonu budanmışsa 404 döner. Silinen akışı revision_list(module: 'flow') satırlarında operation: delete olarak bulun; recordId akış id'sidir.",
|
|
619
|
-
inputSchema: { project: projectParam, environment: environmentParam, flowId: flowIdParam },
|
|
620
|
-
annotations: writes
|
|
621
|
-
}, handle(config, async ({ project, environment, flowId }) => {
|
|
622
|
-
const restored = unwrap(await platform.tenant('POST', project, `/flows/${flowId}/restore`, { environment }));
|
|
623
|
-
return { restored: flowId, flow: restored };
|
|
624
|
-
}));
|
|
625
517
|
}
|
package/dist/tools/folders.js
CHANGED
|
@@ -23,7 +23,7 @@ export function registerFolderTools(server, platform) {
|
|
|
23
23
|
inputSchema: { project: projectParam, environment: environmentParam, definition: definitionParam },
|
|
24
24
|
annotations: writes
|
|
25
25
|
}, handle(config, async ({ project, environment, definition }) => {
|
|
26
|
-
const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'folder', definition, { operation: 'create' })
|
|
26
|
+
const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'folder', definition, { operation: 'create' }));
|
|
27
27
|
return attachFindings(await platform.tenant('POST', project, '/folders', { environment, body: definition }), findings);
|
|
28
28
|
}));
|
|
29
29
|
server.registerTool('folder_update', {
|
package/dist/tools/imports.js
CHANGED
|
@@ -182,10 +182,7 @@ export function registerImportTools(server, platform) {
|
|
|
182
182
|
return { ...payload, note: "Plan henüz çalıştırılmadı: import_run { datasourceId, planId } ile başlatın — planId bu jobId'dir ve plan bir saat geçerlidir." };
|
|
183
183
|
}
|
|
184
184
|
if (status === 'failed') {
|
|
185
|
-
|
|
186
|
-
// otomatik yeniden deneme yok, kurtarma aynı isteği aynı gövdeyle tekrarlamaktır (TB-31).
|
|
187
|
-
const isProtection = job?.kind === 'protection-apply' || job?.kind === 'protection-remove';
|
|
188
|
-
return { ...payload, note: `İş düştü; \`error\` alanı nedeni söyler.${isImport ? ' Yazılmış partiler yerinde kalır; bugün geri alınamaz.' : ''}${isProtection ? " Koruma işi: alan geçiş durumunda kalır ve entity'ye yazım 409 döner. Nedeni giderdikten sonra AYNI entity_protection_update çağrısını AYNI gövdeyle tekrarlayın — iş kaldığı yerden sürer (TB-31)." : ''}` };
|
|
185
|
+
return { ...payload, note: `İş düştü; \`error\` alanı nedeni söyler.${isImport ? ' Yazılmış partiler yerinde kalır; bugün geri alınamaz.' : ''}` };
|
|
189
186
|
}
|
|
190
187
|
if (status === 'cancelled') {
|
|
191
188
|
return { ...payload, note: `İş iptal edildi.${isImport ? ' Yazılmış partiler yerinde kalır; bugün geri alınamaz.' : ''}` };
|
|
@@ -194,7 +191,7 @@ export function registerImportTools(server, platform) {
|
|
|
194
191
|
}));
|
|
195
192
|
server.registerTool('import_history', {
|
|
196
193
|
title: 'Veri işleri geçmişi',
|
|
197
|
-
description: "Projedeki içe/dışa aktarma
|
|
194
|
+
description: "Projedeki içe/dışa aktarma ve geri alma işlerini sayfalı listeler; order verilmezse en yeni iş önce gelir. Her satır kind, status, entityIds ve result taşır. kind: 'import' çalıştırılmamış planları (planned) da içerir; datasource filtresi yoktur. Geri alınabilir bir iş aramak (kind: 'import', status: 'completed', undoAvailableUntil geçmemiş) ya da düşen bir işin nedenini bulmak için kullanılır.",
|
|
198
195
|
inputSchema: {
|
|
199
196
|
project: projectParam,
|
|
200
197
|
environment: environmentParam,
|