@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
@@ -1,81 +1,11 @@
1
- import { guid, projectParam, environmentParam, pagingParams, readOnly, writes, updates, destructive } from './common.js';
2
- import { PlatformApiError } from '../platform/errors.js';
1
+ import { projectParam, environmentParam, pagingParams, readOnly } from './common.js';
3
2
  import { handle } from '../platform/responses.js';
4
- import { registerOrganizationStructureTools } from './organizationStructure.js';
5
- import { registerAccessOperationTools } from './accessOperations.js';
6
- import { registerAccessPolicyTools } from './accessPolicies.js';
7
- import { registerAccessRuntimeTools } from './accessRuntime.js';
8
- import { randomUUID } from 'node:crypto';
9
3
  import { z } from 'zod';
10
- function count(value) {
11
- return Array.isArray(value) ? value.length : 0;
12
- }
13
- /**
14
- * Gateway'in jetonu organizasyonu yalnız SLUG olarak taşır (`UserService.SignInAsync` claim'i
15
- * `organization`) ve `/connect/userinfo` organizasyon id'si döndürmez; şema uçları ise id ister.
16
- * Id `ORGANIZATION` ayarındaki slug ile organizasyon listesinden bulunur.
17
- */
18
- export async function currentOrganizationId(platform, tool = 'organization_schema_get') {
19
- const slug = platform.config.organization;
20
- // Üç tuzak (OrganizationRepository.FilterAsync + OrganizationDto, canlı ölçüm 2026-09-15):
21
- // `includeDefault` olmadan liste varsayılan organizasyonu GİZLER — yerel kurulumun organizasyonu
22
- // tam da odur —, `searchTerm` adda arar ve DTO'da `slug` yoktur: `ORGANIZATION` host'un alt
23
- // alan adıdır (`subDomain`). Arama terimi gönderilmez, eşleşme `subDomain` ile yapılır.
24
- // Liste ucu `organization.read` ister (OrganizationsController.Get), şema ucu yalnız
25
- // `organization.schema.read`: şemayı okuyabilen kullanıcı listeyi okuyamayabilir.
26
- const payload = await platform.org('GET', '/organizations', { query: { pageLength: 200, includeDefault: true } }).catch((error) => {
27
- if (error instanceof PlatformApiError && error.status === 403) {
28
- throw new PlatformApiError(`${tool}: organizasyon id'si bulunamadı — gateway id'yi GET /organizations listesinden okur, o uç 'organization.read' izni ister ve bu kullanıcıda yok (şema ucu yalnız 'organization.schema.read' ister). organizationId'yi açıkça verin.`, 403, error.code);
29
- }
30
- throw error;
31
- });
32
- const found = (payload?.data ?? []).find(entry => entry.subDomain === slug || entry.slug === slug);
33
- if (typeof found?.id !== 'string') {
34
- throw new PlatformApiError(`${tool}: '${slug}' slug'lı organizasyon listede bulunamadı (GET /organizations). organizationId'yi açıkça verin.`, 404);
35
- }
36
- return found.id;
37
- }
38
- const unitTypes = ['holding', 'company', 'branch', 'region', 'department', 'team', 'other'];
39
- const draftWriteNote = "Yazma YALNIZ TASLAĞA gider (PUT /organizations/{id}/schema); hiçbir projeye inmez ve production'a dokunmaz. Abone projeler ancak organization_schema_publish ile güncellenir ve o çağrı production'a yazdığı için AI'ın işi değildir — taslağı AI yazar, YAYINI İNSAN yapar. Farkı yayından önce organization_schema_diff ile okuyun: `from` YAYINLANMIŞ bir sürüm (genelde publishedVersion), `to` verilmezse taslakla karşılaştırır. Organizasyonda hiç yayın yoksa taban da yoktur ve diff 404 döner — o durumda taslağı organization_schema_get ile okuyun.";
40
- function withoutUndefined(input) {
41
- return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== undefined));
42
- }
43
- function draftList(value) {
44
- return Array.isArray(value) ? value : [];
45
- }
46
- /**
47
- * Taslak tek parça yazılır: platformda düğüm başına uç YOKTUR, yönetim konsolu da üç listeyi
48
- * olduğu gibi gönderir (`PUT /organizations/{id}/schema`). Tek düğüm ekleyen araçlar bu yüzden
49
- * önce taslağı okur, listeyi değiştirir ve tamamını geri yazar — arada başkası yazdıysa onun
50
- * değişikliği ezilir (bilinçli sınır: taslakta eşzamanlılık jetonu yok, TB-104 ile aynı çizgi).
51
- */
52
- async function readSchemaDraft(platform, organizationId) {
53
- const payload = await platform.org('GET', `/organizations/${organizationId}/schema`);
54
- const data = payload?.data ?? {};
55
- return { units: draftList(data.units), positions: draftList(data.positions), roles: draftList(data.roles) };
56
- }
57
- async function saveSchemaDraft(platform, organizationId, draft, change, writtenId) {
58
- const payload = await platform.org('PUT', `/organizations/${organizationId}/schema`, { body: draft });
59
- const data = (payload?.data ?? {});
60
- return {
61
- ...payload,
62
- summary: {
63
- organizationId,
64
- ...(writtenId === undefined ? {} : { writtenId }),
65
- draftVersion: data.draftVersion ?? 0,
66
- publishedVersion: data.publishedVersion ?? null,
67
- units: draftList(data.units).length,
68
- positions: draftList(data.positions).length,
69
- roles: draftList(data.roles).length
70
- },
71
- note: `${change} Değişiklik TASLAKTA durur; abone projelere inmesi için insanın organization_schema_publish çağırması gerekir.`
72
- };
73
- }
74
4
  export function registerAccessTools(server, platform) {
75
5
  const config = platform.config;
76
6
  server.registerTool('role_list', {
77
7
  title: 'Rolleri listele',
78
- description: "Projenin rollerini listeler. Uç YALNIZ id + name döner (backend RoleDto bu ikisini taşır) — SLUG BURADA YOKTUR ve iki anahtar farklıdır: page_create/page_update ve microservice_create'in roleIds alanı ID ister (microservice_patch'te aynı liste '/roles' yolundadır ve öğeleri { id, name } çiftidir — yamalanan belge okuma şeklidir), buna karşılık Authorized(user.roles) ile middleware'in kurduğu user.roles SLUG karşılaştırır (platformun get-user sorgusu roles+user_roles join'inden slug dizisi üretir). Slug'ı built-in 'roles' entity'sinden okuyun (sabit id 01917ede-88a2-72ea-8397-2619e5d5dca0; row_list/microservice). ROL OLUŞTURAN BİR TOOL YOKTUR ve olmamalıdır: roller built-in datasource'taki sıradan bir entity'dir (kolonlar id · name UNIQUE · slug · origin). Uygulamanın rol yönetmesi gerekiyorsa yol entity_get('roles') + kendi microservice ucun (uç + sayfa) ve rolü kullanıcıya bağlayan user_roles satırı — MCP'den doğrudan yazma değil; reçete platform_guide('entity') §'Hazır entity'ler'. Projeyle birlikte gelen roller çoğu senaryoya yeter; önce bu listeye bakın. KOMPLEKS PROJEDE roller organizasyon şemasından gelir (roles.origin = 'organization'; bu uç origin'i döndürmez, row_list('roles') ile okuyun): şemadan gelen rol MCP'den yazılmaz, yönetim konsolunda düzenlenir; yetki page.roleIds ile değil access policy ile verilir (organization_schema_get).",
8
+ description: "Projenin rollerini listeler. Uç YALNIZ id + name döner (backend RoleDto bu ikisini taşır) — SLUG BURADA YOKTUR ve iki anahtar farklıdır: page_create/page_update ve microservice_create'in roleIds alanı ID ister (microservice_patch'te aynı liste '/roles' yolundadır ve öğeleri { id, name } çiftidir — yamalanan belge okuma şeklidir), buna karşılık Authorized(user.roles) ile middleware'in kurduğu user.roles SLUG karşılaştırır (platformun get-user sorgusu roles+user_roles join'inden slug dizisi üretir). Slug'ı built-in 'roles' entity'sinden okuyun (sabit id 01917ede-88a2-72ea-8397-2619e5d5dca0; row_list/microservice). ROL OLUŞTURAN BİR TOOL YOKTUR ve olmamalıdır: roller built-in datasource'taki sıradan bir entity'dir (kolonlar id · name UNIQUE · slug). Uygulamanın rol yönetmesi gerekiyorsa yol entity_get('roles') + kendi microservice ucun (uç + sayfa) ve rolü kullanıcıya bağlayan user_roles satırı — MCP'den doğrudan yazma değil; reçete platform_guide('entity') §'Hazır entity'ler'. Projeyle birlikte gelen roller çoğu senaryoya yeter; önce bu listeye bakın.",
79
9
  inputSchema: { project: projectParam, environment: environmentParam },
80
10
  annotations: readOnly
81
11
  }, handle(config, async ({ project, environment }) => {
@@ -88,307 +18,10 @@ export function registerAccessTools(server, platform) {
88
18
  inputSchema: { project: projectParam, environment: environmentParam, searchTerm: z.string().optional(), ...pagingParams },
89
19
  annotations: readOnly
90
20
  }, handle(config, ({ project, environment, ...query }) => platform.tenant('GET', project, '/users', { environment, query })));
91
- server.registerTool('user_create', {
92
- title: 'Proje kullanıcısı oluştur',
93
- description: "Projeye kullanıcı açar (POST /{project}/users). Kompleks projede kurulumun ilk adımıdır: kullanıcı önce burada doğar, sonra user_position_replace ile bir POZİSYONA oturtulur — yetkiyi veren koltuktur, buradaki roleIds değil (ACC-008). Kompleks projede doğrudan atanan rol HİÇ sayılmaz: özne rolleri yalnız pozisyondan gelir (S-15, 2026-09-21) — koltuğu olmayan kullanıcı rolsüzdür. Birleşim yalnız basit projede sürer; bkz. platform_guide('access') §Eski rol listeleri. Parola gateway günlüğüne maskeli yazılır ve yanıta girmez.",
94
- inputSchema: {
95
- project: projectParam,
96
- environment: environmentParam,
97
- id: guid.optional().describe('Verilmezse platform üretir'),
98
- email: z.string().email(),
99
- password: z.string().min(8).describe('En az 8 karakter (platform doğrulaması)'),
100
- firstName: z.string().min(1),
101
- lastName: z.string().min(1),
102
- roleIds: z.array(guid).optional().describe("role_list id'leri; kompleks projede boş bırakın ve yetkiyi pozisyondan verin")
103
- },
104
- annotations: writes
105
- }, handle(config, ({ project, environment, ...body }) => platform.tenant('POST', project, '/users', { environment, body })));
106
- server.registerTool('user_update', {
107
- title: 'Proje kullanıcısını güncelle',
108
- description: "Kullanıcının adını, parolasını ve rollerini değiştirir (PUT /{project}/users/{id}). E-posta DEĞİŞTİRİLEMEZ — gövdede yoktur. roleIds verilirse liste REPLACE edilir; dokunmak istemiyorsanız alanı hiç göndermeyin. KOMPLEKS projede bu liste yetki VERMEZ (S-15): rol pozisyondan gelir, yetkiyi user_position_replace ile verin. Parola boş bırakılırsa değişmez, verilirse en az 8 karakter olmalıdır.",
109
- inputSchema: {
110
- project: projectParam,
111
- environment: environmentParam,
112
- id: guid,
113
- firstName: z.string().min(1),
114
- lastName: z.string().min(1),
115
- password: z.string().min(8).optional().describe('Yalnız değiştirmek istiyorsanız; günlüğe maskeli yazılır'),
116
- roleIds: z.array(guid).optional()
117
- },
118
- annotations: updates
119
- }, handle(config, ({ project, environment, id, ...body }) => platform.tenant('PUT', project, `/users/${id}`, { environment, body })));
120
- server.registerTool('user_delete', {
121
- title: 'Proje kullanıcısını sil',
122
- description: "Kullanıcıyı projeden siler (DELETE /{project}/users/{id}). Silme serttir: pozisyon atamaları (koltukları) ve doğrudan politika atamaları kullanıcıyla birlikte düşer — hangi koltukların boşalacağını önceden görmek için user_position_list; ürettiği denetim kayıtları kalır. Sahip olduğu satırlar silinmez, YALNIZ KOMPLEKS projede sahiplikleri çözülür (basit modelde bu adım hiç çalışmaz): transferToUserId verilmezse sys_owner_user_id boşalır, sys_owner_unit_id kalır ve entity başına bir OWNER-RELEASED denetim kaydı yazılır (TB-106). transferToUserId verilirse satırlar devralana geçer — o zaman sys_owner_unit_id de devralanın birincil aktif pozisyonunun birimine yazılır (devralanın aktif pozisyonu yoksa birim hiç değişmez) ve kayıt OWNER-RELEASED değil REASSIGN olur. Sonucu entity_audit_trails gösterir.",
123
- inputSchema: {
124
- project: projectParam,
125
- environment: environmentParam,
126
- id: guid,
127
- transferToUserId: guid.optional().describe('Devralan kullanıcı: silinenin satırları boşa düşmek yerine buna geçer; silinen kişinin kendisi olamaz. Devralan yoksa 404 gelir ve o 404 silinecek kullanıcıyı değil DEVRALANI gösteriyor olabilir — kullanıcı silinmemiştir')
128
- },
129
- annotations: destructive
130
- }, handle(config, ({ project, environment, id, transferToUserId }) => platform.tenant('DELETE', project, `/users/${id}`, { environment, query: { transferToUserId } })));
131
21
  server.registerTool('org_role_list', {
132
22
  title: 'Organizasyon rollerini listele',
133
23
  description: 'Organization.API tarafındaki rolleri listeler (platform yönetimi); proje içi yetkilendirme için role_list kullanın. Burada da oluşturma yoktur — organizasyon rolleri platform yönetimine aittir ve uygulamanın rol tablosuyla (built-in roles entity) ilgisi yoktur.',
134
24
  inputSchema: {},
135
25
  annotations: readOnly
136
26
  }, handle(config, () => platform.org('GET', '/roles')));
137
- server.registerTool('organization_schema_get', {
138
- title: 'Organizasyon şemasını getir',
139
- description: "Organizasyonun rol yönetim şemasını (birim · pozisyon · rol ağacı) salt okunur getirir: version verilmezse taslak (draftVersion) + son yayın numarası (publishedVersion), verilirse o yayının anlık görüntüsü. Kompleks proje bu şemanın yayınlı son sürümüyle doğar (ORG-002). TASLAĞA yazmak için organization_schema_unit_create/update ve organization_schema_position_create/update; YAYIN insanın işidir (organization_schema_publish production'a yazar). Projenin kendi kopyası hazır entity'lerdedir — row_list('organization_units').",
140
- inputSchema: {
141
- organizationId: guid.optional().describe("Verilmezse gateway ORGANIZATION ayarındaki slug'la organizasyon listesinden bulur"),
142
- version: z.number().int().min(1).optional().describe('Yayın sürümü (organization_schema_get yanıtındaki publishedVersion ya da project_get organizationSchema.appliedVersion)')
143
- },
144
- annotations: readOnly
145
- }, handle(config, async ({ organizationId, version }) => {
146
- const resolvedId = organizationId ?? await currentOrganizationId(platform);
147
- const path = `/organizations/${resolvedId}/schema${version === undefined ? '' : `/versions/${version}`}`;
148
- const payload = await platform.org('GET', path);
149
- const data = (payload?.data ?? {});
150
- const lists = (version === undefined ? data : (data.snapshot ?? {}));
151
- const publishedVersion = typeof data.publishedVersion === 'number' ? data.publishedVersion : undefined;
152
- return {
153
- ...payload,
154
- summary: {
155
- organizationId: resolvedId,
156
- ...(version === undefined
157
- ? { draftVersion: data.draftVersion ?? 0, published: publishedVersion !== undefined, ...(publishedVersion !== undefined ? { publishedVersion } : {}) }
158
- : { version }),
159
- units: count(lists.units),
160
- positions: count(lists.positions),
161
- roles: count(lists.roles)
162
- },
163
- note: version === undefined
164
- ? (publishedVersion === undefined
165
- ? "Organizasyonda yayınlı şema YOK: bu anda açılan kompleks proje boş organizasyon tablolarıyla doğar (ORG-002). Taslak yönetim konsolunda yayınlanmalı."
166
- : "Dönen listeler TASLAKTIR; projelere giden yayınlı sürümün içeriği için version: publishedVersion ile çağırın.")
167
- : 'Yayının donmuş anlık görüntüsü (snapshot); abone projeler bu sürümü taşır.'
168
- };
169
- }));
170
- server.registerTool('organization_schema_unit_create', {
171
- title: 'Şema taslağına birim ekle',
172
- description: `Organizasyon şemasının TASLAĞINA yeni bir birim ekler. ${draftWriteNote} unitType yalnız ETİKETTİR: platform ebeveyn tipini denetlemez (şube doğrudan şirketin altına alınabilir), yalnız döngü ve tek kök denetlenir (TB-111). Şirket sınırı 'company' tipli birimdir ve kapsam hesabında companyIds odur. Taslak düğümün id'si yanıtta döner; pozisyon açarken unitId olarak onu verin.`,
173
- inputSchema: {
174
- organizationId: guid.optional().describe("Verilmezse gateway ORGANIZATION ayarındaki slug'la bulur"),
175
- name: z.string().min(1),
176
- code: z.string().min(1).describe('Şemada tekil kısa kod'),
177
- unitType: z.enum(unitTypes),
178
- parentId: guid.optional().describe("Üst birimin taslaktaki id'si; verilmezse kök"),
179
- functionCode: z.string().optional().describe("İşlev etiketi; grant koşulunda { subject: 'functionCodes' } ile eşleşir"),
180
- managerPositionId: guid.optional(),
181
- sortOrder: z.number().int().optional()
182
- },
183
- annotations: writes
184
- }, handle(config, async ({ organizationId, ...input }) => {
185
- const resolvedId = organizationId ?? await currentOrganizationId(platform);
186
- const draft = await readSchemaDraft(platform, resolvedId);
187
- const unit = { id: randomUUID(), parentId: null, functionCode: null, managerPositionId: null, sortOrder: 0, ...withoutUndefined(input) };
188
- return saveSchemaDraft(platform, resolvedId, { ...draft, units: [...draft.units, unit] }, `Taslağa '${input.name}' birimi eklendi (id ${unit.id}).`, unit.id);
189
- }));
190
- server.registerTool('organization_schema_unit_update', {
191
- title: 'Şema taslağındaki birimi güncelle',
192
- description: `Taslaktaki bir birimin alanlarını değiştirir. ${draftWriteNote} Verilmeyen alan KORUNUR (gateway taslağı okur, tek düğümü değiştirir, listeyi geri yazar) — projedeki organization_unit_update'ten farkı budur, o tam gövde ister. parentId vererek düğümü taşıyabilirsiniz; döngü kuran taşıma platformda reddedilir.`,
193
- inputSchema: {
194
- organizationId: guid.optional(),
195
- id: guid.describe("Birimin taslaktaki id'si (organization_schema_get)"),
196
- name: z.string().min(1).optional(),
197
- code: z.string().min(1).optional(),
198
- unitType: z.enum(unitTypes).optional(),
199
- parentId: guid.nullable().optional().describe('Yeni üst birim; null kökle eşdeğerdir'),
200
- functionCode: z.string().nullable().optional(),
201
- managerPositionId: guid.nullable().optional(),
202
- sortOrder: z.number().int().optional()
203
- },
204
- annotations: updates
205
- }, handle(config, async ({ organizationId, id, ...input }) => {
206
- const resolvedId = organizationId ?? await currentOrganizationId(platform);
207
- const draft = await readSchemaDraft(platform, resolvedId);
208
- const existing = draft.units.find(unit => unit.id === id);
209
- if (!existing)
210
- throw new PlatformApiError(`organization_schema_unit_update: '${id}' taslakta yok. organization_schema_get ile taslaktaki birimleri okuyun.`, 404);
211
- const units = draft.units.map(unit => unit.id === id ? { ...unit, ...withoutUndefined(input) } : unit);
212
- return saveSchemaDraft(platform, resolvedId, { ...draft, units }, `Taslakta '${existing.code}' birimi güncellendi.`);
213
- }));
214
- server.registerTool('organization_schema_position_create', {
215
- title: 'Şema taslağına pozisyon ekle',
216
- description: `Organizasyon şemasının TASLAĞINA yeni bir pozisyon (koltuk) ekler. ${draftWriteNote} Pozisyon şemadaki bir ROLE bağlıdır (roleId — organization_schema_get 'roles'); kullanıcının rolü kompleks projede pozisyonundan gelir. parentPositionId idari, functionalParentPositionId işlevsel hattı kurar ve 'subordinates' kapsamı bu hatlardan yürür.`,
217
- inputSchema: {
218
- organizationId: guid.optional(),
219
- unitId: guid.describe("Pozisyonun bağlı olduğu taslak birimi"),
220
- roleId: guid.describe("Şemadaki rolün id'si (organization_schema_get 'roles')"),
221
- name: z.string().min(1),
222
- code: z.string().min(1).describe('Şemada tekil kısa kod'),
223
- parentPositionId: guid.optional().describe('İdari üst pozisyon'),
224
- functionalParentPositionId: guid.optional().describe('İşlevsel üst pozisyon'),
225
- isMultiSeat: z.boolean().optional().describe('Varsayılan false: koltukta aynı anda tek KALICI kişi oturur')
226
- },
227
- annotations: writes
228
- }, handle(config, async ({ organizationId, ...input }) => {
229
- const resolvedId = organizationId ?? await currentOrganizationId(platform);
230
- const draft = await readSchemaDraft(platform, resolvedId);
231
- const position = { id: randomUUID(), parentPositionId: null, functionalParentPositionId: null, isMultiSeat: false, ...withoutUndefined(input) };
232
- return saveSchemaDraft(platform, resolvedId, { ...draft, positions: [...draft.positions, position] }, `Taslağa '${input.name}' pozisyonu eklendi (id ${position.id}).`, position.id);
233
- }));
234
- server.registerTool('organization_schema_position_update', {
235
- title: 'Şema taslağındaki pozisyonu güncelle',
236
- description: `Taslaktaki bir pozisyonun alanlarını değiştirir. ${draftWriteNote} Verilmeyen alan KORUNUR. Rolü değiştirmek yayından sonra o koltuktaki HER kullanıcının yetkisini değiştirir.`,
237
- inputSchema: {
238
- organizationId: guid.optional(),
239
- id: guid.describe("Pozisyonun taslaktaki id'si (organization_schema_get)"),
240
- unitId: guid.optional(),
241
- roleId: guid.optional(),
242
- name: z.string().min(1).optional(),
243
- code: z.string().min(1).optional(),
244
- parentPositionId: guid.nullable().optional(),
245
- functionalParentPositionId: guid.nullable().optional(),
246
- isMultiSeat: z.boolean().optional()
247
- },
248
- annotations: updates
249
- }, handle(config, async ({ organizationId, id, ...input }) => {
250
- const resolvedId = organizationId ?? await currentOrganizationId(platform);
251
- const draft = await readSchemaDraft(platform, resolvedId);
252
- const existing = draft.positions.find(position => position.id === id);
253
- if (!existing)
254
- throw new PlatformApiError(`organization_schema_position_update: '${id}' taslakta yok. organization_schema_get ile taslaktaki pozisyonları okuyun.`, 404);
255
- const positions = draft.positions.map(position => position.id === id ? { ...position, ...withoutUndefined(input) } : position);
256
- return saveSchemaDraft(platform, resolvedId, { ...draft, positions }, `Taslakta '${existing.code}' pozisyonu güncellendi.`);
257
- }));
258
- server.registerTool('organization_schema_versions', {
259
- title: 'Şema yayınlarını listele',
260
- description: "Organizasyon şemasının yayın geçmişini listeler (GET /organizations/{organizationId}/schema/versions): sürüm numarası, yayın notu, yayınlayan ve tarih. Bir projenin hangi sürümü taşıdığını project_get organizationSchema.appliedVersion söyler; aradaki farkı organization_schema_diff verir.",
261
- inputSchema: {
262
- organizationId: guid.optional().describe("Verilmezse gateway ORGANIZATION ayarındaki slug'la bulur"),
263
- pageIndex: z.number().int().min(0).optional(),
264
- pageLength: z.number().int().min(1).max(1000).optional()
265
- },
266
- annotations: readOnly
267
- }, handle(config, async ({ organizationId, ...query }) => {
268
- const resolvedId = organizationId ?? await currentOrganizationId(platform);
269
- return platform.org('GET', `/organizations/${resolvedId}/schema/versions`, { query });
270
- }));
271
- server.registerTool('organization_schema_diff', {
272
- title: 'İki şema yayınını karşılaştır',
273
- description: "İki yayın arasındaki birim/pozisyon/rol farkını verir (GET /organizations/{organizationId}/schema/diff): eklenen, silinen ve değişen düğümler. Bir projeyi yeni sürüme almadan önce 'ne değişecek' sorusunun cevabı budur — özellikle silinen birim/pozisyon, o düğüme dayanan grant'leri sahipsiz bırakır.",
274
- inputSchema: {
275
- organizationId: guid.optional(),
276
- from: z.number().int().min(1).describe("Karşılaştırmanın başlangıç sürümü — YAYINLANMIŞ bir sürüm olmalı (sürümler 1'den başlar); yayınlanmamış bir numara 404 döner. Organizasyonda hiç yayın yoksa karşılaştırılacak taban da yoktur: taslağı organization_schema_get ile okuyun"),
277
- to: z.number().int().min(1).optional().describe('Karşılaştırmanın bitiş sürümü; VERİLMEZSE yayınlanmamış TASLAKLA karşılaştırır — taslağa yazdıktan sonra "yayın neyi değiştirecek" sorusunun cevabı budur')
278
- },
279
- annotations: readOnly
280
- }, handle(config, async ({ organizationId, from, to }) => {
281
- const resolvedId = organizationId ?? await currentOrganizationId(platform);
282
- return platform.org('GET', `/organizations/${resolvedId}/schema/diff`, { query: { from, ...(to === undefined ? {} : { to }) } });
283
- }));
284
- server.registerTool('organization_schema_subscribers', {
285
- title: 'Şema abonelerini listele',
286
- description: "Organizasyon şemasına abone projeleri listeler (GET /organizations/{organizationId}/schema/subscribers): her projenin uyguladığı sürüm, aboneliğinin açık olup olmadığı ve özelleştirilmiş olup olmadığı. Bir yayının nereye ineceğini yayından ÖNCE buradan görürsünüz.",
287
- inputSchema: { organizationId: guid.optional() },
288
- annotations: readOnly
289
- }, handle(config, async ({ organizationId }) => {
290
- const resolvedId = organizationId ?? await currentOrganizationId(platform);
291
- return platform.org('GET', `/organizations/${resolvedId}/schema/subscribers`);
292
- }));
293
- server.registerTool('organization_schema_publish', {
294
- title: 'Şema taslağını yayınla',
295
- description: "Organizasyon şemasının TASLAĞINI yeni bir sürüm olarak yayınlar (POST /organizations/{organizationId}/schema/publish). GERİ ALINAMAZ ve GENİŞ ETKİLİDİR: yayın bütün abone projelere senkronize edilir ve abone projenin PRODUCTION şemasına da yazar — deployment beklemez. Yayından önce organization_schema_subscribers ile kimin etkileneceğini, organization_schema_diff ile neyin değişeceğini okuyun. Taslak yönetim konsolunda düzenlenir; bu araç yalnız yayınlar.",
296
- inputSchema: {
297
- organizationId: guid.optional(),
298
- note: z.string().max(1000).optional().describe('Yayın notu (sürüm geçmişinde görünür)')
299
- },
300
- annotations: writes
301
- }, handle(config, async ({ organizationId, note }) => {
302
- const resolvedId = organizationId ?? await currentOrganizationId(platform);
303
- const payload = await platform.org('POST', `/organizations/${resolvedId}/schema/publish`, { body: note === undefined ? {} : { note } });
304
- return { ...payload, note: 'Yayın abone projelere senkronize ediliyor; ilerlemeyi project_organization_schema_tasks ile izleyin.' };
305
- }));
306
- server.registerTool('project_organization_schema_tasks', {
307
- title: 'Projenin şema senkron görevleri',
308
- description: "Bir projenin organizasyon şeması senkron görevlerini listeler (GET /projects/{id}/organization-schema/sync-tasks): environment başına sürüm, durum (pending · processing · completed · skipped-customized · error), deneme sayısı ve hata. Yayının o projeye GERÇEKTEN indiğinin kanıtı budur; 'skipped-customized' proje özelleştirildiği için atlandığını söyler (organization_schema_resubscribe gerekir).",
309
- inputSchema: { projectId: guid },
310
- annotations: readOnly
311
- }, handle(config, ({ projectId }) => platform.org('GET', `/projects/${projectId}/organization-schema/sync-tasks`)));
312
- server.registerTool('organization_schema_resubscribe_preview', {
313
- title: 'Yeniden abonelik önizlemesi',
314
- description: "Özelleştirilmiş bir projeyi şemaya yeniden abone etmenin ne yapacağını ÖNCEDEN gösterir (POST /projects/{id}/organization-schema/resubscribe/preview): şemadan gelecek düğümler ve projede elle açılmış (custom) düğümler. Yan etkisizdir; uygulamak için organization_schema_resubscribe.",
315
- inputSchema: { projectId: guid },
316
- annotations: readOnly
317
- }, handle(config, ({ projectId }) => platform.org('POST', `/projects/${projectId}/organization-schema/resubscribe/preview`)));
318
- server.registerTool('organization_schema_drift', {
319
- title: 'Proje organizasyon sapma raporu',
320
- description: "Projenin YEREL organizasyon kopyası ile merkezi şema arasındaki farkı ortam ortam verir (GET /projects/{id}/organization-schema/drift) — 'projede ne değişti, şemada sonradan ne değişti' sorusunun cevabı budur (TB-112). İki ekseni AYIRIR: driftFromApplied = projenin UYGULADIĞI sürüme göre yerel kopyadaki fark (updated = proje bir şema düğümünü yeniden adlandırdı/taşıdı, removed = proje onu ARŞİVLEDİ, added = yerelde olup o sürümde olmayan şema düğümü); newerInSchema = aynı uygulanmış sürümden son YAYIMLANMIŞ sürüme kadar şemada olan değişiklikler. customNodes projede elle açılmış (origin=project) düğümlerdir ve sapma sayılmaz. organization_schema_diff iki YAYIMLANMIŞ sürümü karşılaştırır ve projenin kopyasını hiç görmez; bu uç tam tersine projeye bakar. Yan etkisizdir. Yalnız kompleks projede çalışır (basit projede 400).",
321
- inputSchema: { projectId: guid },
322
- annotations: readOnly
323
- }, handle(config, ({ projectId }) => platform.org('GET', `/projects/${projectId}/organization-schema/drift`)));
324
- server.registerTool('organization_schema_resubscribe', {
325
- title: 'Projeyi şemaya yeniden abone et',
326
- description: "Özelleştirilmiş bir projeyi organizasyon şemasına yeniden abone eder (POST /projects/{id}/organization-schema/resubscribe) ve projenin ağacını yayınlı son sürümle hizalar. customNodePolicy projede elle açılmış düğümlere ne olacağını söyler: 'keep' korur, 'deactivate' pasifleştirir. Etkisini önce organization_schema_resubscribe_preview ile okuyun — hizalama pozisyon silerse o pozisyona bağlı kullanıcı atamaları da düşer.",
327
- inputSchema: {
328
- projectId: guid,
329
- customNodePolicy: z.enum(['keep', 'deactivate']).optional().describe("Projede elle açılmış düğümlerin akıbeti; varsayılan 'keep'")
330
- },
331
- annotations: updates
332
- }, handle(config, ({ projectId, customNodePolicy }) => platform.org('POST', `/projects/${projectId}/organization-schema/resubscribe`, { body: customNodePolicy === undefined ? {} : { customNodePolicy } })));
333
- server.registerTool('access_model_preflight', {
334
- title: 'Erişim modeli dönüşüm ön denetimi',
335
- description: "Bir projeyi basit ↔ kompleks modele çevirmeden ÖNCE ortam ortam ölçüm yapar (POST /projects/{id}/access-model/preflight): entity ve satır sayıları, sahiplik alanı olmayan entity'ler, dış datasource'a bağlı entity'ler, sorgu ve kısıtsız sorgu sayıları, rol sayısı, rezerve tablo adı çakışmaları, sys_created_user_id'den doldurulabilir satır sayısı, middleware'e bağlı uç ve sayfa listesi, pozisyonsuz kullanıcı sayısı ve kapsamlı tabloya dokunan ham SQL sorguları. Yan etkisizdir. slugCollisions BOŞ DEĞİLSE dönüşüm yapılmamalıdır: kompleks model o adlarla sistem tabloları kurar.",
336
- inputSchema: { projectId: guid },
337
- annotations: readOnly
338
- }, handle(config, async ({ projectId }) => {
339
- const payload = await platform.org('POST', `/projects/${projectId}/access-model/preflight`);
340
- const data = (payload?.data ?? {});
341
- const environments = Array.isArray(data.environments) ? data.environments : [];
342
- const collisions = environments.flatMap(entry => Array.isArray(entry.slugCollisions) ? entry.slugCollisions : []);
343
- const withoutOwner = environments.reduce((total, entry) => total + (typeof entry.entitiesWithoutOwnerFields === 'number' ? entry.entitiesWithoutOwnerFields : 0), 0);
344
- const withDirectRoles = environments.reduce((highest, entry) => Math.max(highest, typeof entry.usersWithDirectRoles === 'number' ? entry.usersWithDirectRoles : 0), 0);
345
- const directRoleNote = withDirectRoles > 0
346
- ? ` AYRICA: bir ortamda ${withDirectRoles} kullanıcının doğrudan rol ataması (user_roles satırı) var. KOMPLEKS modelde doğrudan rol yetki VERMEZ — özne rolleri yalnız pozisyondan gelir (S-15). Sayı koltuğu olanları da kapsar; koltuğu OLMAYANLAR dönüşümden sonra her şeyden reddedilir, önce user_position_replace ile oturtun (kimin koltuksuz olduğu usersWithoutPositions ile çaprazlanır).`
347
- : '';
348
- return {
349
- ...payload,
350
- note: (collisions.length > 0
351
- ? `Tablo adı çakışması var (${[...new Set(collisions)].join(', ')}): kompleks model bu adlarla kendi sistem tablolarını kurar, dönüşümden ÖNCE bu entity'ler yeniden adlandırılmalıdır.`
352
- : withoutOwner > 0
353
- ? `${withoutOwner} entity'de sahiplik alanı yok; dönüşüm bunları arka planda ekler (owner-fields işi) ve satır kapsamları ancak o iş bittikten sonra doğru çalışır.`
354
- : 'Ön denetimde engelleyici bulgu yok. Dönüşüm yine de ortam başına asenkron koşar — access_model_conversion_tasks ile izleyin.') + directRoleNote
355
- };
356
- }));
357
- server.registerTool('access_model_convert', {
358
- title: 'Erişim modelini dönüştür',
359
- description: "Projeyi basit ↔ kompleks erişim modeline çevirir (POST /projects/{id}/access-model). GENİŞ ETKİLİ: kompleks'e geçişte organizasyon şeması uygulanır, kaynak kataloğu kurulur, geçiş politikası açılır ve sahiplik alanları arka planda doldurulur; basit'e dönüşte kompleks yetkilendirme kapanır. Her aktif environment için ayrı bir dönüşüm görevi açılır ve iş ASENKRON koşar — yanıt 'başladı' demektir, 'bitti' demez. Önce access_model_preflight, sonra access_model_conversion_tasks. enforcementMode 'enforce' olamaz: kompleks'e yeni geçen proje önce shadow'da izlenir.",
360
- inputSchema: {
361
- projectId: guid,
362
- target: z.enum(['simple', 'complex']).describe('Hedef model'),
363
- enforcementMode: z.enum(['off', 'shadow']).optional().describe("Kompleks'e geçişte aktif environment'ların zorlama modu; varsayılan 'shadow'")
364
- },
365
- annotations: writes
366
- }, handle(config, async ({ projectId, target, enforcementMode }) => {
367
- const payload = await platform.org('POST', `/projects/${projectId}/access-model`, { body: { target, ...(enforcementMode === undefined ? {} : { enforcementMode }) } });
368
- return { ...payload, note: 'Dönüşüm ortam başına asenkron koşuyor; durumu access_model_conversion_tasks ile izleyin — görev error ile kapanırsa o ortam DÖNÜŞMEMİŞ kalır.' };
369
- }));
370
- server.registerTool('access_model_conversion_tasks', {
371
- title: 'Dönüşüm görevlerini listele',
372
- description: "Projenin erişim modeli dönüşüm görevlerini listeler (GET /projects/{id}/access-model/tasks): environment, hedef model, durum (pending · processing · completed · error), deneme sayısı, hata metni ve başlangıç/bitiş zamanı. Dönüşümün gerçekten bittiğinin tek kanıtı budur; error kalan bir ortam dönüştürülmemiştir ve dönüşüm yeniden tetiklenmelidir.",
373
- inputSchema: { projectId: guid },
374
- annotations: readOnly
375
- }, handle(config, async ({ projectId }) => {
376
- const payload = await platform.org('GET', `/projects/${projectId}/access-model/tasks`);
377
- const tasks = payload?.data ?? [];
378
- const failed = tasks.filter(task => task.status === 'error');
379
- const running = tasks.filter(task => task.status === 'pending' || task.status === 'processing');
380
- return {
381
- ...payload,
382
- summary: { total: tasks.length, running: running.length, failed: failed.length },
383
- note: failed.length > 0
384
- ? `${failed.length} ortamın dönüşümü HATA ile kapandı (${failed.map(task => String(task.environment)).join(', ')}): o ortamlar dönüştürülmemiş durumdadır.`
385
- : running.length > 0
386
- ? `${running.length} ortamın dönüşümü sürüyor; bitmeden kompleks yetkilendirme o ortamda eksik çalışır.`
387
- : 'Bütün dönüşüm görevleri tamamlandı.'
388
- };
389
- }));
390
- registerAccessOperationTools(server, platform);
391
- registerOrganizationStructureTools(server, platform);
392
- registerAccessPolicyTools(server, platform);
393
- registerAccessRuntimeTools(server, platform);
394
27
  }
@@ -1,44 +1,6 @@
1
1
  import { guid, pagingParams, readOnly, writes, updates, destructive } from './common.js';
2
2
  import { handle } from '../platform/responses.js';
3
- import { forgetApplication, readApplicationPlatform, resolveApplication } from '../knowledge/platform/resolve.js';
4
- import { mobileTabsProblems, readMobileTabs } from '../knowledge/platform/mobileTabs.js';
5
- import { findingLine } from '../knowledge/platform/profile.js';
6
3
  import { z } from 'zod';
7
- /**
8
- * MOB-007 (sekme ayarı) — `properties.mobile.tabs` yazan mobil uygulama çağrısının denetimi. Yazım
9
- * platforma YİNE gider (D3; backend `properties`'i doğrulamaz): bulgu `platformWarnings`'e düşer.
10
- * Sayfa ve widget listesi okunamazsa o denetimler atlanır, biçim denetimi yine koşar.
11
- */
12
- export async function mobileTabsWarnings(platform, applicationId, projectSlug, homepageId, properties) {
13
- const tabs = readMobileTabs(properties);
14
- if (tabs === undefined)
15
- return [];
16
- const pages = applicationId && projectSlug
17
- ? await platform.tenant('GET', projectSlug, `/pages/${applicationId}`, { query: { pageIndex: 0, pageLength: 200 } })
18
- .then(response => (response?.data ?? []).map(page => ({ id: String(page.id ?? '') })))
19
- .catch(() => undefined)
20
- : undefined;
21
- const widgetIds = applicationId && projectSlug
22
- ? await platform.tenant('GET', projectSlug, `/components/${applicationId}`, { query: { pageIndex: 0, pageLength: 999 } })
23
- .then(response => new Set((response?.data ?? []).filter(entry => entry.kind === 'widget').map(entry => String(entry.id ?? ''))))
24
- .catch(() => undefined)
25
- : undefined;
26
- return mobileTabsProblems(tabs, {
27
- ...(pages ? { pages } : {}),
28
- ...(homepageId ? { homepageId } : {}),
29
- ...(widgetIds ? { widgetIds } : {})
30
- }).map(message => findingLine({
31
- code: 'MOB-007',
32
- severity: 'warn',
33
- message,
34
- guide: "platform_guide('mobile') §Gezinme"
35
- }));
36
- }
37
- function withPlatformWarnings(response, warnings) {
38
- if (warnings.length === 0 || !response || typeof response !== 'object' || Array.isArray(response))
39
- return response;
40
- return { ...response, platformWarnings: warnings };
41
- }
42
4
  export function registerApplicationTools(server, platform) {
43
5
  const config = platform.config;
44
6
  server.registerTool('application_list', {
@@ -72,14 +34,7 @@ export function registerApplicationTools(server, platform) {
72
34
  notFoundPageId: guid.optional()
73
35
  },
74
36
  annotations: writes
75
- }, handle(config, async ({ projectId, ...body }) => {
76
- const warnings = readApplicationPlatform(body.type) === 'mobile'
77
- ? await mobileTabsWarnings(platform, undefined, undefined, undefined, body.properties)
78
- : [];
79
- const response = await platform.org('POST', `/applications/${projectId}`, { body });
80
- forgetApplication(platform);
81
- return withPlatformWarnings(response, warnings);
82
- }));
37
+ }, handle(config, ({ projectId, ...body }) => platform.org('POST', `/applications/${projectId}`, { body })));
83
38
  server.registerTool('application_update', {
84
39
  title: 'Application güncelle',
85
40
  description: 'Application bilgilerini günceller; homepageId zorunludur (mevcut değeri application_get ile alın).',
@@ -94,23 +49,11 @@ export function registerApplicationTools(server, platform) {
94
49
  notFoundPageId: guid.optional()
95
50
  },
96
51
  annotations: updates
97
- }, handle(config, async ({ id, ...body }) => {
98
- const current = await resolveApplication(platform, id);
99
- const warnings = current?.platform === 'mobile'
100
- ? await mobileTabsWarnings(platform, id, current.projectSlug, body.homepageId, body.properties)
101
- : [];
102
- const response = await platform.org('PUT', `/applications/${id}`, { body });
103
- forgetApplication(platform, id);
104
- return withPlatformWarnings(response, warnings);
105
- }));
52
+ }, handle(config, ({ id, ...body }) => platform.org('PUT', `/applications/${id}`, { body })));
106
53
  server.registerTool('application_delete', {
107
54
  title: 'Application sil',
108
55
  description: 'Application\'ı kalıcı olarak siler.',
109
56
  inputSchema: { id: guid },
110
57
  annotations: destructive
111
- }, handle(config, async (args) => {
112
- const response = await platform.org('DELETE', `/applications/${args.id}`);
113
- forgetApplication(platform, args.id);
114
- return response;
115
- }));
58
+ }, handle(config, args => platform.org('DELETE', `/applications/${args.id}`)));
116
59
  }
@@ -28,13 +28,6 @@ export const environmentParam = z.string().min(1).optional()
28
28
  .describe('Environment adı (X-Environment); boşsa DEFAULT_ENVIRONMENT kullanılır');
29
29
  export const languageParam = z.string().min(1).optional()
30
30
  .describe("İstek dili (ISO 639-1, ör. 'en'); X-Data-Language olarak gider. Çok dilli alanlar bu dilde okunur/yazılır, workflow'da context.language ve ham sorguda {{language}} bu değeri alır. Verilmezse platform Accept-Language'a, o da yoksa projenin varsayılan diline düşer. Bölgeli değer ('tr-TR') kabul edilir ve gateway indirger.");
31
- /**
32
- * 38/M-1: kompleks + enforce projede runtime araçları uygulama oturumu istiyordu ve oturum yalnız
33
- * parolayla açılıyordu. Platform production dışında gateway'in kimliği doğrulanmış isteğine bu başlıkla
34
- * özne kurar (`AppSessionMiddleware`); denetimler `platform/impersonation.ts`'tedir.
35
- */
36
- export const asUserIdParam = z.string().uuid().optional()
37
- .describe("Parolasız kullanıcı gözü: users satır id'si (user_list). İstek gateway kimliğiyle ve 'impersonated-user-id' başlığıyla gider; platform özneyi bu kullanıcı olarak kurar — kompleks projede politika, satır kapsamı ve alan maskesi o kullanıcınındır, parola ve oturum gerekmez. Yalnız development ya da dal: production'da platform başlığı düşürür, runtime araçları isteği göndermeden reddeder. asUser ve anonymous ile birlikte verilemez; projede olmayan id reddedilir (platform onu sessizce yok sayıp gateway kimliğiyle yürütürdü).");
38
31
  export const definitionParam = z.record(z.unknown())
39
32
  .describe('API komut gövdesi birebir geçirilir; şablon için ilgili *_get çıktısını ya da ngapps://schemas kaynağını kullanın');
40
33
  /**