@appaflytech/zeyrek-ai-mcp 0.0.31 → 0.0.33

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 (91) hide show
  1. package/README.md +5 -5
  2. package/dist/config.js +0 -26
  3. package/dist/knowledge/backendConstraints.js +1 -18
  4. package/dist/knowledge/componentCatalog.js +27 -493
  5. package/dist/knowledge/componentEvents.js +2 -120
  6. package/dist/knowledge/connectDataDefinition.js +4 -4
  7. package/dist/knowledge/connectDataRules.js +1 -1
  8. package/dist/knowledge/mobileComponentCatalog.js +13 -8
  9. package/dist/knowledge/mobileStore.js +227 -0
  10. package/dist/knowledge/normalize.js +48 -131
  11. package/dist/knowledge/outlines.js +0 -36
  12. package/dist/knowledge/platform/lint.js +1 -1
  13. package/dist/knowledge/platform/nativeBoxModel.js +1 -1
  14. package/dist/knowledge/policy.js +4 -18
  15. package/dist/knowledge/process.js +1 -1
  16. package/dist/knowledge/reservedTables.js +0 -79
  17. package/dist/knowledge/rules.js +10 -83
  18. package/dist/knowledge/schemaGuard.js +0 -11
  19. package/dist/observability/trace.js +2 -5
  20. package/dist/platform/capture/capture.js +1 -25
  21. package/dist/platform/errors.js +10 -162
  22. package/dist/platform/http.js +1 -6
  23. package/dist/platform/responses.js +4 -34
  24. package/dist/platform/schemaReadMemory.js +2 -2
  25. package/dist/platform/secrets.js +1 -8
  26. package/dist/resources/examples/middleware-authenticate.json +1 -1
  27. package/dist/resources/examples/mobile-app-shell-drawer.json +62 -61
  28. package/dist/resources/examples/mobile-list-detail-form.json +51 -20
  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-html-embed.json +1 -1
  32. package/dist/resources/examples/workflow-basic.json +2 -8
  33. package/dist/resources/guides/access.md +4 -18
  34. package/dist/resources/guides/bpm.md +1 -6
  35. package/dist/resources/guides/component.md +4 -83
  36. package/dist/resources/guides/entity.md +8 -50
  37. package/dist/resources/guides/getting-started.md +1 -38
  38. package/dist/resources/guides/merge.md +3 -37
  39. package/dist/resources/guides/microservice.md +0 -78
  40. package/dist/resources/guides/middleware.md +3 -35
  41. package/dist/resources/guides/mobile.md +85 -2
  42. package/dist/resources/guides/page.md +26 -278
  43. package/dist/resources/guides/workflow.md +0 -51
  44. package/dist/resources/rules.js +5 -11
  45. package/dist/resources/schema-fingerprint.json +5 -7
  46. package/dist/resources/schemas/CreateEntityCommand.json +0 -118
  47. package/dist/resources/schemas/CreateMicroserviceCommand.json +1 -13
  48. package/dist/resources/schemas/CreateQueryCommand.json +0 -4
  49. package/dist/resources/schemas/CreateWorkflowCommand.json +1 -146
  50. package/dist/resources/schemas/DataJobDto.json +1 -6
  51. package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +2 -20
  52. package/dist/resources/schemas/MicroserviceDto.json +1 -13
  53. package/dist/resources/schemas/PreviewMicroserviceCommand.json +1 -10
  54. package/dist/resources/schemas/PreviewWorkflowCommand.json +1 -25
  55. package/dist/resources/schemas/StartMobileBuildCommand.json +54 -0
  56. package/dist/resources/schemas/StepDto.json +1 -25
  57. package/dist/resources/schemas/UpdateEntityCommand.json +0 -118
  58. package/dist/resources/schemas/UpdateMicroserviceCommand.json +1 -13
  59. package/dist/resources/schemas/UpdateQueryCommand.json +0 -4
  60. package/dist/resources/schemas/UpdateViewCommand.json +2 -0
  61. package/dist/resources/schemas/UpdateWorkflowCommand.json +1 -146
  62. package/dist/resources/schemas/UpsertMobileStoreSettingsCommand.json +259 -0
  63. package/dist/server.js +5 -25
  64. package/dist/tools/access.js +2 -369
  65. package/dist/tools/common.js +0 -7
  66. package/dist/tools/components.js +2 -15
  67. package/dist/tools/datasources.js +2 -2
  68. package/dist/tools/dependencies.js +1 -1
  69. package/dist/tools/deployments.js +3 -38
  70. package/dist/tools/designSchemaPatch.js +3 -13
  71. package/dist/tools/dtos.js +5 -36
  72. package/dist/tools/entities.js +12 -79
  73. package/dist/tools/externalComponents.js +1 -1
  74. package/dist/tools/flows.js +10 -45
  75. package/dist/tools/folders.js +1 -1
  76. package/dist/tools/imports.js +2 -5
  77. package/dist/tools/layouts.js +5 -6
  78. package/dist/tools/merges.js +2 -2
  79. package/dist/tools/microservices.js +20 -50
  80. package/dist/tools/mobileStore.js +268 -0
  81. package/dist/tools/pages.js +35 -89
  82. package/dist/tools/platformInfo.js +6 -20
  83. package/dist/tools/projects.js +9 -71
  84. package/dist/tools/rows.js +12 -62
  85. package/dist/tools/schemaOps.js +1 -29
  86. package/dist/tools/screenWrite.js +1 -22
  87. package/dist/tools/screens.js +3 -6
  88. package/dist/tools/templates.js +1 -26
  89. package/dist/tools/translations.js +1 -1
  90. package/dist/tools/workflows.js +5 -10
  91. package/package.json +2 -2
@@ -3,7 +3,6 @@ import { PlatformApiError } from '../platform/errors.js';
3
3
  import { ensureWorkflowErrorPath } from './errorPath.js';
4
4
  import { DOCUMENT_STYLE_TYPES, TYPED_STYLE_COMPONENTS } from './styleResolve.js';
5
5
  import { STATE_STORAGE_KINDS, STEP_ALIASES } from './platform/profile.js';
6
- import { inlineStyleFields } from './componentCatalog.js';
7
6
  const SORT_DEFAULT = { name: 'sortField', type: 'sortType', source: 'query-string' };
8
7
  const LIMIT_DEFAULT = { name: 'limit', offset: 'offset', source: 'query-string' };
9
8
  function asArray(value) {
@@ -373,17 +372,9 @@ const REQUIRED_COLLECTIONS = ['events', 'validations', 'stateBindings', 'childre
373
372
  // PropValueType (DesignComponentProperty.cs:421) — 'translation' listeden düşünce çeviriye bağlı
374
373
  // prop'un KENDİSİ veri sanılıp static Prop'a sarılıyordu: istek 200 dönüyor, prop bozuk kuruluyordu
375
374
  // (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).
375
+ export const PROP_VALUE_TYPES = new Set(['static', 'file', 'flow', 'widget', 'element', 'page', 'code', 'translation']);
382
376
  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);
377
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value) && PROP_VALUE_TYPES.has(String(value.type));
387
378
  }
388
379
  function wrapPropDictionaryValues(dictionary) {
389
380
  let wrapped = false;
@@ -626,16 +617,12 @@ export function codePropTemplateErrors(ops) {
626
617
  *
627
618
  * Seçici anahtarlara (`&__body`, `:hover`, `--token`) DOKUNULMAZ; yalnız `a-b` biçimli düz CSS
628
619
  * ö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
620
  */
634
621
  const styleKeyPattern = /^[a-z][a-z0-9]*(-[a-z0-9]+)+$/;
635
622
  export function isStylePropName(name) {
636
623
  return name === 'style' || /Style$/.test(name);
637
624
  }
638
- export function normalizeStyleKeys(value, label, fixed, inlineFields) {
625
+ export function normalizeStyleKeys(value, label, fixed) {
639
626
  if (Array.isArray(value)) {
640
627
  for (const entry of value)
641
628
  normalizeStyleKeys(entry, label, fixed);
@@ -644,10 +631,7 @@ export function normalizeStyleKeys(value, label, fixed, inlineFields) {
644
631
  if (!value || typeof value !== 'object')
645
632
  return;
646
633
  const record = value;
647
- const skipped = new Set(inlineFields ?? []);
648
634
  for (const key of Object.keys(record)) {
649
- if (skipped.has(key))
650
- continue;
651
635
  normalizeStyleKeys(record[key], label, fixed);
652
636
  if (!styleKeyPattern.test(key))
653
637
  continue;
@@ -746,10 +730,8 @@ export function normalizeComponentDefaults(nodes) {
746
730
  if (node.props && typeof node.props === 'object' && !Array.isArray(node.props)) {
747
731
  const props = node.props;
748
732
  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
733
  for (const name of Object.keys(props).filter(isStylePropName)) {
752
- normalizeStyleKeys(props[name], `${String(node.elementId ?? node.name ?? '?')}.${name}`, styleKeys, inlineFields(name));
734
+ normalizeStyleKeys(props[name], `${String(node.elementId ?? node.name ?? '?')}.${name}`, styleKeys);
753
735
  }
754
736
  if (styleKeys.length > 0)
755
737
  missing.push(`stil anahtarları camelCase'e çevrildi: ${styleKeys.join(' · ')}`);
@@ -854,31 +836,19 @@ function normalizeReplacePropValue(op) {
854
836
  }
855
837
  return notes;
856
838
  }
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
839
  // Applier her sarmalın tipini korur, ama page/file/flow/widget/element taşıyıcıları başka alanlara
862
840
  // (FlowId, RedirectPageId, dosya) yazılır ve bu op'la bağları kurulmaz. Remove+add önerilmez:
863
841
  // düğümü yeniden kurmak ona yazan setter iteratee'lerinin element'ini siler (G-04, FLOW-018).
864
842
  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
843
  }
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) {
844
+ export function normalizeSchemaOps(ops) {
872
845
  const components = [];
873
846
  const props = [];
874
847
  const validations = [];
875
848
  for (const op of asObjects(ops)) {
876
849
  if (op.op === 'replace_prop') {
877
850
  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);
851
+ normalizeStyleKeys(op.value, `'${String(op.target ?? '?')}.${String(op.prop)}'`, props);
882
852
  }
883
853
  props.push(...normalizeReplacePropValue(op));
884
854
  continue;
@@ -2095,95 +2065,6 @@ export function flowBindings(schema, hostEvents) {
2095
2065
  visitNode(node);
2096
2066
  return bindings;
2097
2067
  }
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
2068
  /**
2188
2069
  * Bir yamanın SİLECEĞİ akışlar. Platform referanssız kalan akışı KALICI siler; uyarı yamadan sonra
2189
2070
  * geldiğinde "önce yedekle" tavsiyesi uygulanamaz hâle geliyordu (09-05 koşusu: sekiz adımlı giriş
@@ -2196,11 +2077,38 @@ export function orphanedFlowPlan(schema, pageEvents, ops) {
2196
2077
  // `remove_component` akışı uyarısız siliyordu).
2197
2078
  const opList = asObjects(ops).flatMap(op => op.op === 'batch' ? asObjects(op.ops) : [op]);
2198
2079
  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);
2080
+ // Plan yamanın SON durumuna bakar: aynı yamada başka düğüme ya da eklenen gövdeye bağlanan akış
2081
+ // referanssız değildir (K37-d: bağı `click`'ten `itemPress`'e taşıyan yama reddediliyordu). Aynı
2082
+ // yamada kaldırılan düğüme eklenen bağ sayılmaz.
2083
+ const removedTargets = new Set(opList.filter(op => op.op === 'remove_component').map(op => String(op.target ?? '')));
2084
+ const boundByPatch = new Set();
2085
+ for (const op of opList) {
2086
+ if ((op.op === 'add_event' || op.op === 'set_event') && typeof op.eventValue === 'string' && !removedTargets.has(String(op.target ?? ''))) {
2087
+ boundByPatch.add(op.eventValue);
2088
+ }
2089
+ if (op.op === 'add_component' && op.component && typeof op.component === 'object') {
2090
+ for (const flowId of collectFlowRefs(op.component))
2091
+ boundByPatch.add(flowId);
2092
+ }
2093
+ }
2094
+ const survivingRefs = (skipElementId, skipEvent) => {
2095
+ const surviving = new Set(boundByPatch);
2096
+ for (const event of asObjects(pageEvents)) {
2097
+ if (typeof event.value === 'string')
2098
+ surviving.add(event.value);
2099
+ }
2100
+ collectFlowRefsExcept(nodes, skipElementId, surviving);
2101
+ if (skipEvent !== undefined) {
2102
+ const node = findNodeByElementId(nodes, skipElementId);
2103
+ for (const event of asObjects(node?.events)) {
2104
+ if (String(event.name ?? '') !== skipEvent && typeof event.value === 'string')
2105
+ surviving.add(event.value);
2106
+ }
2107
+ for (const flowId of collectFlowRefs({ ...(node ?? {}), events: [] }))
2108
+ surviving.add(flowId);
2109
+ }
2110
+ return surviving;
2111
+ };
2204
2112
  for (const op of opList) {
2205
2113
  const target = String(op.target ?? '');
2206
2114
  if (target === '')
@@ -2210,6 +2118,7 @@ export function orphanedFlowPlan(schema, pageEvents, ops) {
2210
2118
  if (!doomed)
2211
2119
  continue;
2212
2120
  const losing = collectFlowRefs(doomed);
2121
+ const surviving = survivingRefs(target);
2213
2122
  const orphaned = [...losing].filter(flowId => !surviving.has(flowId));
2214
2123
  if (orphaned.length > 0)
2215
2124
  plan.push({ target, op: 'remove_component', flowIds: orphaned });
@@ -2231,7 +2140,10 @@ export function orphanedFlowPlan(schema, pageEvents, ops) {
2231
2140
  // oraya bağlı akış kapıdan geçip kalıcı silinirdi. Düzey olayı olmayan widget'ta applier da
2232
2141
  // düğüm aramasına düşer.
2233
2142
  if (op.op === 'remove_event' && target === 'page' && Array.isArray(pageEvents)) {
2234
- const removed = removedBy(boundTo(asObjects(pageEvents)));
2143
+ const hostEvents = asObjects(pageEvents);
2144
+ const removed = removedBy(boundTo(hostEvents));
2145
+ const surviving = new Set([...boundByPatch, ...hostEvents.filter(event => !removed.includes(event) && typeof event.value === 'string').map(event => String(event.value))]);
2146
+ collectFlowRefsExcept(nodes, '', surviving);
2235
2147
  const flowIds = [...new Set(removed.map(event => String(event.value)))].filter(flowId => !surviving.has(flowId));
2236
2148
  if (flowIds.length > 0)
2237
2149
  plan.push({ target, op: 'remove_event', flowIds });
@@ -2243,6 +2155,11 @@ export function orphanedFlowPlan(schema, pageEvents, ops) {
2243
2155
  const losing = op.op === 'set_event' ? named.filter(event => event.value !== eventValue) : removedBy(named);
2244
2156
  if (losing.length === 0)
2245
2157
  continue;
2158
+ const surviving = survivingRefs(target, eventName);
2159
+ for (const event of named) {
2160
+ if (!losing.includes(event))
2161
+ surviving.add(String(event.value));
2162
+ }
2246
2163
  const flowIds = [...new Set(losing.map(event => String(event.value)))].filter(flowId => !surviving.has(flowId));
2247
2164
  if (flowIds.length > 0)
2248
2165
  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
- }
@@ -329,7 +329,7 @@ export function profileFindings(profile, input) {
329
329
  target: stepIds.join(', '),
330
330
  message: type === 'download'
331
331
  ? "mobil uygulamada 'download' tarayıcı indirmesi yapmaz: adres dönen yanıt Linking.openURL ile açılır, ikili gövde (JSON değil) önbelleğe yazılıp paylaşım sayfasında (expo-sharing) açılır"
332
- : "mobil uygulamada 'setcookie' tarayıcı çerezi yazmaz, değeri güvenli cihaz deposuna (SecureStore) koyar; sonraki her istekte X-Flow-Cookie başlığıyla gider ve middleware/workflow onu web'deki gibi cookie.<ad> olarak okur — okuyan ifadeler aynı çalışır"
332
+ : "mobil uygulamada 'setcookie' çerez yazmaz, cihaz deposuna (storage, expo-sqlite/kv-store) eşlenir — okuyan ifadeler aynı çalışır"
333
333
  });
334
334
  }
335
335
  return findings;
@@ -7,7 +7,7 @@ import { MOBILE_DROPPABLE_TYPES } from '../mobileComponentCatalog.js';
7
7
  */
8
8
  export const RUNTIME_NORMAL_MARGIN = 4;
9
9
  export const RUNTIME_NORMAL_PADDING = 10;
10
- export const FLUSH_SPACING_TYPES = ['safe-area', 'scroll-view', 'app-bar', 'tooltip'];
10
+ export const FLUSH_SPACING_TYPES = ['safe-area', 'scroll-view', 'app-bar', 'tooltip', 'view'];
11
11
  export const HIDE_SPACING_TYPES = ['auth-layout', 'modal', 'drawer'];
12
12
  export const NO_PADDING_TYPES = ['auth-layout', 'modal', 'drawer'];
13
13
  export const SHELL_ROOT_TYPES = ['layout', 'layout-shell'];
@@ -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
  }
@@ -182,7 +182,7 @@ export const processNodeSchemas = [
182
182
  { type: 'start', purpose: 'Sürecin giriş noktası; tanımda üst düzeyde tam bir tane', required: ['id', 'type', 'description'], fields: { ...commonFields, trigger: 'row-event | manual | api | schedule | sub-process | message | signal', entity: 'row-event için entity slug', operation: 'create | update | delete', condition: 'Jint (row, previousRow)' }, example: { id: 'baslangic', type: 'start', description: 'Satır oluşunca başlar.', trigger: 'row-event', entity: 'gorevler', operation: 'create' } },
183
183
  { type: 'user-task', purpose: 'İnsan görevi; kutuya düşer', required: ['id', 'type', 'description', 'assignee'], fields: { ...commonFields, resultKey: 'sonucun adı: motor görev sonucunu { outcome, action, completedBy, payload } olarak vars.tasks.<resultKey> altına yazar (yoksa id snake_case yazılır: ik-kaydi → vars.tasks.ik_kaydi; eski ifadeler için kebab-case id altına da yazılır). Her user-task düğümüne snake_case verin (teslimat_kontrol) — kebab-case/slug değil: tire kabul edilmez, aynı tipte benzersizdir. Geçit vars.tasks.teslimat_kontrol.action === "sorunlu" diye okur; yazılmamış bir ad (vars.tasks.teslimatKontrol) undefined döner', form: '{ dtoId } görev formunun DTO kimliği (dto_list) — { pageId } sayfa formu, { formKey } dış form anahtarı. SLUG KABUL EDİLMEZ: dtoSlug yazmak sessizce düşer (BPM-021)', assignee: 'atama sözlüğü (ör. "subject-field:atanan_id", "role:finans")', mode: 'claim (varsayılan) | individual', join: 'all | any | force-complete (individual)', actions: '[{ id, label, completes, emits, evidence }]', completeOn: '{ trigger: row-event, operation, condition }', sla: '"P2D" ya da [{ name, duration, onBreach }]', requestInfo: 'bool', allowReassign: 'bool', external: 'bool — dış kullanıcı görevi', revisionBound: 'bool — bölge yeniden başlarsa eski görev superseded', undoWindow: 'ISO süre', assessment: '{ questionBank { entity, where, questionField, optionsField, answerField }, count, passScore (1..count, BPM-020), attempts, random, completeAction } — okuma kanıtından önce sınav' }, example: { id: 'gorevi-yap', type: 'user-task', resultKey: 'gorevi_yap', description: 'Atanan görevi yapar.', assignee: 'subject-field:atanan_id', sla: 'P3D' } },
184
184
  { type: 'approval', purpose: 'Onay görevi ve politika kararı', required: ['id', 'type', 'description', 'assignee'], fields: { ...commonFields, resultKey: 'kararın adı: motor sonucu vars.approvals.<resultKey> altına yazar (yoksa id snake_case yazılır: yonetici-onayi → vars.approvals.yonetici_onayi). Her approval düğümüne snake_case verin (yonetici_onayi) — kebab-case/slug değil: tire kabul edilmez, aynı tipte benzersizdir', form: '{ dtoId } görev formunun DTO kimliği (dto_list) — { pageId } sayfa formu, { formKey } dış form anahtarı. SLUG KABUL EDİLMEZ: dtoSlug yazmak sessizce düşer (BPM-021)', assignee: 'atama sözlüğü', policy: 'sequential | all | any | quorum(n) | majority | weighted(0.6)', rejectPolicy: 'any-reject | quorum(n) | majority', onReject: 'end | back-to:<düğüm> | restart', commentRequired: 'bool ya da Jint ("outcome === \'rejected\'")', selfApproval: 'escalate | skip | allow', weights: '{ "role:x": 2 }', veto: '["role:yk-baskani"]', abstain: 'bool', countAs: 'vars yolu' }, example: { id: 'kontrol-onay', type: 'approval', resultKey: 'kontrol_onay', description: 'Birim yöneticisi onaylar.', assignee: 'unit-manager of subject-field:atanan_id', policy: 'any', onReject: 'back-to:iade' } },
185
- { type: 'service', purpose: 'Workflow, bağlayıcı, dış motor ya da AI çağrısı (yan etkili iş)', required: ['id', 'type', 'description'], fields: { ...commonFields, workflowId: 'workflow GUID — workflowId | connector | externalEngine | ai alanlarından biri zorunlu; yalnız workflowSlug yazılan düğüm DefinitionInvalid alır (slug değişebilir), yanıt workflowId ve workflowSlug alanlarını birlikte döner', connector: '{ name, operation, credentialRef, input }', externalEngine: '{ engine: camunda8 | camunda7 | flowable, processKey, credentialRef, input }', input: '{ ad: "<Jint>" }', output: 'vars yolu ("vars.seviye")', retry: '{ count, backoff, delay }', runAs: 'system ise caution zorunlu (BPM-005)', ai: '{ operation: summarize | classify | extract | suggest-assignee | suggest-decision, labels, schema, files, input, instructions, autonomy: suggest | act-in-adhoc (BPM-019) } — öneri output yoluna yazılır, karar vermez' }, example: { id: 'seviye-hesapla', type: 'service', description: 'Tutardan onay seviyesini hesaplar.', workflowId: '<guid>', input: { tutar: 'row.tutar' }, output: 'vars.seviye' } },
185
+ { type: 'service', purpose: 'Workflow, bağlayıcı, dış motor ya da AI çağrısı (yan etkili iş)', required: ['id', 'type', 'description'], fields: { ...commonFields, workflowId: 'workflow GUID — workflowId | workflowSlug | connector | externalEngine | ai alanlarından biri zorunlu', connector: '{ name, operation, credentialRef, input }', externalEngine: '{ engine: camunda8 | camunda7 | flowable, processKey, credentialRef, input }', input: '{ ad: "<Jint>" }', output: 'vars yolu ("vars.seviye")', retry: '{ count, backoff, delay }', runAs: 'system ise caution zorunlu (BPM-005)', ai: '{ operation: summarize | classify | extract | suggest-assignee | suggest-decision, labels, schema, files, input, instructions, autonomy: suggest | act-in-adhoc (BPM-019) } — öneri output yoluna yazılır, karar vermez' }, example: { id: 'seviye-hesapla', type: 'service', description: 'Tutardan onay seviyesini hesaplar.', workflowId: '<guid>', input: { tutar: 'row.tutar' }, output: 'vars.seviye' } },
186
186
  { type: 'notify', purpose: 'Bildirim (kutu, e-posta outbox)', required: ['id', 'type', 'description', 'to'], fields: { ...commonFields, to: 'atama sözlüğü', channels: '["inbox", "email"]', template: '{ subject, body } — {{row.x}} yer tutucuları', ackRequired: 'bool' }, example: { id: 'bildir', type: 'notify', description: 'Yöneticiye bildirim.', to: 'unit-manager of subject-field:atanan_id', channels: ['inbox'] } },
187
187
  { type: 'gateway', purpose: 'Dallanma ve birleşme', required: ['id', 'type', 'description', 'kind'], fields: { ...commonFields, kind: 'exclusive | parallel | inclusive (koşulu tutan her dal; birleşmede hâlâ ulaşabilecek dallar beklenir) | event-based (yalnız wait/timer düğümlerine gider; ilk gelen olay kazanır, diğer bekleyişler iptal)', default: 'exclusive/inclusive için hiçbir koşul tutmazsa gidilen hedef' }, example: { id: 'butce-karari', type: 'gateway', kind: 'exclusive', description: 'Bütçe uygun mu?', default: 'reddedildi' } },
188
188
  { type: 'timer', purpose: 'Süre ya da tarih bekleme', required: ['id', 'type', 'description'], fields: { ...commonFields, duration: 'ISO süre', until: 'Jint tarih ifadesi', calendar: 'iş takvimi slug' }, example: { id: 'bekle', type: 'timer', description: 'Bir gün bekler.', duration: 'P1D' } },
@@ -1,39 +1,17 @@
1
1
  export const reservedTenantTables = [
2
- 'access_assignments',
3
- 'access_decision_logs',
4
- 'access_grants',
5
- 'access_permissions',
6
- 'access_policies',
7
- 'access_resources',
8
- 'ai_usage',
9
- 'app_refresh_tokens',
10
2
  'applications',
11
- 'assignment_pools',
12
3
  'audit_trail_values',
13
4
  'audit_trails',
14
- 'authority_limits',
15
5
  'branches',
16
- 'business_calendars',
17
6
  'caches',
18
- 'case_definition_versions',
19
- 'case_definitions',
20
- 'case_instance_events',
21
- 'case_instances',
22
- 'case_plan_items',
23
- 'component_bundle_versions',
24
7
  'component_definition_blocks',
25
8
  'component_definition_events',
26
9
  'component_definition_properties',
27
10
  'component_definition_property_options',
28
11
  'component_definition_validations',
29
12
  'components',
30
- 'connector_credentials',
31
- 'data_job_changes',
32
- 'data_jobs',
33
13
  'data_transfer_objects',
34
14
  'datasources',
35
- 'decision_versions',
36
- 'decisions',
37
15
  'design_component_blocks',
38
16
  'design_component_events',
39
17
  'design_component_properties',
@@ -56,15 +34,11 @@ export const reservedTenantTables = [
56
34
  'folder_middlewares',
57
35
  'folder_roles',
58
36
  'folders',
59
- 'global_functions',
60
37
  'layout_events',
61
38
  'layouts',
62
- 'microfunction_runtimes',
63
- 'microfunctions',
64
39
  'microservice_middlewares',
65
40
  'microservice_roles',
66
41
  'microservices',
67
- 'module_installations',
68
42
  'ms_source_entities',
69
43
  'ms_source_entity_fields',
70
44
  'ms_source_entity_filters',
@@ -72,79 +46,26 @@ export const reservedTenantTables = [
72
46
  'ms_source_entity_limits',
73
47
  'ms_source_entity_sorts',
74
48
  'ms_type_options',
75
- 'organization_position_closure',
76
- 'organization_positions',
77
- 'organization_unit_closure',
78
- 'organization_units',
79
49
  'page_events',
80
50
  'page_middlewares',
81
51
  'page_roles',
82
52
  'pages',
83
53
  'permissions',
84
- 'process_ai_suggestions',
85
- 'process_assessment_attempts',
86
- 'process_batch_operations',
87
- 'process_comments',
88
- 'process_definition_approval_members',
89
- 'process_definition_assignees',
90
- 'process_definition_edges',
91
- 'process_definition_event_handlers',
92
- 'process_definition_expression_references',
93
- 'process_definition_field_usages',
94
- 'process_definition_forms',
95
- 'process_definition_node_actions',
96
- 'process_definition_node_channels',
97
- 'process_definition_node_templates',
98
- 'process_definition_nodes',
99
- 'process_definition_overrides',
100
- 'process_definition_service_inputs',
101
- 'process_definition_sla_breach_actions',
102
- 'process_definition_sla_counters',
103
- 'process_definition_versions',
104
- 'process_definition_write_backs',
105
- 'process_definitions',
106
- 'process_delegations',
107
- 'process_event_sources',
108
- 'process_handovers',
109
- 'process_instance_archives',
110
- 'process_instance_events',
111
- 'process_instances',
112
- 'process_legal_holds',
113
- 'process_mail_sources',
114
- 'process_message_buffer',
115
- 'process_model_comments',
116
- 'process_notification_preferences',
117
- 'process_notifications',
118
- 'process_processed_events',
119
- 'process_publish_requests',
120
- 'process_signatures',
121
- 'process_task_action_tokens',
122
- 'process_task_candidates',
123
- 'process_tasks',
124
- 'process_test_scenarios',
125
- 'process_timers',
126
- 'process_watchers',
127
- 'process_webhook_subscriptions',
128
54
  'projects',
129
55
  'queries',
130
- 'queued_event_receipts',
131
56
  'queued_events',
132
57
  'role_permissions',
133
58
  'roles',
134
59
  'step_rule_condition_rules',
135
60
  'step_rules',
136
61
  'steps',
137
- 'translations',
138
62
  'ui_flow_step_argument_iterates',
139
63
  'ui_flow_step_argument_parameters',
140
64
  'ui_flow_step_argument_rules',
141
65
  'ui_flow_step_arguments',
142
66
  'ui_flow_step_branches',
143
67
  'ui_flow_steps',
144
- 'user_capacities',
145
- 'user_positions',
146
68
  'user_roles',
147
- 'user_skills',
148
69
  'users',
149
70
  'variables',
150
71
  'view_fields',