@appaflytech/zeyrek-ai-mcp 0.0.31 → 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 (205) 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 +233 -568
  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 -366
  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/middleware-authenticate.json +1 -1
  30. package/dist/resources/examples/page-detail-profile.json +1 -2
  31. package/dist/resources/examples/page-dynamic-form.json +2 -3
  32. package/dist/resources/examples/page-flex-sections.json +1 -1
  33. package/dist/resources/examples/page-html-embed.json +1 -1
  34. package/dist/resources/examples/workflow-basic.json +2 -8
  35. package/dist/resources/guides/component.md +5 -92
  36. package/dist/resources/guides/entity.md +8 -50
  37. package/dist/resources/guides/expressions.md +5 -14
  38. package/dist/resources/guides/functions.md +1 -1
  39. package/dist/resources/guides/getting-started.md +1 -38
  40. package/dist/resources/guides/layout.md +58 -55
  41. package/dist/resources/guides/merge.md +3 -37
  42. package/dist/resources/guides/microservice.md +2 -87
  43. package/dist/resources/guides/middleware.md +4 -68
  44. package/dist/resources/guides/page.md +75 -456
  45. package/dist/resources/guides/theme.md +2 -8
  46. package/dist/resources/guides/translation.md +1 -1
  47. package/dist/resources/guides/workflow.md +1 -58
  48. package/dist/resources/rules.js +5 -11
  49. package/dist/resources/schema-fingerprint.json +5 -7
  50. package/dist/resources/schemas/CreateEntityCommand.json +0 -118
  51. package/dist/resources/schemas/CreateMicroserviceCommand.json +1 -13
  52. package/dist/resources/schemas/CreateQueryCommand.json +0 -4
  53. package/dist/resources/schemas/CreateWorkflowCommand.json +1 -146
  54. package/dist/resources/schemas/DataJobDto.json +1 -6
  55. package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +1 -21
  56. package/dist/resources/schemas/MicroserviceDto.json +3 -15
  57. package/dist/resources/schemas/PreviewMicroserviceCommand.json +1 -10
  58. package/dist/resources/schemas/PreviewWorkflowCommand.json +1 -25
  59. package/dist/resources/schemas/StepDto.json +1 -25
  60. package/dist/resources/schemas/UpdateEntityCommand.json +0 -118
  61. package/dist/resources/schemas/UpdateMicroserviceCommand.json +1 -13
  62. package/dist/resources/schemas/UpdateQueryCommand.json +0 -4
  63. package/dist/resources/schemas/UpdateViewCommand.json +2 -0
  64. package/dist/resources/schemas/UpdateWorkflowCommand.json +1 -146
  65. package/dist/server.js +1 -27
  66. package/dist/tools/access.js +2 -369
  67. package/dist/tools/applications.js +3 -60
  68. package/dist/tools/common.js +0 -7
  69. package/dist/tools/components.js +14 -118
  70. package/dist/tools/datasources.js +3 -3
  71. package/dist/tools/dependencies.js +1 -1
  72. package/dist/tools/deployments.js +3 -38
  73. package/dist/tools/designSchemaPatch.js +18 -34
  74. package/dist/tools/dtos.js +5 -36
  75. package/dist/tools/entities.js +12 -79
  76. package/dist/tools/externalComponents.js +5 -26
  77. package/dist/tools/flows.js +14 -122
  78. package/dist/tools/folders.js +1 -1
  79. package/dist/tools/imports.js +2 -5
  80. package/dist/tools/layouts.js +17 -50
  81. package/dist/tools/merges.js +2 -2
  82. package/dist/tools/microservices.js +25 -77
  83. package/dist/tools/pages.js +112 -465
  84. package/dist/tools/platformInfo.js +8 -27
  85. package/dist/tools/projects.js +9 -71
  86. package/dist/tools/rows.js +13 -69
  87. package/dist/tools/schemaOps.js +1 -61
  88. package/dist/tools/screenWrite.js +8 -37
  89. package/dist/tools/screens.js +5 -95
  90. package/dist/tools/templates.js +1 -26
  91. package/dist/tools/translations.js +1 -1
  92. package/dist/tools/variables.js +5 -11
  93. package/dist/tools/workflows.js +5 -10
  94. package/package.json +1 -1
  95. package/dist/knowledge/access.js +0 -802
  96. package/dist/knowledge/case.js +0 -41
  97. package/dist/knowledge/connectDataBind.js +0 -819
  98. package/dist/knowledge/connectDataDefinition.js +0 -341
  99. package/dist/knowledge/connectDataExecute.js +0 -93
  100. package/dist/knowledge/connectDataRules.js +0 -128
  101. package/dist/knowledge/decision.js +0 -121
  102. package/dist/knowledge/expressionPrelude.js +0 -59
  103. package/dist/knowledge/microserviceParameters.js +0 -58
  104. package/dist/knowledge/mining.js +0 -94
  105. package/dist/knowledge/mobileComponentCatalog.js +0 -859
  106. package/dist/knowledge/mobileComponentEvents.js +0 -239
  107. package/dist/knowledge/platform/lint.js +0 -385
  108. package/dist/knowledge/platform/mobile.js +0 -142
  109. package/dist/knowledge/platform/mobileLayoutLint.js +0 -324
  110. package/dist/knowledge/platform/mobileRules.js +0 -231
  111. package/dist/knowledge/platform/mobileSpacing.js +0 -82
  112. package/dist/knowledge/platform/mobileTabs.js +0 -108
  113. package/dist/knowledge/platform/nativeBoxModel.js +0 -44
  114. package/dist/knowledge/platform/profile.js +0 -25
  115. package/dist/knowledge/platform/resolve.js +0 -122
  116. package/dist/knowledge/platform/web.js +0 -39
  117. package/dist/knowledge/process.js +0 -510
  118. package/dist/knowledge/rowFilter.js +0 -43
  119. package/dist/knowledge/styleResolveNative.js +0 -527
  120. package/dist/platform/argumentAliases.js +0 -128
  121. package/dist/platform/bodyFile.js +0 -103
  122. package/dist/platform/capture/actions.js +0 -333
  123. package/dist/platform/capture/browser.js +0 -1
  124. package/dist/platform/capture/console-log.js +0 -122
  125. package/dist/platform/capture/index.js +0 -11
  126. package/dist/platform/capture/readiness.js +0 -103
  127. package/dist/platform/capture/summary.js +0 -77
  128. package/dist/platform/capture/target.js +0 -5
  129. package/dist/platform/capture/targets/studio-mobile.js +0 -15
  130. package/dist/platform/capture/targets/studio-web.js +0 -5
  131. package/dist/platform/impersonation.js +0 -45
  132. package/dist/platform/jsonArray.js +0 -24
  133. package/dist/platform/schemaReadMemory.js +0 -60
  134. package/dist/resources/examples/bpm-gorev-kontrol.json +0 -294
  135. package/dist/resources/examples/bpm-iso-dokuman.json +0 -228
  136. package/dist/resources/examples/bpm-satinalma.json +0 -376
  137. package/dist/resources/examples/connect-data-convert-verify.json +0 -107
  138. package/dist/resources/examples/connect-data-dropdown-roles.json +0 -66
  139. package/dist/resources/examples/connect-data-edit-m2m.json +0 -73
  140. package/dist/resources/examples/connect-data-query-params.json +0 -50
  141. package/dist/resources/examples/connect-data-table-entity.json +0 -147
  142. package/dist/resources/examples/connect-data-workflow-microservice.json +0 -65
  143. package/dist/resources/examples/mobile-app-shell-drawer.json +0 -243
  144. package/dist/resources/examples/mobile-app-shell-stack.json +0 -157
  145. package/dist/resources/examples/mobile-app-shell-tab.json +0 -208
  146. package/dist/resources/examples/mobile-form-screen.json +0 -365
  147. package/dist/resources/examples/mobile-list-detail-form.json +0 -672
  148. package/dist/resources/guides/access.md +0 -810
  149. package/dist/resources/guides/bpm.md +0 -691
  150. package/dist/resources/guides/case.md +0 -153
  151. package/dist/resources/guides/decision.md +0 -185
  152. package/dist/resources/guides/mobile-layout.md +0 -193
  153. package/dist/resources/guides/mobile.md +0 -495
  154. package/dist/resources/read.js +0 -41
  155. package/dist/resources/schemas/AccessExplanationDto.json +0 -144
  156. package/dist/resources/schemas/AccessMatrixDto.json +0 -170
  157. package/dist/resources/schemas/AccessPermissionDto.json +0 -57
  158. package/dist/resources/schemas/AccessPolicyDto.json +0 -223
  159. package/dist/resources/schemas/AccessResourceDto.json +0 -86
  160. package/dist/resources/schemas/AppSessionDto.json +0 -53
  161. package/dist/resources/schemas/ConnectDataDescribeDto.json +0 -344
  162. package/dist/resources/schemas/ConnectDataRequestModel.json +0 -202
  163. package/dist/resources/schemas/ConnectDataResultDto.json +0 -421
  164. package/dist/resources/schemas/ConnectorCredentialDto.json +0 -70
  165. package/dist/resources/schemas/ConvertConnectDataToMicroserviceCommand.json +0 -37
  166. package/dist/resources/schemas/CreateAccessPolicyCommand.json +0 -209
  167. package/dist/resources/schemas/CreateDecisionCommand.json +0 -221
  168. package/dist/resources/schemas/CreateProcessDefinitionCommand.json +0 -1337
  169. package/dist/resources/schemas/DecisionDto.json +0 -302
  170. package/dist/resources/schemas/DetachConnectDataMicroserviceCommand.json +0 -28
  171. package/dist/resources/schemas/ExplainAccessQuery.json +0 -33
  172. package/dist/resources/schemas/GenerateProcessDocumentCommand.json +0 -116
  173. package/dist/resources/schemas/OrganizationProjectDto.json +0 -335
  174. package/dist/resources/schemas/OrganizationSchemaDto.json +0 -196
  175. package/dist/resources/schemas/OrganizationSchemaVersionDto.json +0 -207
  176. package/dist/resources/schemas/PatchProcessDefinitionCommand.json +0 -76
  177. package/dist/resources/schemas/ProcessDefinitionDto.json +0 -1480
  178. package/dist/resources/schemas/ProcessSimulationDto.json +0 -96
  179. package/dist/resources/schemas/SaveConnectorCredentialCommand.json +0 -90
  180. package/dist/resources/schemas/SaveProcessEventSourceCommand.json +0 -61
  181. package/dist/resources/schemas/SaveProcessMailSourceCommand.json +0 -89
  182. package/dist/resources/schemas/SignProcessTaskCommand.json +0 -73
  183. package/dist/resources/schemas/SimulateProcessDefinitionQuery.json +0 -92
  184. package/dist/resources/schemas/UpdateAccessPolicyCommand.json +0 -209
  185. package/dist/resources/schemas/UpdateDecisionCommand.json +0 -216
  186. package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +0 -1357
  187. package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +0 -1339
  188. package/dist/tools/accessOperations.js +0 -135
  189. package/dist/tools/accessPolicies.js +0 -170
  190. package/dist/tools/accessRuntime.js +0 -203
  191. package/dist/tools/bpm.js +0 -343
  192. package/dist/tools/bpmGovernance.js +0 -266
  193. package/dist/tools/bpmOperations.js +0 -230
  194. package/dist/tools/bpmReporting.js +0 -154
  195. package/dist/tools/bpmRouting.js +0 -150
  196. package/dist/tools/bpmRuntime.js +0 -396
  197. package/dist/tools/case.js +0 -178
  198. package/dist/tools/caseRuntime.js +0 -89
  199. package/dist/tools/connectData.js +0 -449
  200. package/dist/tools/connectors.js +0 -193
  201. package/dist/tools/decisions.js +0 -206
  202. package/dist/tools/mobile.js +0 -221
  203. package/dist/tools/modules.js +0 -48
  204. package/dist/tools/organizationStructure.js +0 -137
  205. package/dist/tools/profileWrite.js +0 -92
package/.env.example CHANGED
@@ -51,21 +51,6 @@ REQUEST_TIMEOUT_MS=100000
51
51
  STUDIO_BASE_URL=http://localhost:3000
52
52
  SCREENSHOT_BROWSER_PATH=
53
53
 
54
- # Jeton kasasi (g-09): MCP_STATE_DIR verilirse tok_ referanslari ve test kullanicisi jetonlari
55
- # <dizin>/token-vault.json'a (0600) yazilir ve gateway yeniden baslayinca da cozulur. Yalniz lokal
56
- # hedefte (ORG_API_BASE_URL localhost) yazilir. MCP_TOKEN_TTL_MINUTES referansin omru (dakika).
57
- MCP_STATE_DIR=
58
- MCP_TOKEN_TTL_MINUTES=60
59
-
60
- # asUser: 'test:<ad>' icin test kullanicilari — satiri INSAN yazar, AI .env'i duzenlemez.
61
- # Bicim (JSON, tek satir): uygulamanin kendi giris ucu ve onun bekledigi govde. Ayrinti: docs/ortam.md
62
- # MCP_TEST_USER_OGRENCI={"application":"<uygulama slug>","microservice":"<giris ucu slug>","body":{"email":"…","password":"…"}}
63
-
64
- # bodyFile icin: tanim yazan araclarin (page_create, flow_create, microservice_create, *_patch …)
65
- # govdeyi okuyabilecegi ek dizin. Gateway surecinin calisma dizini her zaman izinlidir; bu dizin
66
- # ek olarak izinli olur. Bos birakilirsa yalniz calisma dizini okunur. Sembolik bag cozulur.
67
- MCP_INPUT_DIR=
68
-
69
54
  # generate-schemas icin swagger adresleri. Bos birakilirsa sirayla denenir:
70
55
  # 1) asagidaki override, 2) {API_BASE_URL}/swagger/v1/swagger.json, 3) localhost:3000 frontend proxy'si
71
56
  ORG_SWAGGER_URL=
package/README.md CHANGED
@@ -4,7 +4,7 @@ Zeyrek (NgApps) platformunu **MCP tool'ları** olarak sunan bağımsız gateway.
4
4
  oturumu Studio arayüzüne hiç girmeden proje kurabilir, veri modeli çıkarabilir, mikroservis ve
5
5
  workflow yazıp çalıştırabilir, sayfa tasarlayabilir.
6
6
 
7
- - **260 tool · 35 modül** — veri/mantık tarafı (project, application, datasource, entity, row,
7
+ - **212 tool · 34 modül** — veri/mantık tarafı (project, application, datasource, entity, row,
8
8
  import, microservice, query, workflow, automation, function, dto, view, dependency), Studio
9
9
  tasarım tarafı (page, **theme**, component, external component, flow, layout, variable, function,
10
10
  folder, file, access, translation), yönetim (template, organization, deployment) ve proje dallanması
@@ -140,10 +140,10 @@ ya da ikisi karışık (`core,page`). `platform` modülü (3 tool) her kümede v
140
140
 
141
141
  | Küme | Tool | Modüller |
142
142
  |---|---|---|
143
- | `core` | 280 | platform, project, application, datasource, entity, row, import, microservice, microfunction, query, workflow, automation, function, dto, view, access, dependency, environment, merge, activity, revision, bpm, bpmRuntime, bpmOperations, bpmRouting, bpmGovernance, bpmReporting, decision, connector, case, caseRuntime, module |
144
- | `studio` | 119 | platform, page, theme, component, externalComponent, flow, layout, variable, function, folder, file, import, access, translation, revision |
145
- | `admin` | 28 | platform, template, organization, deployment, environment, merge, activity |
146
- | (boş) | **354** | 45 modülün tamamı (ölçüm 2026-09-18, `listTools()`) |
143
+ | `core` | 136 | platform, project, application, datasource, entity, row, import, microservice, microfunction, query, workflow, automation, function, dto, view, dependency, environment, merge, activity, revision |
144
+ | `studio` | 82 | platform, page, theme, component, externalComponent, flow, layout, variable, function, folder, file, import, access, translation, revision |
145
+ | `admin` | 27 | platform, template, organization, deployment, environment, merge, activity |
146
+ | (boş) | **212** | 34 modülün tamamı (ölçüm 2026-09-16, `listTools()`) |
147
147
 
148
148
  Bilinmeyen bir modül/küme adı verilirse sunucu açılmaz, geçerli adları listeleyen bir hata yazar.
149
149
 
package/dist/config.js CHANGED
@@ -35,19 +35,6 @@ export const moduleNames = [
35
35
  "merge",
36
36
  "activity",
37
37
  "revision",
38
- "connectData",
39
- "bpm",
40
- "bpmRuntime",
41
- "bpmOperations",
42
- "bpmRouting",
43
- "bpmGovernance",
44
- "bpmReporting",
45
- "decision",
46
- "connector",
47
- "case",
48
- "caseRuntime",
49
- "module",
50
- "mobile",
51
38
  ];
52
39
  export const modulePresets = {
53
40
  core: [
@@ -66,24 +53,11 @@ export const modulePresets = {
66
53
  "function",
67
54
  "dto",
68
55
  "view",
69
- "access",
70
56
  "dependency",
71
57
  "environment",
72
58
  "merge",
73
59
  "activity",
74
60
  "revision",
75
- "connectData",
76
- "bpm",
77
- "bpmRuntime",
78
- "bpmOperations",
79
- "bpmRouting",
80
- "bpmGovernance",
81
- "bpmReporting",
82
- "decision",
83
- "connector",
84
- "case",
85
- "caseRuntime",
86
- "module",
87
61
  ],
88
62
  studio: [
89
63
  "platform",
@@ -101,8 +75,6 @@ export const modulePresets = {
101
75
  "access",
102
76
  "translation",
103
77
  "revision",
104
- "connectData",
105
- "mobile",
106
78
  ],
107
79
  admin: ["platform", "template", "organization", "deployment", "environment", "merge", "activity"],
108
80
  };
@@ -146,9 +118,6 @@ const environmentSchema = z.object({
146
118
  STUDIO_BASE_URL: z.string().url().optional(),
147
119
  SCREENSHOT_BROWSER_PATH: z.string().min(1).optional(),
148
120
  SCREENSHOT_QUEUE_WAIT_MS: z.coerce.number().int().positive().default(120000),
149
- MCP_INPUT_DIR: z.string().min(1).optional(),
150
- MCP_STATE_DIR: z.string().min(1).optional(),
151
- MCP_TOKEN_TTL_MINUTES: z.coerce.number().int().positive().optional(),
152
121
  });
153
122
  export const environmentKeys = Object.keys(environmentSchema.shape);
154
123
  /**
@@ -257,11 +226,5 @@ export function loadConfig(env) {
257
226
  studioBaseUrl: values.STUDIO_BASE_URL?.replace(/\/+$/, ""),
258
227
  screenshotBrowserPath: values.SCREENSHOT_BROWSER_PATH,
259
228
  screenshotQueueWaitMs: values.SCREENSHOT_QUEUE_WAIT_MS,
260
- inputDirectory: values.MCP_INPUT_DIR,
261
- stateDirectory: values.MCP_STATE_DIR,
262
- tokenTtlMinutes: values.MCP_TOKEN_TTL_MINUTES,
263
- testUsers: Object.fromEntries(Object.entries(env)
264
- .filter((entry) => entry[0].startsWith("MCP_TEST_USER_") && typeof entry[1] === "string" && entry[1] !== "")
265
- .map(([key, value]) => [key.slice("MCP_TEST_USER_".length).toLowerCase(), value])),
266
229
  };
267
230
  }
package/dist/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
3
3
  import { configureLogging, logGatewayEvent } from './observability/trace.js';
4
- import { configureTokenVault } from './platform/tokenVault.js';
5
4
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
5
  import { Platform, requestAuthStorage } from './platform/http.js';
7
6
  import { createGatewayServer } from './server.js';
@@ -32,7 +31,6 @@ catch (error) {
32
31
  const platform = new Platform(config);
33
32
  const useStdio = process.argv.includes('--stdio');
34
33
  configureLogging(config, useStdio ? 'stdio' : 'http');
35
- configureTokenVault(config);
36
34
  if (useStdio) {
37
35
  if (config.authMode === 'passthrough') {
38
36
  logger.error('stdio kipi passthrough auth ile kullanılamaz; AUTH_MODE=local yapın.');
@@ -639,14 +639,6 @@ function projectCreateFindings(body) {
639
639
  }
640
640
  return [];
641
641
  }
642
- function projectSlugFindings(body) {
643
- if (body.slug === undefined || body.slug === null)
644
- return [];
645
- const slug = String(body.slug);
646
- return /^[a-z0-9]+([-_][a-z0-9]+)*$/.test(slug) && slug.length >= 2 && slug.length <= 40
647
- ? []
648
- : [`slug: '${slug}' veritabanı ve rol adının parçası olur (zeyrek_<org>_<slug>, <org>_<slug>__<ortam>) — 2–40 karakter, yalnız küçük harf ve rakam, parçalar arasında tek '-' ya da '_' (örn. 'satis-crm', 'satis_crm'); '__', tırnak, boşluk ve büyük harf reddedilir.`];
649
- }
650
642
  function languageFindings(label, codes) {
651
643
  const unknown = codes.filter(code => !SUPPORTED_LANGUAGES.includes(code));
652
644
  return unknown.length === 0
@@ -826,18 +818,9 @@ export const backendRules = [
826
818
  commands: { create: 'CreateOrganizationProjectCommand' },
827
819
  status: 409,
828
820
  summary: "templateOptions yoksa application zorunlu · slug organizasyonda tekil (veritabanı adı zeyrek_<org>_<slug>; çakışma eski build'de 500, 2026-09-08 sonrası 409)",
829
- sourceRef: "CreateOrganizationProjectCommandValidator: When(TemplateOptions null) Application.NotNull(); OrganizationProjectService.CreateAsync: ExistsByDatabaseNameAsync (organizasyonlar arası, 2026-09-25) ⇒ DatabaseNameAlreadyExistsException (ExceptionHandler eşlemesi 2026-09-08'de 409'a alındı). Gateway POST'tan önce project_list ile slug'ı arar. Ölçüm: 2026-09-08 3. koşu S-1 / P3-7",
821
+ sourceRef: "CreateOrganizationProjectCommandValidator: When(TemplateOptions null) Application.NotNull(); OrganizationProjectService.CreateAsync: ExistsByOrganizationAndDatabaseNameAsync ⇒ DatabaseNameAlreadyExistsException (ExceptionHandler eşlemesi 2026-09-08'de 409'a alındı). Gateway POST'tan önce project_list ile slug'ı arar. Ölçüm: 2026-09-08 3. koşu S-1 / P3-7",
830
822
  check: body => projectCreateFindings(body)
831
823
  },
832
- {
833
- id: 'PRJ-005',
834
- module: 'project',
835
- commands: { create: 'CreateOrganizationProjectCommand' },
836
- status: 422,
837
- summary: "slug ^[a-z0-9]+([-_][a-z0-9]+)*$, 2–40 (veritabanı ve rol adının parçası; '__' ortam rolü ayırıcısı olduğu için yasak) · zeyrek_<org>_<slug> ≤ 63 bayt, organizasyonlar arası tekil",
838
- sourceRef: "CreateOrganizationProjectCommandValidator: Slug.Length(DatabaseSlugMinLength, DatabaseSlugMaxLength).Matches(DatabaseSlugPattern); OrganizationProjectService.CreateAsync: DatabaseSettings.IsDatabaseSlug ⇒ DatabaseSlugInvalidException (422, her oluşturma yolu — içe aktarma dahil), DatabaseNameTooLongException (422), ExistsByDatabaseNameAsync ⇒ DatabaseNameAlreadyExistsException (409). Güncellemede kural yalnız slug DEĞİŞİRSE serviste işler (eski slug'lı projeler güncellenebilsin; gateway PRJ-004 gereği her project_update gövdesine mevcut slug'ı koyar, bu yüzden gateway update'te bloklamaz). K-21, 2026-09-25",
839
- check: body => projectSlugFindings(body)
840
- },
841
824
  {
842
825
  id: 'PRJ-002',
843
826
  module: 'project',
@@ -0,0 +1,184 @@
1
+ function asObjects(value) {
2
+ return Array.isArray(value) ? value.filter((entry) => !!entry && typeof entry === 'object' && !Array.isArray(entry)) : [];
3
+ }
4
+ /**
5
+ * Bölge bir bayrak değil DÜĞÜMDÜR (QA BX-002, 2026-09-30). Studio `hasHeader`/`hasFooter`
6
+ * anahtarını çevirince `syncBoxSections` (zeyrek-frontend `box-sections.store.ts`) ayrı bir
7
+ * `box-section` çocuğu kurar; runtime ve kanvas bölgeyi o düğümün `role` prop'undan çizer
8
+ * (`box-shell.ts` `groupBoxShellChildren`). Gateway yalnız bayrağı yazıyordu: panel "Has header"
9
+ * işaretli, ekranda ve kanvasta bölge yok (qa-box-01 / bx_hdrflag ölçümü). Bu modül Studio'nun
10
+ * yaptığını yamaya ekler — `page_container`'ı kendisi kurduğu gibi (`ensurePageContainer`).
11
+ */
12
+ export const BOX_SECTION_HOSTS = new Set(['box', 'aibox']);
13
+ export const BOX_SECTION_TYPE = 'box-section';
14
+ const SECTION_FLAGS = { hasHeader: 'header', hasFooter: 'footer' };
15
+ /**
16
+ * Studio'nun bölgeye yazdığı prop'lar: `box-section/schema.ts` varsayılanları + `role`.
17
+ * Kopyadır, çünkü gateway katalog varsayılanını yazma anında okumaz; `page_container` yerleşim
18
+ * setiyle aynı emsal. Eksik bırakılsa bölge `verticalAlign` yokken üste yaslanır, `wrap` yokken
19
+ * sarmazdı (`flex-layout.ts` `FLEX_ABSENT_PROPS`) — Studio'nun kurduğu bölgeden farklı çizilirdi.
20
+ */
21
+ const SECTION_PROPS = {
22
+ layout: 'flex',
23
+ direction: 'row',
24
+ horizontalAlign: 'left',
25
+ verticalAlign: 'middle',
26
+ size: 'shrink',
27
+ gap: 'medium',
28
+ wrap: true
29
+ };
30
+ const propData = (value) => value && typeof value === 'object' && !Array.isArray(value) && 'type' in value ? value.data : value;
31
+ const isSection = (node) => node.type === BOX_SECTION_TYPE;
32
+ /** Rol yazılmamışsa `header` sayılır — `box-shell.ts` `sectionRoleOf` ile aynı kural. */
33
+ const roleOf = (node) => propData(node.props?.role) === 'footer' ? 'footer' : 'header';
34
+ const findSection = (children, role) => children.find(child => isSection(child) && roleOf(child) === role);
35
+ const uniqueId = (base, taken) => {
36
+ let id = base;
37
+ for (let suffix = 2; taken.has(id); suffix++)
38
+ id = `${base}_${suffix}`;
39
+ taken.add(id);
40
+ return id;
41
+ };
42
+ /**
43
+ * Studio `generateBoxSection` şeklinin aynısı: 12 kolon blok (başlık y=0, altlık y=999), bırakılabilir,
44
+ * kendi boşluğunu eklemez (`marginType/paddingType: 'none'`). Tohum metni YOKTUR — Studio'daki
45
+ * "Header"/"Footer" yer tutucusu tasarımcıya bir davet; AI içeriği kendisi koyar.
46
+ */
47
+ export function boxSectionNode(boxId, role, taken) {
48
+ const elementId = uniqueId(`${boxId}_${role}`, taken);
49
+ return {
50
+ elementId,
51
+ name: elementId,
52
+ kind: 'component',
53
+ type: BOX_SECTION_TYPE,
54
+ // Prop sarmalı burada kurulur: layout/widget yazma yolunda normalizasyon kaydı okumadan ÖNCE
55
+ // koşar, bölge ondan sonra eklenir (`designSchemaPatch.ts`). Çıplak değer platformda 422 verir.
56
+ props: Object.fromEntries(Object.entries({ ...SECTION_PROPS, role }).map(([name, data]) => [name, { type: 'static', ref: null, data }])),
57
+ blocks: [{ breakpoint: 1024, size: { w: 12, h: role === 'header' ? 6 : 5 }, position: { x: 0, y: role === 'header' ? 0 : 999 } }],
58
+ states: { isSticky: false, isDroppable: true, isScrollable: false, isWrapper: false, isFloating: false, isQuickStack: false },
59
+ appearance: { heightType: 'auto', marginType: 'none', paddingType: 'none' },
60
+ events: [],
61
+ validations: [],
62
+ stateBindings: [],
63
+ children: []
64
+ };
65
+ }
66
+ export function collectIds(nodes, into) {
67
+ for (const node of asObjects(nodes)) {
68
+ if (typeof node.elementId === 'string')
69
+ into.add(node.elementId);
70
+ collectIds(node.children, into);
71
+ }
72
+ return into;
73
+ }
74
+ /**
75
+ * add_component gövdelerindeki box/aibox düğümlerine eksik bölgeyi ekler (iç içe kutular dahil).
76
+ * Başlık ilk, altlık son çocuk olur (`orderBoxChildren`). Verilmiş bölge ikinci kez eklenmez.
77
+ */
78
+ export function ensureBoxSections(nodes, taken) {
79
+ const created = [];
80
+ for (const node of asObjects(nodes)) {
81
+ if (BOX_SECTION_HOSTS.has(String(node.type))) {
82
+ const props = (node.props ?? {});
83
+ const children = asObjects(node.children);
84
+ for (const [flag, role] of Object.entries(SECTION_FLAGS)) {
85
+ if (propData(props[flag]) !== true || findSection(children, role))
86
+ continue;
87
+ const section = boxSectionNode(String(node.elementId ?? node.type), role, taken);
88
+ if (role === 'header')
89
+ children.unshift(section);
90
+ else
91
+ children.push(section);
92
+ created.push(String(section.elementId));
93
+ }
94
+ node.children = children;
95
+ }
96
+ created.push(...ensureBoxSections(node.children, taken));
97
+ }
98
+ return created;
99
+ }
100
+ function findNode(nodes, elementId) {
101
+ for (const node of asObjects(nodes)) {
102
+ if (node.elementId === elementId)
103
+ return node;
104
+ const nested = findNode(node.children, elementId);
105
+ if (nested)
106
+ return nested;
107
+ }
108
+ return undefined;
109
+ }
110
+ const blockOf = (node) => {
111
+ const position = (asObjects(node.blocks)[0]?.position ?? {});
112
+ return { x: Number(position.x) || 0, y: Number(position.y) || 0 };
113
+ };
114
+ /**
115
+ * Kapatılan bölgenin çocukları gövdenin neresine gider: başlığınkiler başa, altlığınkiler sona.
116
+ * Studio `orphanTargetY` ile aynı kural — sıra blok konumundan türetilir, eski y'yi koruyan düğüm
117
+ * gövdenin ORTASINA düşerdi.
118
+ */
119
+ function orphanY(role, body) {
120
+ const ys = body.map(child => blockOf(child).y);
121
+ if (ys.length === 0)
122
+ return 0;
123
+ return role === 'header' ? Math.min(...ys) - 1 : Math.max(...ys) + 1;
124
+ }
125
+ /**
126
+ * Studio bölgeyi açarken içine "Header"/"Footer" metni koyar; dokunulmadıysa bölgeyle birlikte
127
+ * silinir, taşınmaz (`isPristineSectionSeed`, ölçüldü 2026-09-18). Gateway taşısaydı Studio'da
128
+ * açılıp MCP ile kapatılan bölge gövdeye anlamsız bir "Header" metni bırakırdı (qa-box-01 bx_row).
129
+ */
130
+ function isPristineSeed(node, role) {
131
+ if (node.type !== 'text')
132
+ return false;
133
+ if (propData(node.props?.content) !== (role === 'footer' ? 'Footer' : 'Header'))
134
+ return false;
135
+ return [node.events, node.validations, node.stateBindings, node.children].every(list => asObjects(list).length === 0);
136
+ }
137
+ /**
138
+ * Kayıtlı kutuya `replace_prop hasHeader|hasFooter` yazılınca Studio'nun `syncBoxSections` adımını
139
+ * yamaya ekler: açılınca bölge düğümü `add_component`; kapanınca bölgenin çocukları gövdeye
140
+ * `move_component` ile taşınır ve bölge `remove_component` ile silinir — içerik sessizce silinmez.
141
+ * Eklenen op'lar tetikleyen `replace_prop`'un hemen arkasına yerleşir; `ops` yerinde değişir.
142
+ */
143
+ export function expandSectionToggles(ops, schema, taken) {
144
+ const result = { created: [], removed: [] };
145
+ for (let index = 0; index < ops.length; index++) {
146
+ const op = ops[index];
147
+ const role = SECTION_FLAGS[String(op.prop)];
148
+ if (op.op !== 'replace_prop' || !role || typeof op.target !== 'string')
149
+ continue;
150
+ const box = findNode(schema, op.target);
151
+ if (!box || !BOX_SECTION_HOSTS.has(String(box.type)))
152
+ continue;
153
+ const children = asObjects(box.children);
154
+ const existing = findSection(children, role);
155
+ const wanted = propData(op.value) === true;
156
+ const extra = [];
157
+ if (wanted && !existing) {
158
+ const section = boxSectionNode(op.target, role, taken);
159
+ extra.push({ op: 'add_component', parent: op.target, component: section });
160
+ result.created.push(String(section.elementId));
161
+ }
162
+ if (!wanted && existing) {
163
+ const targetY = orphanY(role, children.filter(child => !isSection(child)));
164
+ for (const orphan of asObjects(existing.children).filter(child => !isPristineSeed(child, role))) {
165
+ extra.push({ op: 'move_component', target: orphan.elementId, parent: op.target, position: { x: blockOf(orphan).x, y: targetY } });
166
+ }
167
+ extra.push({ op: 'remove_component', target: existing.elementId });
168
+ result.removed.push(String(existing.elementId));
169
+ }
170
+ ops.splice(index + 1, 0, ...extra);
171
+ index += extra.length;
172
+ }
173
+ return result;
174
+ }
175
+ export function boxSectionNote(created, removed = []) {
176
+ const notes = [];
177
+ if (created.length > 0) {
178
+ notes.push(`box bölgesi eklendi: ${created.join(', ')} — hasHeader/hasFooter bayrağı tek başına bölge çizmez, bölge ayrı bir box-section düğümüdür (Studio aynısını yapar). Bölgeye içerik eklemek için add_component parent: '<bu elementId>'`);
179
+ }
180
+ if (removed.length > 0) {
181
+ notes.push(`box bölgesi kaldırıldı: ${removed.join(', ')} — içindeki çocuklar kutunun gövdesine taşındı (silinmedi)`);
182
+ }
183
+ return notes;
184
+ }