@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.
Files changed (203) hide show
  1. package/.env.example +0 -15
  2. package/README.md +5 -5
  3. package/dist/config.js +0 -37
  4. package/dist/index.js +0 -2
  5. package/dist/knowledge/backendConstraints.js +1 -18
  6. package/dist/knowledge/boxSections.js +184 -0
  7. package/dist/knowledge/componentCatalog.js +232 -562
  8. package/dist/knowledge/componentEvents.js +21 -141
  9. package/dist/knowledge/layoutSummary.js +2 -140
  10. package/dist/knowledge/normalize.js +67 -236
  11. package/dist/knowledge/outlines.js +0 -36
  12. package/dist/knowledge/policy.js +4 -18
  13. package/dist/knowledge/reservedTables.js +0 -79
  14. package/dist/knowledge/rules.js +21 -319
  15. package/dist/knowledge/schemaGuard.js +0 -11
  16. package/dist/knowledge/styleResolve.js +38 -55
  17. package/dist/knowledge/themeResolve.js +3 -3
  18. package/dist/observability/trace.js +3 -6
  19. package/dist/platform/diagnostics.js +4 -10
  20. package/dist/platform/domSummary.js +1 -1
  21. package/dist/platform/errors.js +10 -162
  22. package/dist/platform/http.js +8 -29
  23. package/dist/platform/responses.js +5 -39
  24. package/dist/platform/{capture/capture.js → screenshot.js} +519 -105
  25. package/dist/platform/secrets.js +1 -17
  26. package/dist/platform/strictArguments.js +12 -68
  27. package/dist/platform/tokenVault.js +4 -187
  28. package/dist/resources/examples/layout-app-shell.json +707 -229
  29. package/dist/resources/examples/page-detail-profile.json +1 -2
  30. package/dist/resources/examples/page-dynamic-form.json +2 -3
  31. package/dist/resources/examples/page-flex-sections.json +1 -1
  32. package/dist/resources/examples/page-html-embed.json +1 -1
  33. package/dist/resources/examples/workflow-basic.json +2 -8
  34. package/dist/resources/guides/component.md +4 -91
  35. package/dist/resources/guides/entity.md +8 -50
  36. package/dist/resources/guides/expressions.md +5 -14
  37. package/dist/resources/guides/functions.md +1 -1
  38. package/dist/resources/guides/getting-started.md +1 -38
  39. package/dist/resources/guides/layout.md +58 -55
  40. package/dist/resources/guides/microservice.md +2 -81
  41. package/dist/resources/guides/middleware.md +2 -44
  42. package/dist/resources/guides/page.md +75 -454
  43. package/dist/resources/guides/theme.md +2 -8
  44. package/dist/resources/guides/translation.md +1 -1
  45. package/dist/resources/guides/workflow.md +1 -58
  46. package/dist/resources/rules.js +5 -11
  47. package/dist/resources/schema-fingerprint.json +5 -7
  48. package/dist/resources/schemas/CreateEntityCommand.json +0 -118
  49. package/dist/resources/schemas/CreateMicroserviceCommand.json +1 -13
  50. package/dist/resources/schemas/CreateQueryCommand.json +0 -4
  51. package/dist/resources/schemas/CreateWorkflowCommand.json +1 -143
  52. package/dist/resources/schemas/DataJobDto.json +1 -6
  53. package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +1 -21
  54. package/dist/resources/schemas/MicroserviceDto.json +3 -15
  55. package/dist/resources/schemas/PreviewMicroserviceCommand.json +1 -10
  56. package/dist/resources/schemas/PreviewWorkflowCommand.json +1 -22
  57. package/dist/resources/schemas/StepDto.json +1 -22
  58. package/dist/resources/schemas/UpdateEntityCommand.json +0 -118
  59. package/dist/resources/schemas/UpdateMicroserviceCommand.json +1 -13
  60. package/dist/resources/schemas/UpdateQueryCommand.json +0 -4
  61. package/dist/resources/schemas/UpdateViewCommand.json +2 -0
  62. package/dist/resources/schemas/UpdateWorkflowCommand.json +1 -143
  63. package/dist/server.js +1 -27
  64. package/dist/tools/access.js +2 -369
  65. package/dist/tools/applications.js +3 -60
  66. package/dist/tools/common.js +0 -7
  67. package/dist/tools/components.js +14 -118
  68. package/dist/tools/datasources.js +3 -3
  69. package/dist/tools/dependencies.js +1 -1
  70. package/dist/tools/deployments.js +2 -2
  71. package/dist/tools/designSchemaPatch.js +18 -34
  72. package/dist/tools/dtos.js +5 -36
  73. package/dist/tools/entities.js +12 -79
  74. package/dist/tools/externalComponents.js +5 -26
  75. package/dist/tools/flows.js +14 -122
  76. package/dist/tools/folders.js +1 -1
  77. package/dist/tools/imports.js +2 -5
  78. package/dist/tools/layouts.js +17 -50
  79. package/dist/tools/merges.js +1 -1
  80. package/dist/tools/microservices.js +25 -77
  81. package/dist/tools/pages.js +112 -465
  82. package/dist/tools/platformInfo.js +8 -27
  83. package/dist/tools/projects.js +9 -71
  84. package/dist/tools/rows.js +13 -69
  85. package/dist/tools/schemaOps.js +1 -61
  86. package/dist/tools/screenWrite.js +8 -37
  87. package/dist/tools/screens.js +5 -95
  88. package/dist/tools/templates.js +1 -26
  89. package/dist/tools/translations.js +1 -1
  90. package/dist/tools/variables.js +5 -11
  91. package/dist/tools/workflows.js +5 -10
  92. package/package.json +2 -2
  93. package/dist/knowledge/access.js +0 -802
  94. package/dist/knowledge/case.js +0 -41
  95. package/dist/knowledge/connectDataBind.js +0 -819
  96. package/dist/knowledge/connectDataDefinition.js +0 -341
  97. package/dist/knowledge/connectDataExecute.js +0 -93
  98. package/dist/knowledge/connectDataRules.js +0 -128
  99. package/dist/knowledge/decision.js +0 -121
  100. package/dist/knowledge/expressionPrelude.js +0 -59
  101. package/dist/knowledge/microserviceParameters.js +0 -58
  102. package/dist/knowledge/mining.js +0 -94
  103. package/dist/knowledge/mobileComponentCatalog.js +0 -859
  104. package/dist/knowledge/mobileComponentEvents.js +0 -239
  105. package/dist/knowledge/platform/lint.js +0 -385
  106. package/dist/knowledge/platform/mobile.js +0 -142
  107. package/dist/knowledge/platform/mobileLayoutLint.js +0 -324
  108. package/dist/knowledge/platform/mobileRules.js +0 -231
  109. package/dist/knowledge/platform/mobileSpacing.js +0 -82
  110. package/dist/knowledge/platform/mobileTabs.js +0 -108
  111. package/dist/knowledge/platform/nativeBoxModel.js +0 -44
  112. package/dist/knowledge/platform/profile.js +0 -25
  113. package/dist/knowledge/platform/resolve.js +0 -122
  114. package/dist/knowledge/platform/web.js +0 -39
  115. package/dist/knowledge/process.js +0 -510
  116. package/dist/knowledge/rowFilter.js +0 -43
  117. package/dist/knowledge/styleResolveNative.js +0 -527
  118. package/dist/platform/argumentAliases.js +0 -128
  119. package/dist/platform/bodyFile.js +0 -103
  120. package/dist/platform/capture/actions.js +0 -333
  121. package/dist/platform/capture/browser.js +0 -1
  122. package/dist/platform/capture/console-log.js +0 -122
  123. package/dist/platform/capture/index.js +0 -11
  124. package/dist/platform/capture/readiness.js +0 -103
  125. package/dist/platform/capture/summary.js +0 -77
  126. package/dist/platform/capture/target.js +0 -5
  127. package/dist/platform/capture/targets/studio-mobile.js +0 -15
  128. package/dist/platform/capture/targets/studio-web.js +0 -5
  129. package/dist/platform/impersonation.js +0 -45
  130. package/dist/platform/jsonArray.js +0 -24
  131. package/dist/platform/schemaReadMemory.js +0 -60
  132. package/dist/resources/examples/bpm-gorev-kontrol.json +0 -294
  133. package/dist/resources/examples/bpm-iso-dokuman.json +0 -228
  134. package/dist/resources/examples/bpm-satinalma.json +0 -376
  135. package/dist/resources/examples/connect-data-convert-verify.json +0 -107
  136. package/dist/resources/examples/connect-data-dropdown-roles.json +0 -66
  137. package/dist/resources/examples/connect-data-edit-m2m.json +0 -73
  138. package/dist/resources/examples/connect-data-query-params.json +0 -50
  139. package/dist/resources/examples/connect-data-table-entity.json +0 -147
  140. package/dist/resources/examples/connect-data-workflow-microservice.json +0 -65
  141. package/dist/resources/examples/mobile-app-shell-drawer.json +0 -243
  142. package/dist/resources/examples/mobile-app-shell-stack.json +0 -157
  143. package/dist/resources/examples/mobile-app-shell-tab.json +0 -208
  144. package/dist/resources/examples/mobile-form-screen.json +0 -365
  145. package/dist/resources/examples/mobile-list-detail-form.json +0 -672
  146. package/dist/resources/guides/access.md +0 -796
  147. package/dist/resources/guides/bpm.md +0 -686
  148. package/dist/resources/guides/case.md +0 -153
  149. package/dist/resources/guides/decision.md +0 -185
  150. package/dist/resources/guides/mobile-layout.md +0 -193
  151. package/dist/resources/guides/mobile.md +0 -495
  152. package/dist/resources/read.js +0 -41
  153. package/dist/resources/schemas/AccessExplanationDto.json +0 -144
  154. package/dist/resources/schemas/AccessMatrixDto.json +0 -170
  155. package/dist/resources/schemas/AccessPermissionDto.json +0 -57
  156. package/dist/resources/schemas/AccessPolicyDto.json +0 -223
  157. package/dist/resources/schemas/AccessResourceDto.json +0 -86
  158. package/dist/resources/schemas/AppSessionDto.json +0 -53
  159. package/dist/resources/schemas/ConnectDataDescribeDto.json +0 -344
  160. package/dist/resources/schemas/ConnectDataRequestModel.json +0 -202
  161. package/dist/resources/schemas/ConnectDataResultDto.json +0 -421
  162. package/dist/resources/schemas/ConnectorCredentialDto.json +0 -70
  163. package/dist/resources/schemas/ConvertConnectDataToMicroserviceCommand.json +0 -37
  164. package/dist/resources/schemas/CreateAccessPolicyCommand.json +0 -209
  165. package/dist/resources/schemas/CreateDecisionCommand.json +0 -221
  166. package/dist/resources/schemas/CreateProcessDefinitionCommand.json +0 -1337
  167. package/dist/resources/schemas/DecisionDto.json +0 -302
  168. package/dist/resources/schemas/DetachConnectDataMicroserviceCommand.json +0 -28
  169. package/dist/resources/schemas/ExplainAccessQuery.json +0 -33
  170. package/dist/resources/schemas/GenerateProcessDocumentCommand.json +0 -116
  171. package/dist/resources/schemas/OrganizationProjectDto.json +0 -335
  172. package/dist/resources/schemas/OrganizationSchemaDto.json +0 -196
  173. package/dist/resources/schemas/OrganizationSchemaVersionDto.json +0 -207
  174. package/dist/resources/schemas/PatchProcessDefinitionCommand.json +0 -76
  175. package/dist/resources/schemas/ProcessDefinitionDto.json +0 -1480
  176. package/dist/resources/schemas/ProcessSimulationDto.json +0 -96
  177. package/dist/resources/schemas/SaveConnectorCredentialCommand.json +0 -90
  178. package/dist/resources/schemas/SaveProcessEventSourceCommand.json +0 -61
  179. package/dist/resources/schemas/SaveProcessMailSourceCommand.json +0 -89
  180. package/dist/resources/schemas/SignProcessTaskCommand.json +0 -73
  181. package/dist/resources/schemas/SimulateProcessDefinitionQuery.json +0 -92
  182. package/dist/resources/schemas/UpdateAccessPolicyCommand.json +0 -209
  183. package/dist/resources/schemas/UpdateDecisionCommand.json +0 -216
  184. package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +0 -1357
  185. package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +0 -1339
  186. package/dist/tools/accessOperations.js +0 -135
  187. package/dist/tools/accessPolicies.js +0 -170
  188. package/dist/tools/accessRuntime.js +0 -203
  189. package/dist/tools/bpm.js +0 -343
  190. package/dist/tools/bpmGovernance.js +0 -266
  191. package/dist/tools/bpmOperations.js +0 -230
  192. package/dist/tools/bpmReporting.js +0 -154
  193. package/dist/tools/bpmRouting.js +0 -150
  194. package/dist/tools/bpmRuntime.js +0 -396
  195. package/dist/tools/case.js +0 -178
  196. package/dist/tools/caseRuntime.js +0 -89
  197. package/dist/tools/connectData.js +0 -449
  198. package/dist/tools/connectors.js +0 -193
  199. package/dist/tools/decisions.js +0 -206
  200. package/dist/tools/mobile.js +0 -221
  201. package/dist/tools/modules.js +0 -48
  202. package/dist/tools/organizationStructure.js +0 -137
  203. package/dist/tools/profileWrite.js +0 -92
@@ -4,16 +4,13 @@ import { patchResult, baseVersionOf } from '../platform/patch.js';
4
4
  import fastJsonPatch from 'fast-json-patch';
5
5
  import { normalizeComponentDefaults, componentDefaultsNote, flexSizeWarnings, spacingLayerWarnings, verticalGapWarnings, withNormalization } from '../knowledge/normalize.js';
6
6
  import { fetchHost, layoutUpdateBody, schemaParam, eventsParam, modeParam, summarize, findNode } from './screens.js';
7
- import { assertScreenWriteGuards, assertScreenCatalog } from './screenWrite.js';
7
+ import { assertScreenWriteGuards, screenCatalogNotes } from './screenWrite.js';
8
8
  import { applyPropTypesToSchema, isSetPropTypeOp, setPropTypeErrors } from '../knowledge/propTypes.js';
9
9
  import { writeDiff, withWriteDiff } from '../platform/writeDiff.js';
10
10
  import { PlatformApiError } from '../platform/errors.js';
11
11
  import { handle } from '../platform/responses.js';
12
- import { applicationTypeField, resolveProfile } from '../knowledge/platform/resolve.js';
13
- import { screenProfileWarnings } from './profileWrite.js';
14
- import { jsonArray } from '../platform/jsonArray.js';
15
12
  import { z } from 'zod';
16
- const patchOperationsParam = jsonArray(z.array(z.record(z.unknown())).min(1))
13
+ const patchOperationsParam = z.array(z.record(z.unknown())).min(1)
17
14
  .describe("JSON Patch listesi (RFC 6902): { op, path, value }. Yol seçici alabilir — '/views/0/children[elementId=baslik]/props/content/data'.");
18
15
  const viewsParam = schemaParam.describe("Layout'un komponent ağacı. DİKKAT: layout'ta şema alanının adı 'schema' değil 'views'tir; ağaçta hedefli değişiklik için tam ağaç yerine layout_schema_patch micro-op'larını kullanın. İçinde MUTLAKA bir { type: 'slot' } komponenti olmalı — sayfa içeriği YALNIZ slot'un içine render edilir, slot'suz layout'a bağlanan sayfalar boş görünür. 2026-09-08'den beri views, page_schema_patch'in doğrulama duvarından geçer: tanınmayan prop adı ve geçersiz enum değeri 422 ile REDDEDİLİR (kabul edilen değer listesiyle) ve hiçbir şey kaydedilmez — eskiden sessizce kaydediliyordu (P1-2).");
19
16
  function countSlots(nodes) {
@@ -49,13 +46,7 @@ export function registerLayoutTools(server, platform) {
49
46
  description: "Layout'u komponent ağacı (views), widget'ları, akışları ve olaylarıyla getirir.",
50
47
  inputSchema: { project: projectParam, environment: environmentParam, applicationId: guid, id: guid },
51
48
  annotations: readOnly
52
- }, handle(config, async ({ project, environment, applicationId, id }) => {
53
- const response = await platform.tenant('GET', project, `/layouts/${applicationId}/${id}`, { environment });
54
- const typeField = applicationTypeField(await resolveProfile(platform, applicationId));
55
- return response && typeof response === 'object' && !Array.isArray(response) && Object.keys(typeField).length > 0
56
- ? { ...response, ...typeField }
57
- : response;
58
- }));
49
+ }, handle(config, ({ project, environment, applicationId, id }) => platform.tenant('GET', project, `/layouts/${applicationId}/${id}`, { environment })));
59
50
  server.registerTool('layout_schema_get', {
60
51
  title: "Layout komponent ağacını oku",
61
52
  description: "Layout'un komponent ağacını (views) okur — page_schema_get'in layout karşılığı. Ağaçta hedefli değişiklik için layout_schema_patch (sayfa ile aynı micro-op sözlüğü, PATCH /layouts/{app}/{id}/schema). Ad/parametre/olay alanlarında ya da düz JSON Patch yolu gerektiğinde layout_patch — o araç buradaki updatedAt'i expectedUpdatedAt olarak kabul eder. Tam ağacı kendiniz yazacaksanız layout_update.",
@@ -70,21 +61,20 @@ export function registerLayoutTools(server, platform) {
70
61
  annotations: readOnly
71
62
  }, handle(config, async ({ project, environment, applicationId, id, mode, componentId }) => {
72
63
  const layout = await fetchHost(platform, 'layout', project, environment, applicationId, id);
73
- const typeField = applicationTypeField(await resolveProfile(platform, applicationId));
74
64
  const audit = layout.audit;
75
65
  const updatedAt = audit?.updatedAt ?? audit?.createdAt;
76
66
  const views = (layout.views ?? []);
77
67
  if (mode === 'full')
78
- return { updatedAt, ...typeField, views };
68
+ return { updatedAt, views };
79
69
  if (mode === 'subtree') {
80
70
  if (!componentId)
81
71
  throw new PlatformApiError("mode='subtree' için componentId zorunludur.");
82
72
  const subtree = findNode(views, componentId);
83
73
  if (!subtree)
84
74
  throw new PlatformApiError(`Layout'ta '${componentId}' id'li bir komponent yok; layout_schema_get'i summary kipinde çağırıp hedefi doğrulayın.`);
85
- return { updatedAt, ...typeField, views: subtree };
75
+ return { updatedAt, views: subtree };
86
76
  }
87
- return { updatedAt, ...typeField, views: views.map(node => summarize(node)) };
77
+ return { updatedAt, views: views.map(node => summarize(node)) };
88
78
  }));
89
79
  server.registerTool('layout_create', {
90
80
  title: 'Layout oluştur',
@@ -100,28 +90,19 @@ export function registerLayoutTools(server, platform) {
100
90
  },
101
91
  annotations: writes
102
92
  }, handle(config, async ({ project, environment, applicationId, name, views, events, parameters }) => {
103
- const resolved = await resolveProfile(platform, applicationId);
104
- assertScreenWriteGuards('layout', { schema: views, events }, resolved.profile.platform);
93
+ assertScreenWriteGuards('layout', { schema: views, events });
105
94
  const fixed = normalizeComponentDefaults(views);
106
- const catalogNotes = await assertScreenCatalog(platform, project, environment, applicationId, views, 'layout_create');
107
- const gaps = [
108
- ...(resolved.profile.layout.blocksMeaningful ? verticalGapWarnings(views ?? [], 'LAY-003 (uyarı)') : []),
109
- ...flexSizeWarnings(views ?? [], 'LAY-007 (uyarı)', 'LAY-008 (uyarı)'),
110
- ...spacingLayerWarnings(views ?? [], 'LAY-010 (uyarı)', 'LAY-011 (uyarı)'),
111
- ...await screenProfileWarnings(platform, resolved, project, environment, applicationId, { kind: 'layout', nodes: views ?? [] })
112
- ];
95
+ const catalogNotes = await screenCatalogNotes(platform, project, environment, applicationId, views);
96
+ const gaps = [...verticalGapWarnings(views ?? [], 'LAY-003 (uyarı)'), ...flexSizeWarnings(views ?? [], 'LAY-007 (uyarı)', 'LAY-008 (uyarı)'), ...spacingLayerWarnings(views ?? [], 'LAY-010 (uyarı)', 'LAY-011 (uyarı)')];
113
97
  const response = await platform.tenant('POST', project, `/layouts/${applicationId}`, {
114
98
  environment,
115
99
  body: { name, views: views ?? [], events: events ?? [], parameters: parameters ?? null }
116
100
  });
117
101
  const drops = writeDiff({ name, views: views ?? [], events: events ?? [] }, response);
118
102
  const normalized = withWriteDiff(withNormalization(response, [...componentDefaultsNote(fixed), ...catalogNotes, ...slotWarning(views)]), drops);
119
- const typeField = applicationTypeField(resolved);
120
- if (!normalized || typeof normalized !== 'object')
103
+ if (gaps.length === 0 || !normalized || typeof normalized !== 'object')
121
104
  return normalized;
122
- if (gaps.length === 0)
123
- return Object.keys(typeField).length === 0 ? normalized : { ...normalized, ...typeField };
124
- return { ...normalized, ...typeField, layoutWarnings: gaps };
105
+ return { ...normalized, layoutWarnings: gaps };
125
106
  }));
126
107
  server.registerTool('layout_update', {
127
108
  title: 'Layout güncelle',
@@ -139,21 +120,13 @@ export function registerLayoutTools(server, platform) {
139
120
  annotations: updates
140
121
  }, handle(config, async ({ project, environment, applicationId, id, ...changes }) => {
141
122
  const overrides = Object.fromEntries(Object.entries(changes).filter(([, value]) => value !== undefined));
142
- const resolved = overrides.views === undefined ? undefined : await resolveProfile(platform, applicationId);
143
- assertScreenWriteGuards('layout', { schema: overrides.views, events: overrides.events }, resolved?.profile.platform);
123
+ assertScreenWriteGuards('layout', { schema: overrides.views, events: overrides.events });
144
124
  const current = await fetchHost(platform, 'layout', project, environment, applicationId, id);
145
125
  const fixed = normalizeComponentDefaults(overrides.views);
146
- const catalogNotes = await assertScreenCatalog(platform, project, environment, applicationId, overrides.views, 'layout_update');
126
+ const catalogNotes = await screenCatalogNotes(platform, project, environment, applicationId, overrides.views);
147
127
  const body = layoutUpdateBody({ ...current, applicationId }, overrides);
148
128
  await platform.tenant('PUT', project, `/layouts/${applicationId}/${id}`, { environment, body });
149
- const gaps = overrides.views === undefined || !resolved
150
- ? []
151
- : [
152
- ...(resolved.profile.layout.blocksMeaningful ? verticalGapWarnings(body.views, 'LAY-003 (uyarı)') : []),
153
- ...flexSizeWarnings(body.views, 'LAY-007 (uyarı)', 'LAY-008 (uyarı)'),
154
- ...spacingLayerWarnings(body.views, 'LAY-010 (uyarı)', 'LAY-011 (uyarı)'),
155
- ...await screenProfileWarnings(platform, resolved, project, environment, applicationId, { kind: 'layout', nodes: body.views })
156
- ];
129
+ const gaps = overrides.views === undefined ? [] : [...verticalGapWarnings(body.views, 'LAY-003 (uyarı)'), ...flexSizeWarnings(body.views, 'LAY-007 (uyarı)', 'LAY-008 (uyarı)'), ...spacingLayerWarnings(body.views, 'LAY-010 (uyarı)', 'LAY-011 (uyarı)')];
157
130
  const summary = { id, changed: Object.keys(overrides), preserved: { viewNodes: body.views.length } };
158
131
  if (gaps.length > 0)
159
132
  summary.layoutWarnings = gaps;
@@ -207,10 +180,9 @@ export function registerLayoutTools(server, platform) {
207
180
  const overrides = Object.fromEntries(['name', 'views', 'events', 'parameters']
208
181
  .filter(key => patched[key] !== undefined)
209
182
  .map(key => [key, patched[key]]));
210
- const profile = await resolveProfile(platform, applicationId);
211
- assertScreenWriteGuards('layout', { schema: overrides.views, events: overrides.events }, profile.profile.platform);
183
+ assertScreenWriteGuards('layout', { schema: overrides.views, events: overrides.events });
212
184
  const fixed = normalizeComponentDefaults(overrides.views);
213
- const catalogNotes = await assertScreenCatalog(platform, project, environment, applicationId, overrides.views, 'layout_patch');
185
+ const catalogNotes = await screenCatalogNotes(platform, project, environment, applicationId, overrides.views);
214
186
  const body = layoutUpdateBody({ ...current, applicationId }, overrides);
215
187
  // Gövde değil FARK gönderilir: gateway normalizasyonları (komponent varsayılanları, katalog
216
188
  // kuralları, value'suz olayların elenmesi) son hâle işlendikten sonra net diff hesaplanır.
@@ -221,12 +193,7 @@ export function registerLayoutTools(server, platform) {
221
193
  body: { baseVersion: baseVersionOf(document, 'layout_get'), ops: netOps }
222
194
  });
223
195
  const written = patchResult(saved, finalDocument);
224
- const gaps = [
225
- ...(profile.profile.layout.blocksMeaningful ? verticalGapWarnings(body.views, 'LAY-003 (uyarı)') : []),
226
- ...flexSizeWarnings(body.views, 'LAY-007 (uyarı)', 'LAY-008 (uyarı)'),
227
- ...spacingLayerWarnings(body.views, 'LAY-010 (uyarı)', 'LAY-011 (uyarı)'),
228
- ...await screenProfileWarnings(platform, profile, project, environment, applicationId, { kind: 'layout', nodes: body.views })
229
- ];
196
+ const gaps = [...verticalGapWarnings(body.views, 'LAY-003 (uyarı)'), ...flexSizeWarnings(body.views, 'LAY-007 (uyarı)', 'LAY-008 (uyarı)'), ...spacingLayerWarnings(body.views, 'LAY-010 (uyarı)', 'LAY-011 (uyarı)')];
230
197
  const summary = {
231
198
  id,
232
199
  applied: patchOps.length,
@@ -37,7 +37,7 @@ export function registerMergeTools(server, platform) {
37
37
  const config = platform.config;
38
38
  server.registerTool('merge_plan', {
39
39
  title: 'Merge planı oluştur',
40
- description: "Bir dalı ebeveynine (development) merge etmek için üç yönlü diff planı ister. Hedef her zaman dalın ebeveynidir — production'a merge eden bir yol YOKTUR. title ZORUNLUDUR: isteğin adıdır ve geçmişte o adla durur. Asenkron: yanıt 202 döner, plan hemen dolu değildir. Projede açık bir plan varsa 400 döner; önce onu uygulayın ya da merge_discard ile bırakın. Süreç tanımları ve iş takvimleri planda modül olarak görünür (fark versions[…].model.nodes[<düğüm id>] yolunda); örnekler, görevler, defter ve uyarlamalar merge edilmez.",
40
+ description: "Bir dalı ebeveynine (development) merge etmek için üç yönlü diff planı ister. Hedef her zaman dalın ebeveynidir — production'a merge eden bir yol YOKTUR. title ZORUNLUDUR: isteğin adıdır ve geçmişte o adla durur. Asenkron: yanıt 202 döner, plan hemen dolu değildir. Projede açık bir plan varsa 400 döner; önce onu uygulayın ya da merge_discard ile bırakın.",
41
41
  inputSchema: { projectId: guid, sourceEnvironmentId: guid, title: mergeTitle, description: mergeDescription },
42
42
  annotations: writes
43
43
  }, handle(config, async ({ projectId, sourceEnvironmentId, title, description }) => {
@@ -1,24 +1,19 @@
1
- import { guid, appRef, withResolved, projectParam, environmentParam, definitionParam, languageParam, pagingParams, asUserIdParam, readOnly, writes, updates, destructive, microOps } from './common.js';
1
+ import { guid, appRef, withResolved, projectParam, environmentParam, definitionParam, languageParam, pagingParams, readOnly, writes, updates, destructive, microOps } from './common.js';
2
2
  import { languageHeader } from '../knowledge/languageCodes.js';
3
3
  import { hydrateMicroserviceRefs } from '../knowledge/hydrate.js';
4
4
  import { RefResolver } from '../platform/refs.js';
5
5
  import { normalizeMicroserviceDefinition, normalizeMicroservicePatchOps, withNormalization } from '../knowledge/normalize.js';
6
6
  import { evaluatePolicy, enforcePolicy, attachFindings } from '../knowledge/policy.js';
7
7
  import { microserviceOutline, workflowOutline, resolvePart, resolvePatchOperations } from '../knowledge/outlines.js';
8
- import { unresolvedParameterAliases, parameterAliasWarning } from '../knowledge/microserviceParameters.js';
9
8
  import { patchResult, baseVersionOf } from '../platform/patch.js';
10
- import { filterOperatorError, policyRules } from '../knowledge/rules.js';
9
+ import { policyRules } from '../knowledge/rules.js';
11
10
  import { writeDiff, withWriteDiff } from '../platform/writeDiff.js';
12
- import { identityHeaders, resolveIdentity } from '../platform/tokenVault.js';
13
- import { impersonationHeaders } from '../platform/impersonation.js';
14
- import { accessDecisionOf, legacyRoleListFindings, projectAccessContext } from '../knowledge/access.js';
11
+ import { identityHeaders } from '../platform/tokenVault.js';
15
12
  import { PlatformApiError } from '../platform/errors.js';
16
13
  import { existingMatch, ifExistsParam, listAll, platformRename, withOutcome, withRename } from '../platform/ifExists.js';
17
14
  import { outlineWrite, recordWriteViewParam } from '../platform/writeView.js';
18
15
  import { handle } from '../platform/responses.js';
19
- import { headersForMode } from '../platform/http.js';
20
16
  import fastJsonPatch from 'fast-json-patch';
21
- import { jsonArray } from '../platform/jsonArray.js';
22
17
  import { z } from 'zod';
23
18
  import { constraintSummary } from '../knowledge/backendConstraints.js';
24
19
  import { unmappedMembers, introducedUnmappedMembers, withUnmappedMembers } from '../knowledge/schemaGuard.js';
@@ -71,9 +66,9 @@ async function queryScopeFindings(platform, project, environment, definition) {
71
66
  }]
72
67
  : [];
73
68
  }
74
- const patchOperationsParam = jsonArray(z.array(z.record(z.unknown())).min(1))
69
+ const patchOperationsParam = z.array(z.record(z.unknown())).min(1)
75
70
  .describe("RFC 6902 JSON Patch işlemleri; path'leri view:'outline'/'part' ile keşfedin. Dizi öğelerinde indeks yerine seçici kullanılabilir: '/sourceParameters/joins[alias=customers]/path' — seçici gövde platforma gitmeden indekse çevrilir, çözülemezse istek hiç gönderilmez.");
76
- const asUserParam = z.string().min(1).optional().describe("Uygulama üyesinin kimliği: istek gateway'in servis jetonu yerine bu kimlikle gider. Jeton HEM Authorization başlığında HEM NG_AccessToken çerezinde taşınır, böylece jetonu ÇEREZDEN okuyan middleware de geçer — uca middleware bağlandığı anda bu alan olmadan çağrı 401 döner (09-05 koşusu S-21). KOMPLEKS PROJEDE referans access_session_create'ten gelir: jeton Bearer olarak gider, platform Bearer'lı isteğe CSRF sormaz (ZY_App_ çerezi kurulmaz — çerezle gelen durum değiştiren istek X-ZY-CSRF ister); microservice_preview bir Studio ucudur ve uygulama jetonuyla sınanamaz, uygulama kullanıcısı olarak microservice_execute / microservice_debug kullanın. ÜÇ ŞEKİL kabul edilir: (1) TERCİH EDİLEN `test:<ad>` — gateway kök .env'deki MCP_TEST_USER_<AD> satırıyla giriş ucunu kendisi çağırır, jetonu kasadan yeniden kullanır (satırı insan yazar), (2) `tok_…` referansı (giriş ucunu çağırdığınızda yanıtın tokenRefs alanında döner; ömür MCP_TOKEN_TTL_MINUTES, MCP_STATE_DIR varsa gateway yeniden başlayınca da çözülür), (3) ham JWT. anonymous ile birlikte verilemez.");
71
+ const asUserParam = z.string().min(1).optional().describe("Uygulama üyesinin kimliği: istek gateway'in servis jetonu yerine bu kimlikle gider. Jeton HEM Authorization başlığında HEM NG_AccessToken çerezinde taşınır, böylece jetonu ÇEREZDEN okuyan middleware de geçer — uca middleware bağlandığı anda bu alan olmadan çağrı 401 döner (09-05 koşusu S-21). İKİ ŞEKİL kabul edilir: (1) ham JWT, (2) `tok_…` referansı (giriş ucunu çağırdığınızda yanıtın tokenRefs alanında döner, 15 dk geçerli). anonymous ile birlikte verilemez.");
77
72
  const cookiesParam = z.record(z.string()).optional().describe("İsteğe eklenecek çerezler (ad → değer): uygulamanın KENDİ oturum çerezi buraya verilir (ör. { CORE_Token: '<jwt>' }). asUser verildiğinde gateway NG_AccessToken çerezini zaten kendisi kurar; bu alan yalnız uygulama başka bir çerez adı okuyorsa gerekir. anonymous ile birlikte verilemez.");
78
73
  const executeInput = {
79
74
  project: projectParam,
@@ -90,7 +85,6 @@ const executeInput = {
90
85
  headers: z.record(z.string()).optional().describe("İsteğe eklenecek header'lar. 'Authorization' verirseniz gateway KENDİ token'ını KOYMAZ — istek tamamen sizin kimliğinizle gider (middleware'li uçları üye token'ıyla test etmenin yolu budur)"),
91
86
  anonymous: z.boolean().optional().describe("true: istek HİÇBİR Authorization header'ı olmadan gider — 'korumalı uç tokensız ne döner?' sorusunun cevabı budur (korumalı uçtan 401, anonim uçtan 200 beklenir). Gateway normalde her çağrıya kendi token'ını koyduğu için bu bayrak olmadan anonim erişim testi yapılamaz."),
92
87
  asUser: asUserParam,
93
- asUserId: asUserIdParam,
94
88
  cookies: cookiesParam,
95
89
  language: languageParam,
96
90
  expectFailure: z.boolean().optional().describe("true: bu çağrıda bir hata dönmesi BEKLENİYOR (kasıtlı negatif test — yanlış parola, yetkisiz erişim, geçersiz gövde). Yanıt yine httpStatus'u/hatayı taşır, ama ölçüm aracı bu satırı plansız hata saymaz (page_screenshot'taki expectFailure deseniyle aynı).")
@@ -105,9 +99,6 @@ function runIdentity(anonymous, asUser, cookies, headers) {
105
99
  }
106
100
  return identityHeaders(asUser, cookies, headers);
107
101
  }
108
- function hasAuthorization(headers) {
109
- return Object.keys(headers ?? {}).some(name => name.toLowerCase() === 'authorization');
110
- }
111
102
  /**
112
103
  * Debug çıktısındaki `executionItems` ucun kendi adımlarıdır; middleware AYRI bir workflow olarak
113
104
  * ucun ÖNÜNDE koşar ve ağaçta hiç görünmez — 09-04 koşusunda sessizce açık kalan şirket kapısı
@@ -198,27 +189,17 @@ function unboundQueryParameters(value, into = []) {
198
189
  unboundQueryParameters(entry, into);
199
190
  return into;
200
191
  }
201
- /** Çağrının dinamik filtresi (`filters`, sorguda ya da gövdede) bilinen işleçlerle mi — değilse istek gitmez (g-03). */
202
- function assertFilterOperators(tool, bound) {
203
- const bodyFilters = bound.body && !Array.isArray(bound.body) ? bound.body.filters : undefined;
204
- const error = filterOperatorError(tool, bound.query?.filters) ?? filterOperatorError(tool, bodyFilters);
205
- if (error)
206
- throw new PlatformApiError(error, 400);
207
- }
208
192
  function executePath(prefix, application, microservice, routeParams) {
209
193
  const routeSuffix = routeParams && routeParams.length > 0
210
194
  ? `/${routeParams.map(encodeURIComponent).join('/')}`
211
195
  : '';
212
196
  return `/${prefix}/${application}/${microservice}${routeSuffix}`;
213
197
  }
214
- /**
215
- * Slug application_update ile değişebildiği için önbellek kısa ömürlüdür (yalnız aynı turdaki tekrar okumaları ucuzlatır);
216
- * runtime yolu 404 dönen çağıran `fresh: true` ile önbelleği atlar. Org API'nin 404 dışı hatası (yetki, ağ) çağırana gider.
217
- */
198
+ /** Slug application_update ile değişebildiği için önbellek kısa ömürlüdür (yalnız aynı turdaki tekrar okumaları ucuzlatır). */
218
199
  const APPLICATION_SLUG_TTL_MS = 60_000;
219
200
  const applicationSlugCache = new Map();
220
- export async function applicationSlug(platform, applicationId, options = {}) {
221
- const cached = options.fresh ? undefined : applicationSlugCache.get(applicationId);
201
+ async function applicationSlug(platform, applicationId) {
202
+ const cached = applicationSlugCache.get(applicationId);
222
203
  if (cached && cached.expiresAt > Date.now())
223
204
  return cached.slug;
224
205
  try {
@@ -229,10 +210,8 @@ export async function applicationSlug(platform, applicationId, options = {}) {
229
210
  applicationSlugCache.set(applicationId, { slug, expiresAt: Date.now() + APPLICATION_SLUG_TTL_MS });
230
211
  return slug;
231
212
  }
232
- catch (error) {
233
- if (error instanceof PlatformApiError && error.status === 404)
234
- return undefined;
235
- throw error;
213
+ catch {
214
+ return undefined;
236
215
  }
237
216
  }
238
217
  /**
@@ -262,12 +241,6 @@ async function resolveRuntimeUrl(platform, project, environment, applicationId,
262
241
  }
263
242
  export function registerMicroserviceTools(server, platform) {
264
243
  const config = platform.config;
265
- server.registerTool('microservice_system_operation_list', {
266
- title: 'Sistem operasyonlarını listele',
267
- description: "Bir microservice'in systemOperation alanına konabilecek hazır platform operasyonlarının kataloğunu döner (GET /{project}/microservices/system-operations): operasyon adı, karar motorunun soracağı izin, kaynak tipi, beklediği parametreler ve açıklaması. Sistem operasyonlu uç kendi adımlarını yazmaz — platformun hazır davranışını (ör. satır sahibini değiştirme, maskeli alan açma, uygulama girişi) uygulamanın kendi ucu gibi yayınlar. Her satırın 'guard' alanı korumayı söyler: 'permission' → oturum + buradaki permission karara bağlanır; permission BOŞ olan 'permission' satırında izni işlemin çağırdığı servis verir (ADR-0004): süreç çalışma zamanı işlemleri (process.* — görev kutusu ve eylemleri, process.task.sign dahil; örnek, vekalet, devir, bildirim, tercih, rapor) kişiye ve kayda göre karar verir, REST bpm/* ucuyla aynı görünürlüğü ve aynı alan adlarını döner; yalnız process.override.* process.manage ister; 'session' → operasyon izin sormaz, yalnız oturum ister (ör. access.session.get: oturumdaki kullanıcı; uç anonim değilse microservice.execute kararı yine uygulanır); 'anonymous' → oturum da izin de sorulmaz (access.session.create: giriş; girdi yalnız gövdeden okunur, çerezler yalnız application/json istekte yazılır, gövdede jeton dönmez) ve uç isAnonymous:true olmak zorundadır, önizlemede çalışmaz. Süreç ekranı process.* işlemleriyle kurulur, Page.bpm ile değil (BPM-022); kod adımından platform ucuna ham fetch yerine bu uçlar kullanılır (FLOW-028). Katalog sabittir, projeye göre değişmez.",
268
- inputSchema: { project: projectParam, environment: environmentParam },
269
- annotations: readOnly
270
- }, handle(config, ({ project, environment }) => platform.tenant('GET', project, '/microservices/system-operations', { environment })));
271
244
  server.registerTool('microservice_list', {
272
245
  title: 'Microservice listele',
273
246
  description: 'Application altındaki microservice\'leri listeler.',
@@ -291,7 +264,7 @@ export function registerMicroserviceTools(server, platform) {
291
264
  }));
292
265
  server.registerTool('microservice_get', {
293
266
  title: 'Microservice getir',
294
- description: "Microservice tanımını getirir. Büyük tanımda önce view:'outline' (kaynak/alan özeti), sonra view:'part' ile tek parça çekin. parameterScheme[].name ÇAĞRI PARAMETRESİNİN adıdır ve tablo kaynaklı uçta kök filtre için nitelenmemiş alan slug'ıdır ('id'); nitelikli bir ad ('kredi.id') yalnız JOIN alias'ıyla meşrudur — join değilse o filtre runtime'da hiç çözülmez ve yanıt MS-023 uyarısını taşır (TB-119).",
267
+ description: "Microservice tanımını getirir. Büyük tanımda önce view:'outline' (kaynak/alan özeti), sonra view:'part' ile tek parça çekin.",
295
268
  inputSchema: {
296
269
  project: projectParam,
297
270
  environment: environmentParam,
@@ -312,16 +285,9 @@ export function registerMicroserviceTools(server, platform) {
312
285
  return withResolved({ part, value: resolvePart(definition, part) }, resolver.resolved);
313
286
  }
314
287
  const resolvedUrl = await resolveRuntimeUrl(platform, project, environment, resolvedApplicationId, definition);
315
- // MS-023 — entity slug'ı YALNIZ kusur varken okunur: sağlam uçta fazladan istek atılmaz.
316
- const unresolved = unresolvedParameterAliases(definition);
317
- const entitySlug = unresolved.length === 0 || typeof definition.entityId !== 'string'
318
- ? undefined
319
- : await resolver.entity(definition.entityId).then(entity => entity.slug).catch(() => undefined);
320
- const warning = parameterAliasWarning(unresolved, entitySlug);
321
- const parameterWarnings = warning === undefined ? {} : { parameterWarnings: [warning] };
322
288
  if (view === 'outline')
323
- return withResolved({ ...microserviceOutline(definition), resolvedUrl, ...parameterWarnings }, resolver.resolved);
324
- return withResolved({ ...payload, resolvedUrl, ...parameterWarnings }, resolver.resolved);
289
+ return withResolved({ ...microserviceOutline(definition), resolvedUrl }, resolver.resolved);
290
+ return withResolved({ ...payload, resolvedUrl }, resolver.resolved);
325
291
  }));
326
292
  server.registerTool('microservice_create', {
327
293
  title: 'Microservice oluştur',
@@ -355,8 +321,7 @@ export function registerMicroserviceTools(server, platform) {
355
321
  ...(existing === undefined
356
322
  ? createFindings
357
323
  : enforcePolicy(evaluatePolicy(config, policyRules, 'microservice', definition, { operation: 'update' }, policyOverride))),
358
- ...scopeFindings,
359
- ...await legacyRoleListFindings(platform, project, environment, definition, 'microservice', policyOverride)
324
+ ...scopeFindings
360
325
  ];
361
326
  const drift = unmappedMembers(existing === undefined ? 'CreateMicroserviceCommand' : 'UpdateMicroserviceCommand', definition);
362
327
  const payload = existing === undefined
@@ -378,8 +343,7 @@ export function registerMicroserviceTools(server, platform) {
378
343
  const normalized = normalizeMicroserviceDefinition(definition);
379
344
  const findings = [
380
345
  ...enforcePolicy(evaluatePolicy(config, policyRules, 'microservice', definition, { operation: 'update' }, policyOverride)),
381
- ...await queryScopeFindings(platform, project, environment, definition),
382
- ...await legacyRoleListFindings(platform, project, environment, definition, 'microservice', policyOverride)
346
+ ...await queryScopeFindings(platform, project, environment, definition)
383
347
  ];
384
348
  const drift = unmappedMembers('UpdateMicroserviceCommand', definition);
385
349
  const payload = await platform.tenant('PUT', project, `/microservices/${resolvedApplicationId}/${id}`, { environment, body: definition });
@@ -442,41 +406,26 @@ export function registerMicroserviceTools(server, platform) {
442
406
  }, handle(config, ({ project, environment, id }) => platform.tenant('POST', project, `/microservices/${id}/clone`, { environment })));
443
407
  server.registerTool('microservice_execute', {
444
408
  title: 'Microservice çalıştır',
445
- description: "Kayıtlı microservice'i gerçek runtime yolundan çalıştırır (POST /{project}/m/{application}/{microservice SLUG'ı}). Dönen httpStatus microservice'in kendi sonucudur (hata da geçerli çıktıdır); beklenmedik sonuçta microservice_debug ile adım adım inceleyin. Anonim erişim testi için anonymous: true. KOMPLEKS PROJEDE gateway kimliği uygulama öznesi değildir (enforce'ta 401 AppSessionRequired): kullanıcı gözüyle çalıştırmak için asUserId (parolasız, users satır id'si; yalnız development/dal — production'da istek gönderilmez) ya da oturum açılmış üye için asUser. Yanıt 'headers' alanı VARSAYILAN OLARAK yalnız iş başlıklarını taşır (küçük harf): content-type, content-length, content-disposition, location, total-count (sayfalı tablo akışlarının okuduğu sözleşme), x-request-id, traceparent. Ucun response adımında kendi yazdığı başlıkları ya da sunucu başlıklarını görmek için includeHeaders:'all'; hiç başlık istemiyorsanız 'none'. set-cookie/authorization her kipte elenir.",
446
- inputSchema: {
447
- ...executeInput,
448
- includeHeaders: z.enum(['none', 'essential', 'all']).optional().describe("Yanıttaki 'headers' alanı. essential (varsayılan): content-type, content-length, content-disposition, location, total-count, x-request-id, traceparent. all: platformun döndüğü bütün başlıklar (gizliler hariç) — ucun kendi yazdığı başlığı doğrulamak için. none: başlık yok")
449
- },
409
+ description: "Kayıtlı microservice'i gerçek runtime yolundan çalıştırır (POST /{project}/m/{application}/{microservice SLUG'ı}). Dönen httpStatus microservice'in kendi sonucudur (hata da geçerli çıktıdır); beklenmedik sonuçta microservice_debug ile adım adım inceleyin. Anonim erişim testi için anonymous: true. Yanıt 'headers' alanında platformun döndüğü header'ları taşır (küçük harf; ör. headers['total-count'] — sayfalı tablo akışlarının okuduğu sözleşme; set-cookie/authorization elenir).",
410
+ inputSchema: executeInput,
450
411
  annotations: writes
451
- }, handle(config, async ({ project, environment, application, microservice, method, routeParams, query, body, parameters, headers, anonymous, asUser, asUserId, cookies, language, includeHeaders }) => {
412
+ }, handle(config, async ({ project, environment, application, microservice, method, routeParams, query, body, parameters, headers, anonymous, asUser, cookies, language }) => {
452
413
  const notes = [];
453
- const eye = await impersonationHeaders(platform, 'microservice_execute', project, environment, { asUserId, asUser, anonymous, ownAuthorization: hasAuthorization(headers) }, { runtime: true });
454
- const member = anonymous === true ? asUser : await resolveIdentity(asUser, platform, project, environment);
455
- const requestHeaders = { ...runIdentity(anonymous, member, cookies, headers), ...eye, ...languageHeader(language, notes) };
414
+ const requestHeaders = { ...runIdentity(anonymous, asUser, cookies, headers), ...languageHeader(language, notes) };
456
415
  const bound = bindCallParameters(method, parameters, query, body, notes);
457
- assertFilterOperators('microservice_execute', bound);
458
- const raw = await platform.tenantRaw(method, project, executePath('m', application, microservice, routeParams), { environment, query: bound.query, body: bound.body, headers: requestHeaders, anonymous, mirrorAuthorizationCookie: true });
459
- return withNormalization({ ...raw, headers: headersForMode(raw.headers, includeHeaders ?? 'essential') }, notes);
416
+ return withNormalization(await platform.tenantRaw(method, project, executePath('m', application, microservice, routeParams), { environment, query: bound.query, body: bound.body, headers: requestHeaders, anonymous, mirrorAuthorizationCookie: true }), notes);
460
417
  }));
461
418
  server.registerTool('microservice_debug', {
462
419
  title: 'Microservice debug',
463
- description: "Microservice'i debug modunda çalıştırır; yanıtta adım adım executionItems ağacı döner (her adımın girdi/çıktısı). executionItems YALNIZ ucun kendi adımlarını kapsar — ucun ÖNÜNDE koşan middleware'ler ayrıca 'middlewares' alanında adım özetiyle listelenir (09-04 Y-04). Değeri NULL bağlanan query parametreleri 'unboundParameters' alanında adıyla listelenir (ağaçta bu satırların value anahtarı görünmez). Preview semantiğiyle koşar: tek transaction + sonunda rollback, kalıcı satır yazmaz. httpStatus akışın kendi sonucudur (4xx/5xx'te runtimeErrors eklenir); ağaç düğümlerinde hata bayrağı YOKTUR — patlayan adımın output'u boştur, hata gövdesi hata dalındaki response adımının çıktısındadır. Zamanlanmış (schedule-job) uçlar da slug yoluyla debug edilir (method: 'POST', parametresiz): job geçmişi hatayı yalnız mesaj olarak yazar, adım adım girdi/çıktı burada görülür (platform_guide('microservice') §Zamanlanmış işin gerçek sonucunu görmek). Kompleks projede kullanıcı gözü asUserId (parolasız) ya da asUser ile verilir ve yanıta 'accessDecision' eklenir: { decision: allow | deny | not-enforced | unknown, mode, code?, permission?, reason, next } — 401/403'ün erişim kararından mı geldiğini ve sıradaki adımı söyler.",
420
+ description: "Microservice'i debug modunda çalıştırır; yanıtta adım adım executionItems ağacı döner (her adımın girdi/çıktısı). executionItems YALNIZ ucun kendi adımlarını kapsar — ucun ÖNÜNDE koşan middleware'ler ayrıca 'middlewares' alanında adım özetiyle listelenir (09-04 Y-04). Değeri NULL bağlanan query parametreleri 'unboundParameters' alanında adıyla listelenir (ağaçta bu satırların value anahtarı görünmez). Preview semantiğiyle koşar: tek transaction + sonunda rollback, kalıcı satır yazmaz. httpStatus akışın kendi sonucudur (4xx/5xx'te runtimeErrors eklenir); ağaç düğümlerinde hata bayrağı YOKTUR — patlayan adımın output'u boştur, hata gövdesi hata dalındaki response adımının çıktısındadır. Zamanlanmış (schedule-job) uçlar da slug yoluyla debug edilir (method: 'POST', parametresiz): job geçmişi hatayı yalnız mesaj olarak yazar, adım adım girdi/çıktı burada görülür (platform_guide('microservice') §Zamanlanmış işin gerçek sonucunu görmek).",
464
421
  inputSchema: executeInput,
465
422
  annotations: writes
466
- }, handle(config, async ({ project, environment, application, microservice, method, routeParams, query, body, parameters, headers, anonymous, asUser, asUserId, cookies, language }) => {
423
+ }, handle(config, async ({ project, environment, application, microservice, method, routeParams, query, body, parameters, headers, anonymous, asUser, cookies, language }) => {
467
424
  const notes = [];
468
- const eye = await impersonationHeaders(platform, 'microservice_debug', project, environment, { asUserId, asUser, anonymous, ownAuthorization: hasAuthorization(headers) }, { runtime: true });
469
- const member = anonymous === true ? asUser : await resolveIdentity(asUser, platform, project, environment);
470
- const requestHeaders = { ...runIdentity(anonymous, member, cookies, headers), ...eye, ...languageHeader(language, notes) };
425
+ const requestHeaders = { ...runIdentity(anonymous, asUser, cookies, headers), ...languageHeader(language, notes) };
471
426
  const bound = bindCallParameters(method, parameters, query, body, notes);
472
- assertFilterOperators('microservice_debug', bound);
473
427
  const payload = await platform.tenantRaw(method, project, executePath('debug', application, microservice, routeParams), { environment, query: bound.query, body: bound.body, headers: requestHeaders, anonymous, mirrorAuthorizationCookie: true });
474
428
  const unbound = unboundQueryParameters(payload.body);
475
- const chain = await middlewareChain(platform, project, environment, application, microservice, payload.httpStatus);
476
- // Karar yanıtta ayrı alan olarak gelmez: kompleks projede hata kodundan ve ortamın modundan türetilir
477
- // (g-31). Proje okuması zincirden SONRA yapılır; basit projede alan hiç eklenmez.
478
- const errorBody = (payload.body && typeof payload.body === 'object' ? payload.body : {});
479
- const decision = accessDecisionOf(await projectAccessContext(platform, project, environment), payload.httpStatus, errorBody.code, errorBody.message);
480
429
  return withNormalization({
481
430
  ...payload,
482
431
  ...(unbound.length > 0
@@ -485,8 +434,7 @@ export function registerMicroserviceTools(server, platform) {
485
434
  unboundParametersNote: "Bu query parametreleri NULL bağlandı: çağrıda yoklar ya da değerleri boş string'di (platform boş string'i NULL'a çevirir). Parametreyi 'parameters' (ya da GET'te 'query', POST/PUT'ta 'body') ile verin; ad sorgunun parametre adıyla birebir aynı olmalı."
486
435
  }
487
436
  : {}),
488
- ...chain,
489
- ...(decision ? { accessDecision: decision } : {})
437
+ ...await middlewareChain(platform, project, environment, application, microservice, payload.httpStatus)
490
438
  }, notes);
491
439
  }));
492
440
  server.registerTool('microservice_preview', {
@@ -526,7 +474,7 @@ export function registerMicroserviceTools(server, platform) {
526
474
  const findings = enforcePolicy(evaluatePolicy(config, policyRules, 'microservice', definition, { operation: 'preview' }, policyOverride));
527
475
  // Önizleme de ucun middleware'lerini koşturur: kimlik verilmezse korumalı uç 401 döner ve kuru
528
476
  // koşu aracı tam gerektiği anda kullanılamaz hâle gelir (09-05 koşusu S-21).
529
- const payload = await platform.tenantRaw('POST', project, `/microservices/${resolvedApplicationId}/preview`, { environment, body: definition, headers: { ...identityHeaders(await resolveIdentity(asUser, platform, project, environment), cookies, undefined), ...languageHeader(language, normalized) }, mirrorAuthorizationCookie: true });
477
+ const payload = await platform.tenantRaw('POST', project, `/microservices/${resolvedApplicationId}/preview`, { environment, body: definition, headers: { ...identityHeaders(asUser, cookies, undefined), ...languageHeader(language, normalized) }, mirrorAuthorizationCookie: true });
530
478
  return attachFindings(withResolved(withNormalization(payload, normalized), [...resolver.resolved, ...hydrated]), findings);
531
479
  }));
532
480
  server.registerTool('microservice_job_history', {