@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,9 +1,7 @@
1
1
  import { logStep } from '../observability/trace.js';
2
2
  import { PlatformApiError } from '../platform/errors.js';
3
3
  import { ensureWorkflowErrorPath } from './errorPath.js';
4
- import { DOCUMENT_STYLE_TYPES, TYPED_STYLE_COMPONENTS } from './styleResolve.js';
5
- import { STATE_STORAGE_KINDS, STEP_ALIASES } from './platform/profile.js';
6
- import { inlineStyleFields } from './componentCatalog.js';
4
+ import { TYPED_STYLE_COMPONENTS } from './styleResolve.js';
7
5
  const SORT_DEFAULT = { name: 'sortField', type: 'sortType', source: 'query-string' };
8
6
  const LIMIT_DEFAULT = { name: 'limit', offset: 'offset', source: 'query-string' };
9
7
  function asArray(value) {
@@ -271,11 +269,12 @@ export function normalizeWorkflowDefinition(definition) {
271
269
  */
272
270
  /**
273
271
  * Adım tipi sözlüğü backend'in, KOŞAN tipler barındırıcının: motor yedi tip register eder, web
274
- * `Runtime.svelte` altı, mobil `runtime-tasks.ts` yedi tip ekler ve aynı sayfa kaydı ikisinde de
272
+ * `Runtime.svelte` altı, mobil `ScreenRuntime.tsx` beş tip ekler ve aynı sayfa kaydı ikisinde de
275
273
  * koşar. Register edilmemiş bir tipe gelen akış sessizce ölür (`flow-engine.ts` `process()`
276
274
  * callback bulamazsa next/completed/stopped hiç çağrılmaz), üstelik `run()` promise'i
277
275
  * çözülmediği için `__ngAppsFlowActivity.running` sıfıra inmez. İki hâl tamamen türetilebilir
278
- * olduğu için lint değil NORMALİZASYON; `FLOW-023` kalan hâlleri uyarır.
276
+ * olduğu için lint değil NORMALİZASYON — kalanı (`confirm`/`download` mobilde yok) yalnız
277
+ * uygulama tarafında kapanabilir, `FLOW-023` onları uyarır.
279
278
  */
280
279
  function normalizeFlowHostGaps(steps, list) {
281
280
  const fixes = [];
@@ -289,15 +288,12 @@ function normalizeFlowHostGaps(steps, list) {
289
288
  .map(step => String(step.stepId ?? ''))
290
289
  .filter(id => id.length > 0));
291
290
  for (const step of list) {
292
- // navigate ile redirect'in argümanı AYNI ({ path, pageId, query, targetBlank, presentation })
293
- // ama navigate'i yalnız mobil register eder; redirect ise iki barındırıcıda da koşar (mobilde
294
- // aynı navigate uygulamasına eşlenir), yani redirect kesin üstün. `presentation`
295
- // (push | modal | replace) yalnız mobil barındırıcıda okunur; web yok sayar.
296
- const alias = STEP_ALIASES[String(step.type ?? '')];
297
- if (alias) {
298
- const original = String(step.type);
299
- step.type = alias;
300
- fixes.push(`'${label(step)}': type ${original} → ${alias} yazıldı — argüman şekli aynı ({ path, pageId, query, targetBlank, presentation }) ama ${original}'i web barındırıcısı register etmez, ${alias} ikisinde de koşar`);
291
+ // navigate ile redirect'in argümanı AYNI ({ path, pageId, query, targetBlank }) ama navigate'i
292
+ // yalnız mobil register eder; redirect ise iki barındırıcıda da koşar (mobilde aynı navigate
293
+ // uygulamasına eşlenir), yani redirect kesin üstün.
294
+ if (step.type === 'navigate') {
295
+ step.type = 'redirect';
296
+ fixes.push(`'${label(step)}': type navigate → redirect yazıldı — argüman şekli aynı ({ path, pageId, query, targetBlank }) ama navigate'i web barındırıcısı register etmez, redirect ikisinde de koşar`);
301
297
  }
302
298
  if (endStepIds.size === 0)
303
299
  continue;
@@ -373,17 +369,9 @@ const REQUIRED_COLLECTIONS = ['events', 'validations', 'stateBindings', 'childre
373
369
  // PropValueType (DesignComponentProperty.cs:421) — 'translation' listeden düşünce çeviriye bağlı
374
370
  // prop'un KENDİSİ veri sanılıp static Prop'a sarılıyordu: istek 200 dönüyor, prop bozuk kuruluyordu
375
371
  // (09-04 Y-22). Enum burada eksiksiz tutulur.
376
- export const PROP_VALUE_TYPES = new Set(['static', 'file', 'flow', 'widget', 'element', 'page', 'code', 'translation', 'connectData']);
377
- // Prop'un TAŞIYICISI da aranır: `type` tek başına yetmez, çünkü liste öğesinin kendi `type` alanı
378
- // olabilir ve değeri Prop tipi adıyla çakışabilir — datatable kolonunda dosya alanı tam olarak
379
- // böyledir (`{ name, label, type: 'file', isFilterable }`). Yalnız `type`'a bakan sürüm o öğeyi
380
- // kurulu bir Prop sanıp sarmadan bırakıyordu ve platform 500 JsonException veriyordu (koşu
381
- // bulgusu S-2'nin gateway ayağı; Studio ayağı `staticFieldListItems` ile aynı kararı verdi).
372
+ export const PROP_VALUE_TYPES = new Set(['static', 'file', 'flow', 'widget', 'element', 'page', 'code', 'translation']);
382
373
  function isPropShaped(value) {
383
- if (!value || typeof value !== 'object' || Array.isArray(value))
384
- return false;
385
- const candidate = value;
386
- return PROP_VALUE_TYPES.has(String(candidate.type)) && ('data' in candidate || 'ref' in candidate);
374
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value) && PROP_VALUE_TYPES.has(String(value.type));
387
375
  }
388
376
  function wrapPropDictionaryValues(dictionary) {
389
377
  let wrapped = false;
@@ -626,16 +614,12 @@ export function codePropTemplateErrors(ops) {
626
614
  *
627
615
  * Seçici anahtarlara (`&__body`, `:hover`, `--token`) DOKUNULMAZ; yalnız `a-b` biçimli düz CSS
628
616
  * özellik adları camelCase'e çevrilir ve çevrim `gatewayNormalized` ile bildirilir.
629
- *
630
- * TB-129 — `inlineFields` verilirse o ÜST DÜZEY alanların altına hiç girilmez: `table.style.th`
631
- * gibi dallar satır içi `style` attribute'una basılır ve kebab-case zorunludur
632
- * (`INLINE_STYLE_FIELDS_BY_TYPE`). Çeviri orada stili öldürüyordu.
633
617
  */
634
618
  const styleKeyPattern = /^[a-z][a-z0-9]*(-[a-z0-9]+)+$/;
635
619
  export function isStylePropName(name) {
636
620
  return name === 'style' || /Style$/.test(name);
637
621
  }
638
- export function normalizeStyleKeys(value, label, fixed, inlineFields) {
622
+ export function normalizeStyleKeys(value, label, fixed) {
639
623
  if (Array.isArray(value)) {
640
624
  for (const entry of value)
641
625
  normalizeStyleKeys(entry, label, fixed);
@@ -644,10 +628,7 @@ export function normalizeStyleKeys(value, label, fixed, inlineFields) {
644
628
  if (!value || typeof value !== 'object')
645
629
  return;
646
630
  const record = value;
647
- const skipped = new Set(inlineFields ?? []);
648
631
  for (const key of Object.keys(record)) {
649
- if (skipped.has(key))
650
- continue;
651
632
  normalizeStyleKeys(record[key], label, fixed);
652
633
  if (!styleKeyPattern.test(key))
653
634
  continue;
@@ -669,44 +650,6 @@ export function styleKeyNote(fixed) {
669
650
  + 'değer kaydedilir ama hiç uygulanmaz ve tek işareti tarayıcı konsoludur (F-06). '
670
651
  + "Seçici anahtarlara ('&__body', ':hover', '--token') dokunulmadı."];
671
652
  }
672
- /**
673
- * Kabın `states.isDroppable`ı KATALOĞUN kararıdır. Gateway düğümü kurarken bu alanı
674
- * yazmıyordu (`DEFAULT_STATES` hepsini `false` bırakır) ve Studio kanvası düğümü kap saymıyordu:
675
- * imleç `scroll-view`un İÇİNDEYKEN bırakma planı sayfa kabına düşüyor, çizgi kabın üst kenarına
676
- * çiziliyordu (ölçüldü 2026-09-21, `test/mobile app` › `Satislar`). Aynı tipi paletten ekleyen
677
- * Studio katalog değerini yazdığı için tek şemada iki türlü davranan kap oluyordu.
678
- *
679
- * Değer uygulamanın KENDİ sözlüğünden gelir (`listComponents`; mobil uygulamada `type=mobile`
680
- * satırları), yani kural platformdan bağımsızdır ve kuruluşun kendi komponentlerini de kapsar.
681
- * Yalnız `true` yazılır: katalog bir tipi kap saymıyorsa düğüme dokunulmaz.
682
- */
683
- export function normalizeDroppableStates(nodes, droppable) {
684
- const fixed = [];
685
- if (droppable.size === 0)
686
- return fixed;
687
- for (const node of asObjects(nodes)) {
688
- const type = typeof node.type === 'string' ? node.type : '';
689
- if (droppable.get(type) === true) {
690
- // `states` normalde `normalizeComponentDefaults`tan geçmiş olur; gelmediyse burada da
691
- // eksiksiz kurulur — yarım `states` platformda NullReference üretir.
692
- if (!node.states || typeof node.states !== 'object' || Array.isArray(node.states)) {
693
- node.states = { ...DEFAULT_STATES };
694
- }
695
- const states = node.states;
696
- if (states.isDroppable !== true) {
697
- states.isDroppable = true;
698
- fixed.push(`'${String(node.elementId ?? node.name ?? type)}' (${type})`);
699
- }
700
- }
701
- fixed.push(...normalizeDroppableStates(node.children, droppable));
702
- }
703
- return fixed;
704
- }
705
- export function droppableStatesNote(fixed) {
706
- return fixed.length === 0
707
- ? []
708
- : [`states.isDroppable katalogdan yazıldı (${fixed.join(' · ')}) — kataloğun kap saydığı düğüm Studio kanvasında da kap olmalı; alanı bilerek kapatmak için resize_component/set_states kullanın`];
709
- }
710
653
  export function normalizeComponentDefaults(nodes) {
711
654
  const fixed = [];
712
655
  for (const node of asObjects(nodes)) {
@@ -746,10 +689,8 @@ export function normalizeComponentDefaults(nodes) {
746
689
  if (node.props && typeof node.props === 'object' && !Array.isArray(node.props)) {
747
690
  const props = node.props;
748
691
  const styleKeys = [];
749
- // Satır içi stil dalları komponent TİPİNE göre atlanır; tip bilinmiyorsa eski davranış.
750
- const inlineFields = (name) => name === 'style' ? inlineStyleFields(typeof node.type === 'string' ? node.type : undefined) : undefined;
751
692
  for (const name of Object.keys(props).filter(isStylePropName)) {
752
- normalizeStyleKeys(props[name], `${String(node.elementId ?? node.name ?? '?')}.${name}`, styleKeys, inlineFields(name));
693
+ normalizeStyleKeys(props[name], `${String(node.elementId ?? node.name ?? '?')}.${name}`, styleKeys);
753
694
  }
754
695
  if (styleKeys.length > 0)
755
696
  missing.push(`stil anahtarları camelCase'e çevrildi: ${styleKeys.join(' · ')}`);
@@ -854,31 +795,19 @@ function normalizeReplacePropValue(op) {
854
795
  }
855
796
  return notes;
856
797
  }
857
- // connectData sarmalı burada değiştirilmez: gövde duvarı (CD-005, `connectDataOpIssues`) op'u
858
- // set_connect_data'ya yönlendirerek rejectedOps'a yazar; burada atmak listeyi tek hataya indirirdi.
859
- if (propType === 'connectData')
860
- return notes;
861
798
  // Applier her sarmalın tipini korur, ama page/file/flow/widget/element taşıyıcıları başka alanlara
862
799
  // (FlowId, RedirectPageId, dosya) yazılır ve bu op'la bağları kurulmaz. Remove+add önerilmez:
863
800
  // düğümü yeniden kurmak ona yazan setter iteratee'lerinin element'ini siler (G-04, FLOW-018).
864
801
  throw new PlatformApiError(`${label}: '${propType}' tipli Prop replace_prop ile kurulmaz — bu op static, code ve translation sarmalını taşır. Komponenti silip yeniden EKLEMEYİN: ona yazan setter adımlarının hedefi silinir (FLOW-018). Akış bağı için set_event, diğer tipler için page_update(schema) ile tam şema yazın.`, 400);
865
802
  }
866
- /**
867
- * `typesByElementId` — TB-129: `replace_prop` op'u yalnız elementId taşır, stil çevirisinin
868
- * komponent tipine bakabilmesi için haritayı çağıran (okuduğu şemadan) verir. Verilmezse çeviri
869
- * tip ayrımı yapmaz; bu, harita okunamadığında yazmayı engellememek için bilinçli düşüştür.
870
- */
871
- export function normalizeSchemaOps(ops, typesByElementId) {
803
+ export function normalizeSchemaOps(ops) {
872
804
  const components = [];
873
805
  const props = [];
874
806
  const validations = [];
875
807
  for (const op of asObjects(ops)) {
876
808
  if (op.op === 'replace_prop') {
877
809
  if (isStylePropName(String(op.prop ?? ''))) {
878
- const inline = String(op.prop) === 'style'
879
- ? inlineStyleFields(typesByElementId?.get(String(op.target ?? '')))
880
- : undefined;
881
- normalizeStyleKeys(op.value, `'${String(op.target ?? '?')}.${String(op.prop)}'`, props, inline);
810
+ normalizeStyleKeys(op.value, `'${String(op.target ?? '?')}.${String(op.prop)}'`, props);
882
811
  }
883
812
  props.push(...normalizeReplacePropValue(op));
884
813
  continue;
@@ -955,11 +884,11 @@ export function pageContainerNode() {
955
884
  * çekilirlerse sayfa içeriğinin akışına girer ve katman olarak açılmazlar.
956
885
  */
957
886
  const ROOT_LAYER_TYPES = new Set(['modal', 'drawer']);
958
- export function ensurePageContainer(schema, rootContainer = pageContainerNode) {
887
+ export function ensurePageContainer(schema) {
959
888
  const nodes = asObjects(schema);
960
889
  if (nodes.some(node => node.elementId === PAGE_CONTAINER_ELEMENT_ID))
961
890
  return { schema: nodes, fixes: [] };
962
- const container = rootContainer();
891
+ const container = pageContainerNode();
963
892
  const layers = nodes.filter(node => ROOT_LAYER_TYPES.has(String(node.type ?? '')));
964
893
  container.children = nodes.filter(node => !ROOT_LAYER_TYPES.has(String(node.type ?? '')));
965
894
  const moved = container.children.length;
@@ -1002,7 +931,7 @@ export function clampBlockSizes(nodes, maxSizes) {
1002
931
  * başlatır (`ComponentHeightType.Fixed = 0`), yani "alan yok" = "sabit yükseklik". Studio'nun
1003
932
  * kendi bırakma yolu bunu ASLA yapmaz: katalogdaki `isDefaultAutoHeight`e bakıp
1004
933
  * `heightType: isDefaultAutoHeight ? 'auto' : 'fixed'` yazar
1005
- * (`ScreenBuilderDroppable.svelte:701`, `store-converter.ts` `createDefaultSchemaNode`). Katalogda varsayılan
934
+ * (`ScreenBuilderDroppable.svelte:701`, `store-converter.ts:233`). Katalogda varsayılan
1006
935
  * `true`'dur (`ZeyrekComponent.ts:62`); `false` diyen yalnız sekiz tip var — auth-layout, html,
1007
936
  * image, layout, qrcode, table, text-editor, video.
1008
937
  *
@@ -1788,18 +1717,19 @@ export function viewAliasNote(fixes) {
1788
1717
  return [`view alanlarının entity bağı id'den alias'a çevrildi (${fixes.join(', ')}): yazma tarafı viewEntityAlias ister, okuma tarafı viewEntityId döndürür — alias boş kalsa platform tüm alanları ilk tabloya düşürürdü`];
1789
1718
  }
1790
1719
  /**
1791
- * `storage` kayıtta isteğe bağlıdır (`docs/adr/0004-state-saklama-turu.md`). Tanınmayan tür ya da
1792
- * metin olmayan değer çalışma zamanında da yok sayılır (`@ng-apps/ui-native` `variableStorageKinds`);
1793
- * gateway onu taşımaz ki bir sonraki yazım bozuk değeri kalıcılaştırmasın.
1720
+ * Değişken seti tek bir kayıtta yaşar: `CreateAppVariableCommand`/`CreatePageVariableCommand`
1721
+ * yalnız `Data` alanı taşır (Studio uygulama başına ve sayfa başına TEK satır tutar —
1722
+ * `IsVariableExistForApplicationAsync` doluysa create update'e döner). Studio'nun gönderdiği şekil
1723
+ * `data`'nın **JSON string** olmasıdır: "[{\"key\":\"MyTest\",\"value\":{\"isActive\":true}}]".
1724
+ * `Data` tipi `object` olduğu için platform her gövdeyi kabul eder; alan adı tutmayan bir gövde
1725
+ * (name/type/defaultValue gibi) `Data`'yı null bırakır ve istek 200 döner ama HİÇBİR ŞEY yazılmaz
1726
+ * (17/Ç1). Okuma tarafı da aynı string'i geri verir (`AppVariablesDto.Map` → GetRawText).
1794
1727
  */
1795
1728
  export function parseVariableEntries(data) {
1796
1729
  const source = typeof data === 'string' ? safeParse(data) : data;
1797
1730
  return asObjects(source)
1798
1731
  .filter(entry => typeof entry.key === 'string' && entry.key !== '')
1799
- .map(entry => {
1800
- const storage = STATE_STORAGE_KINDS.find(kind => kind === entry.storage);
1801
- return { key: String(entry.key), value: entry.value, ...(storage ? { storage } : {}) };
1802
- });
1732
+ .map(entry => ({ key: String(entry.key), value: entry.value }));
1803
1733
  }
1804
1734
  function safeParse(value) {
1805
1735
  try {
@@ -1814,29 +1744,17 @@ function safeParse(value) {
1814
1744
  * mevcut seti okuyup anahtar bazında birleştirir; `replace: true` verilirse bilinçli olarak ezer.
1815
1745
  */
1816
1746
  export function mergeVariableEntries(existing, incoming, replace) {
1817
- const stored = (entry, current) => {
1818
- const storage = entry.storage === undefined ? current?.storage : STATE_STORAGE_KINDS.find(kind => kind === entry.storage);
1819
- const value = entry.value === undefined ? (current ? current.value : null) : entry.value;
1820
- return { key: entry.key, value, ...(storage ? { storage } : {}) };
1821
- };
1822
1747
  if (replace)
1823
- return { entries: incoming.map(entry => stored(entry)), fixes: [] };
1748
+ return { entries: incoming, fixes: [] };
1824
1749
  const merged = [...existing];
1825
1750
  const kept = [];
1826
- const keptStorage = [];
1827
- const keptValue = [];
1828
1751
  for (const entry of incoming) {
1829
1752
  const index = merged.findIndex(current => current.key === entry.key);
1830
1753
  if (index === -1) {
1831
- merged.push(stored(entry));
1754
+ merged.push(entry);
1832
1755
  continue;
1833
1756
  }
1834
- const current = merged[index];
1835
- if (entry.storage === undefined && current?.storage)
1836
- keptStorage.push(`'${entry.key}' → ${current.storage}`);
1837
- if (entry.value === undefined)
1838
- keptValue.push(`'${entry.key}'`);
1839
- merged[index] = stored(entry, current);
1757
+ merged[index] = entry;
1840
1758
  }
1841
1759
  for (const entry of existing) {
1842
1760
  if (!incoming.some(current => current.key === entry.key))
@@ -1844,17 +1762,9 @@ export function mergeVariableEntries(existing, incoming, replace) {
1844
1762
  }
1845
1763
  return {
1846
1764
  entries: merged,
1847
- fixes: [
1848
- ...(kept.length > 0
1849
- ? [`mevcut değişkenler korundu (${kept.join(', ')}): uç seti komple değiştirir, gateway anahtar bazında birleştirdi — kasten silmek için replace: true verin`]
1850
- : []),
1851
- ...(keptStorage.length > 0
1852
- ? [`saklama türü korundu (${keptStorage.join(', ')}): gelen değişken storage taşımıyordu, kayıttaki tür silinmedi — belleğe çevirmek için storage: 'memory' verin`]
1853
- : []),
1854
- ...(keptValue.length > 0
1855
- ? [`değer korundu (${keptValue.join(', ')}): gelen değişken value taşımıyordu, kayıttaki değer silinmedi — boşaltmak için value: null verin`]
1856
- : [])
1857
- ]
1765
+ fixes: kept.length > 0
1766
+ ? [`mevcut değişkenler korundu (${kept.join(', ')}): uç seti komple değiştirir, gateway anahtar bazında birleştirdi — kasten silmek için replace: true verin`]
1767
+ : []
1858
1768
  };
1859
1769
  }
1860
1770
  export function blockSizeNote(clamped) {
@@ -1935,22 +1845,12 @@ export function nestedRepeaterNodes(nodes) {
1935
1845
  walk(asObjects(nodes), false);
1936
1846
  return found;
1937
1847
  }
1938
- /**
1939
- * Mobil profilde gruplu listenin (gün/kategori başlığı altında satırlar) hazır bileşeni vardır:
1940
- * `grouped-list` (ui-native, ADR 0007). Web'de karşılığı yok — web mesajı textarea tarifinde kalır.
1941
- */
1942
- export function nestedRepeaterMessage(ids, platform = 'web') {
1943
- const measured = `PAGE-013 — repeater içinde repeater (istek gönderilmedi): ${ids.join(' · ')}. `
1848
+ export function nestedRepeaterMessage(ids) {
1849
+ return `PAGE-013 — repeater içinde repeater (istek gönderilmedi): ${ids.join(' · ')}. `
1944
1850
  + 'Ölçüldü (2026-08-19): iç repeater OKUMADA çalışır ama girilen değer dış satıra GERİ YAZILMAZ '
1945
1851
  + '(_repeaterValues null kalır) ve tek düzenlemeden sonra DOM bozulur. Sebep yapısal: şemada iç '
1946
- + 'repeater tek düğümdür, dış satır başına ayrı düğüm yoktur. ';
1947
- const textarea = "Satır içi listeyi tek bir textarea ile topla (satır başına bir öğe) ve kaydederken split('\n') ile böl — platform_guide('page') Kural 1g.";
1948
- if (platform !== 'mobile')
1949
- return measured + textarea;
1950
- return measured
1951
- + 'Başlıklar altında gruplanmış liste (güne/kategoriye göre) için mobilde tek `grouped-list` kur: düz `rows` + '
1952
- + '`groupBy` alan yolu; çocuk 0 bölüm başlığı (`{{ Section.title }}`), çocuk 1 öğe şablonu (`Row`, `{{ item.<alan> }}`) — '
1953
- + "platform_guide('mobile') §Güne göre görev listesi. Satır içinde düzenlenen alt liste gerekiyorsa: " + textarea;
1852
+ + 'repeater tek düğümdür, dış satır başına ayrı düğüm yoktur. Satır içi listeyi tek bir textarea '
1853
+ + "ile topla (satır başına bir öğe) ve kaydederken split('\n') ile böl — platform_guide('page') Kural 1g.";
1954
1854
  }
1955
1855
  /**
1956
1856
  * `style` prop'u düz CSS STRING verilmiş düğümler. Çalışır (emotion string'i CSS metni sayar) ama
@@ -1964,7 +1864,7 @@ export function stringStyleNodes(nodes) {
1964
1864
  for (const node of list) {
1965
1865
  const props = (node.props ?? {});
1966
1866
  const style = props.style;
1967
- if (style && typeof style.data === 'string' && style.data.includes(':') && !DOCUMENT_STYLE_TYPES.has(String(node.type))) {
1867
+ if (style && typeof style.data === 'string' && style.data.includes(':')) {
1968
1868
  found.push(String(node.elementId ?? node.name ?? '?'));
1969
1869
  }
1970
1870
  walk(asObjects(node.children));
@@ -2095,95 +1995,6 @@ export function flowBindings(schema, hostEvents) {
2095
1995
  visitNode(node);
2096
1996
  return bindings;
2097
1997
  }
2098
- /**
2099
- * TB-125 — op listesi UYGULANDIKTAN sonra şemada (ve düzey olaylarında) hâlâ referanslı olan
2100
- * akışlar. Simülasyon yalnız akış referansını umursar: eklenen düğüm ağacın köküne konur (konum
2101
- * sayıma girmez), silinen düğüm ağaçtan çıkarılır, olay op'ları olay dizisini günceller.
2102
- * `batch` op'u iç listesiyle düzleştirilir.
2103
- */
2104
- function survivingFlowRefs(nodes, hostEvents, ops) {
2105
- const simulated = structuredClone(nodes);
2106
- const simulatedHostEvents = structuredClone(hostEvents);
2107
- const removeNode = (list, target) => {
2108
- const index = list.findIndex(node => node.elementId === target);
2109
- if (index >= 0) {
2110
- list.splice(index, 1);
2111
- return true;
2112
- }
2113
- for (const node of list) {
2114
- if (Array.isArray(node.children) && removeNode(node.children, target))
2115
- return true;
2116
- }
2117
- return false;
2118
- };
2119
- const eventsOf = (target) => {
2120
- if (target === 'page')
2121
- return simulatedHostEvents;
2122
- const node = findNodeByElementId(simulated, target);
2123
- if (!node)
2124
- return undefined;
2125
- if (!Array.isArray(node.events))
2126
- node.events = [];
2127
- return node.events;
2128
- };
2129
- const apply = (op) => {
2130
- if (op.op === 'batch') {
2131
- for (const inner of asObjects(op.ops))
2132
- apply(inner);
2133
- return;
2134
- }
2135
- if (op.op === 'add_component' && op.component && typeof op.component === 'object') {
2136
- simulated.push(structuredClone(op.component));
2137
- return;
2138
- }
2139
- const target = String(op.target ?? '');
2140
- if (target === '')
2141
- return;
2142
- if (op.op === 'remove_component') {
2143
- removeNode(simulated, target);
2144
- return;
2145
- }
2146
- if (op.op !== 'set_event' && op.op !== 'add_event' && op.op !== 'remove_event')
2147
- return;
2148
- const events = eventsOf(target);
2149
- if (events === undefined)
2150
- return;
2151
- const eventName = String(op.event ?? '');
2152
- const eventValue = typeof op.eventValue === 'string' ? op.eventValue : undefined;
2153
- const named = events.filter(event => String(event.name ?? '') === eventName && typeof event.value === 'string' && event.value !== '');
2154
- if (op.op === 'add_event') {
2155
- if (eventValue !== undefined)
2156
- events.push({ name: eventName, value: eventValue });
2157
- return;
2158
- }
2159
- if (op.op === 'set_event') {
2160
- // set_event adın BÜTÜN bağlarını tek kayda indirir.
2161
- for (const event of named)
2162
- events.splice(events.indexOf(event), 1);
2163
- if (eventValue !== undefined)
2164
- events.push({ name: eventName, value: eventValue });
2165
- return;
2166
- }
2167
- // Değersiz remove_event çoklu bağda platformda ambiguous-event ile düşer: hiçbir bağ kalkmaz.
2168
- const removed = eventValue === undefined
2169
- ? (named.length === 1 ? named : [])
2170
- : named.filter(event => event.value === eventValue);
2171
- for (const event of removed)
2172
- events.splice(events.indexOf(event), 1);
2173
- };
2174
- for (const op of ops)
2175
- apply(op);
2176
- const surviving = new Set();
2177
- for (const event of simulatedHostEvents) {
2178
- if (typeof event.value === 'string')
2179
- surviving.add(event.value);
2180
- }
2181
- for (const node of simulated) {
2182
- for (const flowId of collectFlowRefs(node))
2183
- surviving.add(flowId);
2184
- }
2185
- return surviving;
2186
- }
2187
1998
  /**
2188
1999
  * Bir yamanın SİLECEĞİ akışlar. Platform referanssız kalan akışı KALICI siler; uyarı yamadan sonra
2189
2000
  * geldiğinde "önce yedekle" tavsiyesi uygulanamaz hâle geliyordu (09-05 koşusu: sekiz adımlı giriş
@@ -2192,15 +2003,26 @@ function survivingFlowRefs(nodes, hostEvents, ops) {
2192
2003
  */
2193
2004
  export function orphanedFlowPlan(schema, pageEvents, ops) {
2194
2005
  const nodes = asObjects(schema);
2195
- // `batch` açılır: içindeki silme de plana girer (kapı yalnız üst düzeye bakınca batch'teki
2196
- // `remove_component` akışı uyarısız siliyordu).
2197
- const opList = asObjects(ops).flatMap(op => op.op === 'batch' ? asObjects(op.ops) : [op]);
2006
+ const opList = asObjects(ops);
2198
2007
  const plan = [];
2199
- // TB-125 — hayatta kalan referanslar yamanın SONUCUNDAN okunur, op op özgün ağaçtan değil. Eski
2200
- // hesap her op'a tek başına baktığı için aynı yamada başka bir düğüme bağlanan akışı da
2201
- // "referanssız" sayıyor ve düğüm taşıyan her yamayı ikiye böldürüyordu (S2-35). İstek atomik
2202
- // olduğuna göre doğru soru tektir: yama bittiğinde bu akışa referans kalıyor mu?
2203
- const surviving = survivingFlowRefs(nodes, asObjects(pageEvents), opList);
2008
+ const survivingRefs = (skipElementId, skipEvent) => {
2009
+ const surviving = new Set();
2010
+ for (const event of asObjects(pageEvents)) {
2011
+ if (typeof event.value === 'string')
2012
+ surviving.add(event.value);
2013
+ }
2014
+ collectFlowRefsExcept(nodes, skipElementId, surviving);
2015
+ if (skipEvent !== undefined) {
2016
+ const node = findNodeByElementId(nodes, skipElementId);
2017
+ for (const event of asObjects(node?.events)) {
2018
+ if (String(event.name ?? '') !== skipEvent && typeof event.value === 'string')
2019
+ surviving.add(event.value);
2020
+ }
2021
+ for (const flowId of collectFlowRefs({ ...(node ?? {}), events: [] }))
2022
+ surviving.add(flowId);
2023
+ }
2024
+ return surviving;
2025
+ };
2204
2026
  for (const op of opList) {
2205
2027
  const target = String(op.target ?? '');
2206
2028
  if (target === '')
@@ -2210,6 +2032,7 @@ export function orphanedFlowPlan(schema, pageEvents, ops) {
2210
2032
  if (!doomed)
2211
2033
  continue;
2212
2034
  const losing = collectFlowRefs(doomed);
2035
+ const surviving = survivingRefs(target);
2213
2036
  const orphaned = [...losing].filter(flowId => !surviving.has(flowId));
2214
2037
  if (orphaned.length > 0)
2215
2038
  plan.push({ target, op: 'remove_component', flowIds: orphaned });
@@ -2231,7 +2054,10 @@ export function orphanedFlowPlan(schema, pageEvents, ops) {
2231
2054
  // oraya bağlı akış kapıdan geçip kalıcı silinirdi. Düzey olayı olmayan widget'ta applier da
2232
2055
  // düğüm aramasına düşer.
2233
2056
  if (op.op === 'remove_event' && target === 'page' && Array.isArray(pageEvents)) {
2234
- const removed = removedBy(boundTo(asObjects(pageEvents)));
2057
+ const hostEvents = asObjects(pageEvents);
2058
+ const removed = removedBy(boundTo(hostEvents));
2059
+ const surviving = new Set(hostEvents.filter(event => !removed.includes(event) && typeof event.value === 'string').map(event => String(event.value)));
2060
+ collectFlowRefsExcept(nodes, '', surviving);
2235
2061
  const flowIds = [...new Set(removed.map(event => String(event.value)))].filter(flowId => !surviving.has(flowId));
2236
2062
  if (flowIds.length > 0)
2237
2063
  plan.push({ target, op: 'remove_event', flowIds });
@@ -2243,6 +2069,11 @@ export function orphanedFlowPlan(schema, pageEvents, ops) {
2243
2069
  const losing = op.op === 'set_event' ? named.filter(event => event.value !== eventValue) : removedBy(named);
2244
2070
  if (losing.length === 0)
2245
2071
  continue;
2072
+ const surviving = survivingRefs(target, eventName);
2073
+ for (const event of named) {
2074
+ if (!losing.includes(event))
2075
+ surviving.add(String(event.value));
2076
+ }
2246
2077
  const flowIds = [...new Set(losing.map(event => String(event.value)))].filter(flowId => !surviving.has(flowId));
2247
2078
  if (flowIds.length > 0)
2248
2079
  plan.push({ target, op: String(op.op), flowIds });
@@ -357,39 +357,3 @@ export function functionOutline(definition) {
357
357
  view: 'outline'
358
358
  };
359
359
  }
360
- export function processOutline(payload) {
361
- const model = (payload.definition && typeof payload.definition === 'object' ? payload.definition : payload);
362
- const describeAssignee = (value) => {
363
- if (!value || typeof value !== 'object' || Array.isArray(value))
364
- return value ?? null;
365
- const assignee = value;
366
- const rule = [assignee.rule, assignee.arg].filter(part => part !== undefined && part !== null).join(':');
367
- return assignee.of ? `${rule} of ${String(assignee.of)}` : rule;
368
- };
369
- const describeNodes = (nodes, depth) => asArray(nodes).flatMap(node => [{
370
- id: node.id,
371
- type: node.type,
372
- depth,
373
- editable: node.editable ?? 'locked',
374
- description: node.description ?? null,
375
- assignee: describeAssignee(node.assignee ?? node.to),
376
- policy: node.policy ?? null,
377
- sla: Array.isArray(node.sla) ? asArray(node.sla).map(sla => sla.duration) : node.sla ?? null,
378
- on: asArray(node.on).map(handler => `${String(handler.event)} → ${String(handler.handler?.type ?? '?')}${handler.afterHandlers ? ` (${String(handler.afterHandlers)})` : ''}`)
379
- }, ...describeNodes(node.nodes, depth + 1)]);
380
- const nodes = describeNodes(model.nodes, 0);
381
- return {
382
- id: payload.id ?? null,
383
- slug: model.slug ?? payload.slug,
384
- name: model.name ?? payload.name,
385
- version: payload.version ?? null,
386
- activeVersionId: payload.activeVersionId ?? null,
387
- versions: asArray(payload.versions).map(version => ({ number: version.number, state: version.state })),
388
- nodeCount: nodes.length,
389
- nodes,
390
- edgeCount: asArray(model.edges).length,
391
- on: asArray(model.on).map(handler => String(handler.event)),
392
- view: 'outline',
393
- hint: "Tek düğüm için process_definition_get view:'part', part:'definition.nodes[id=<düğüm>]'; değişiklik için process_definition_patch (yol /nodes[id=<düğüm>]/…)."
394
- };
395
- }
@@ -1,27 +1,13 @@
1
1
  import { logStep } from '../observability/trace.js';
2
2
  export class PolicyBlockError extends Error {
3
3
  findings;
4
- canOverride;
5
- /**
6
- * `canOverride` kaçış cümlesini seçer. Her tool `policyOverride` girdisini
7
- * TAŞIMAZ (row_*, datasource_*, folder_*, project_*, translation_*,
8
- * external_component_*): oralarda "aynı çağrıyı policyOverride ile
9
- * tekrarlayın" demek olmayan bir alana yönlendirmekti ve çağıran aynı
10
- * isteği ikinci kez gönderip aynı duvara çarpıyordu (S-12, 2026-09-19).
11
- * Girdiyi taşıyan tool'larda da mutlak kapılar vardır (BPM-001/014/018
12
- * ortam ve imza kapıları): orada da bu dal seçilir, o yüzden cümle "bu
13
- * çağrı" der.
14
- */
15
- constructor(findings, canOverride = true) {
4
+ constructor(findings) {
16
5
  super([
17
6
  'Politika kontrolü isteği durdurdu (istek platforma gönderilmedi):',
18
7
  ...findings.map(finding => `- [${finding.ruleId}] ${finding.message}${finding.guide ? ` (rehber: ${finding.guide})` : ''}`),
19
- canOverride
20
- ? "Bilinçli bir istisnaysa aynı çağrıyı policyOverride: true ile tekrarlayın; kural yanlışsa zeyrek-mcp/docs/08-kural-envanteri.md'ye işleyin."
21
- : "Bu çağrı policyOverride kabul etmez: çağrıyı kuralı sağlayacak biçimde değiştirin; kural yanlışsa zeyrek-mcp/docs/08-kural-envanteri.md'ye işleyin."
8
+ "Bilinçli bir istisnaysa aynı çağrıyı policyOverride: true ile tekrarlayın; kural yanlışsa zeyrek-mcp/docs/08-kural-envanteri.md'ye işleyin."
22
9
  ].join('\n'));
23
10
  this.findings = findings;
24
- this.canOverride = canOverride;
25
11
  this.name = 'PolicyBlockError';
26
12
  }
27
13
  }
@@ -49,11 +35,11 @@ export function evaluatePolicy(config, rules, module, definition, context, polic
49
35
  logStep('politika', `${module}/${context.operation}${context.workflowKind ? ` (${context.workflowKind})` : ''} · ${applicable.length} kural denendi · ${findings.length === 0 ? 'bulgu yok' : `${findings.length} bulgu`}${policyOverride ? ' · policyOverride açık' : ''}`, findings.map(finding => `[${finding.ruleId}] ${finding.severity}: ${finding.message}`));
50
36
  return findings;
51
37
  }
52
- export function enforcePolicy(findings, canOverride = true) {
38
+ export function enforcePolicy(findings) {
53
39
  const blocking = findings.filter(finding => finding.severity === 'block');
54
40
  if (blocking.length > 0) {
55
41
  logStep('politika ✕', `${blocking.length} block bulgusu isteği durdurdu — platforma HİÇBİR istek gitmedi`, blocking.map(finding => `[${finding.ruleId}] ${finding.message}`));
56
- throw new PolicyBlockError(blocking, canOverride);
42
+ throw new PolicyBlockError(blocking);
57
43
  }
58
44
  return findings;
59
45
  }