@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,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',
@@ -4,9 +4,7 @@ import { reservedTenantTables } from './reservedTables.js';
4
4
  import { headersAccessNames, isHeadersAccessGuarded } from './flowGuards.js';
5
5
  import { callsItself, functionCallRefs, isValidParameterName, mentionsAwait, nameProblem, sourceOf, callPrefix } from './functionGuards.js';
6
6
  import { backendPolicyRules } from './backendConstraints.js';
7
- import { accessPolicyRules } from './access.js';
8
7
  import { themePolicyRules } from './themeRules.js';
9
- import { processPolicyRules } from './process.js';
10
8
  const terminalStepTypes = new Set(['response', 'convert', 'revert']);
11
9
  const DESCRIPTION_EXEMPT_STEPS = new Set(['start']);
12
10
  const stepKindMatrix = {
@@ -21,7 +19,6 @@ const stepKindMatrix = {
21
19
  email: ['workflow', 'automation', 'middleware'],
22
20
  'file-upload': ['workflow', 'automation', 'middleware'],
23
21
  microfunction: ['workflow', 'automation', 'middleware'],
24
- process: ['workflow', 'automation'],
25
22
  variable: ['middleware'],
26
23
  'set-user': ['middleware'],
27
24
  setcookie: ['middleware'],
@@ -149,22 +146,13 @@ export function readsBeforeGuard(source, root) {
149
146
  * code.ts:49). Eşleşme yoksa flow-engine.ts:79 sessizce durur. Studio tarafında da zincir
150
147
  * `sourceBranch === 'always'` ile çizilir (EventActionsStart.svelte:47, EventActionsItem.svelte:298).
151
148
  * condition dalları rule id'sidir (serbest), microservice'te 'success' yalnız eski şema için
152
- * yaşatılır (microservice.ts:174 `isHasSuccess`). 'error' dalı 2026-09-26'dan beri motorun
153
- * KENDİSİ tanır (ADR 0004, ZM-07/g-02): bağlıysa hata anında `always` hiç koşmaz, sürer
154
- * (microservice.ts:182 `hasBranch`) — eski motor tanımadığı dalı hiç aramadığı için bu ekleme
155
- * geriye dönük zararsızdır.
149
+ * yaşatılır (microservice.ts:144).
156
150
  */
157
151
  const flowBranchNames = {
158
152
  start: ['always'],
159
- microservice: ['always', 'success', 'error'],
153
+ microservice: ['always', 'success'],
160
154
  confirm: ['yes', 'no', 'always'],
161
155
  function: ['always'],
162
- haptic: ['always'],
163
- location: ['always', 'error'],
164
- 'notification-permission': ['always'],
165
- 'notification-schedule': ['always', 'error'],
166
- 'notification-cancel': ['always'],
167
- bpm: ['always', 'success', 'fail'],
168
156
  end: []
169
157
  };
170
158
  /**
@@ -175,16 +163,8 @@ const flowBranchNames = {
175
163
  */
176
164
  export const knownFlowStepTypes = new Set([
177
165
  'start', 'end', 'query', 'setter', 'download', 'condition', 'redirect', 'setcookie', 'alert', 'confirm',
178
- 'microservice', 'validation', 'flow-trigger', 'storage', 'navigate', 'code', 'function', 'share',
179
- 'haptic', 'location', 'notification-permission', 'notification-schedule', 'notification-cancel', 'bpm'
166
+ 'microservice', 'validation', 'flow-trigger', 'storage', 'navigate', 'code', 'function'
180
167
  ]);
181
- /**
182
- * Cihaz yeteneği adımlarının kapalı kümeleri — `@ng-apps/flow` `tasks/device/device.functions.ts`
183
- * `HAPTIC_STYLES`/`LOCATION_ACCURACIES`'in aynası (`test/flow-step-parity.test.ts` bağlar); backend
184
- * `FlowDtoValidator` aynı kümeyle 400 döner. Kök `docs/adr/0003-cihaz-yetenegi-adimlari.md`.
185
- */
186
- export const hapticStyles = new Set(['success', 'warning', 'error', 'light', 'medium', 'heavy', 'selection']);
187
- export const locationAccuracies = new Set(['low', 'balanced', 'high']);
188
168
  const flowFreeBranchTypes = new Set(['condition']);
189
169
  /** `condition.types.ts` ConditionArgumentRuleType — motorun tanıdığı üçlü. */
190
170
  const conditionRuleTypes = new Set(['if', 'else-if', 'else']);
@@ -196,17 +176,16 @@ const conditionRuleIdPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}
196
176
  // Runtime.svelte'de HAM verilir (`argument: step.args`), yani bu alanlarda ifade değerlendirilmez.
197
177
  const flowLiteralTextFields = new Map([
198
178
  ['alert', ['message', 'description']],
199
- ['confirm', ['message', 'title', 'confirmText', 'cancelText']],
200
- ['share', ['title']],
201
- ['notification-schedule', ['name', 'title', 'path']],
202
- ['notification-cancel', ['name']]
179
+ ['confirm', ['message', 'title', 'confirmText', 'cancelText']]
203
180
  ]);
204
181
  const flowExpressionLooking = /\$\{|\b(?:Steps|Page|Row|Widget|LocalStorage|state|self|item|event|error|cookie)\s*(?:\?\.|\.|\[)/;
205
- // Barındırıcıya özel tipler BURADA kural üretmez. `navigate`i gateway normalizasyonu zaten
206
- // `redirect`e çeviriyor (normalize.ts `normalizeFlowHostGaps`) — `redirect` iki barındırıcıda da
207
- // koşar, yani vaka uyarılmaz, ORTADAN KALKAR. Gateway uygulamanın tipini platform profilinden bilir
208
- // ve barındırıcı sözlüğü `platform/*.ts`'tedir (`profile.steps`); mobil farkları orada `MOB-005`
209
- // olarak konuşulur (`platform/lint.ts`). Yeni mobil runtime `confirm`/`download`'ı kaydeder.
182
+ // Barındırıcıya özel tipler (`navigate` web'de, `confirm`/`download` mobilde register edilmez)
183
+ // BURADA kural üretmez. `navigate`i gateway normalizasyonu zaten `redirect`e çeviriyor
184
+ // (normalize.ts `normalizeFlowHostGaps`) — `redirect` iki barındırıcıda da koşar, yani vaka
185
+ // uyarılmaz, ORTADAN KALKAR. Geriye kalan `confirm`/`download` tek başına kusur değildir: sayfa
186
+ // tek bir uygulamaya aittir (`Page.ApplicationId`), uygulamanın tipi web ya da mobile'dır
187
+ // (`ApplicationType.cs`) ve gateway hangisi olduğunu bilmez. Mobil ayağı uygulama tarafında
188
+ // kapanır (`ScreenRuntime.tsx`), lint'te değil.
210
189
  const flowUnregisteredStepTypes = new Set(['end', 'query']);
211
190
  const flowSetterIterateeTypes = new Set(['change', 'fill']);
212
191
  function flowStepList(value) {
@@ -326,71 +305,25 @@ function writesRolesWithoutSlug(entityId, parameters) {
326
305
  }
327
306
  const rolesSlugMessage = "Built-in 'roles' entity'sine slug YAZMADAN rol satırı ÜRETİLİYOR (operation create/upsert). Insert 200 döner, satır role_list'te görünür ve page.roleIds ile bağlanır — ama yetkilendirme SLUG karşılaştırır: platformun get-user sorgusu roles+user_roles join'inden slug dizisi üretir ve Authorized(user.roles) o rol için hiçbir zaman tutmaz. fields'a slug'ı ekleyin ('super-admin' slug'ını vermeyin — platform süper yöneticiyi o slug ile arar). Upsert'te slug'ı İFADEYLE üretmeyin: UPDATE yolunda ifade yeniden değerlendirilir ve var olan rolün slug'ı sessizce değişir (MS-016) — üretilen slug'ı yalnız create ucunda yazın. Rolü kullanıcıya bağlamak ayrı bir user_roles satırıdır.";
328
307
  const contractKeys = ['returnDtoId', 'parameterDtoId', 'returnBehavior', 'parameterBehavior'];
329
- /**
330
- * Filtre işleci sözlüğü — backend `OperatorType` enum'u (paketlenmiş `Filter` şeması; eşitliği
331
- * `test/filter-operators.test.ts` kilitler). Studio filtre ARAYÜZÜNÜN sözlüğü (`notContains`, `between`…,
332
- * `componentCatalog.ts`) ayrı bir kavramdır: arayüz onları bu işleçlere çevirir.
333
- */
334
- export const filterOperators = new Set(['eq', 'neq', 'lt', 'lte', 'gt', 'gte', 'contains', 'icontains', 'in', 'notin', 'startswith', 'endswith', 'istartswith', 'iendswith', 'isnull', 'isnotnull']);
335
- /** Ajanların sık yazdığı yanlış adlar → doğru işleç. Yalnız ÖNERİLİR, sessizce çevrilmez. */
336
- const filterOperatorSuggestions = {
337
- ne: 'neq', '!=': 'neq', '<>': 'neq', noteq: 'neq', notequal: 'neq', notequals: 'neq', not_eq: 'neq',
338
- '=': 'eq', '==': 'eq', equal: 'eq', equals: 'eq',
339
- '<': 'lt', '<=': 'lte', '>': 'gt', '>=': 'gte',
340
- like: 'contains', ilike: 'icontains', nin: 'notin', 'not in': 'notin', not_in: 'notin'
341
- };
308
+ const filterOperators = new Set(['eq', 'neq', 'lt', 'lte', 'gt', 'gte', 'contains', 'icontains', 'in', 'notin', 'startswith', 'endswith', 'istartswith', 'iendswith', 'isnull', 'isnotnull']);
342
309
  function flattenFilterTree(filters) {
343
310
  return filters
344
311
  .filter((filter) => Boolean(filter) && typeof filter === 'object')
345
312
  .flatMap(filter => [filter, ...flattenFilterTree(asArray(filter.children))]);
346
313
  }
347
- /**
348
- * Bilinmeyen işleçler, öneriyle: `status: 'ne' (neq mı demek istedin?)`. Grup çocukları da okunur. Ad
349
- * büyük/küçük harfe DUYARLI eşlenir — backend de öyle eşler (`GetValueFromDescription` `==`); `NEQ`
350
- * bilinmeyendir ve küçük harfli adı önerilir.
351
- */
352
- function unknownFilterOperators(filters) {
353
- return flattenFilterTree(filters)
354
- .filter(filter => filter.operator !== undefined && filter.operator !== null && !filterOperators.has(String(filter.operator)))
355
- .map(filter => {
356
- const operator = String(filter.operator);
357
- const lower = operator.toLowerCase();
358
- const suggestion = filterOperators.has(lower) ? lower : filterOperatorSuggestions[lower];
359
- return `${String(filter.field ?? filter.fieldSlug ?? filter.fieldId ?? '?')}: '${operator}'${suggestion ? ` (${suggestion} mı demek istedin?)` : ''}`;
360
- });
361
- }
362
- const unknownOperatorConsequence = "Bilinmeyen işleç yola ve backend sürümüne göre ya 400 alır ya sessizce 'eq'e düşer ve sorgu yanlış sonuç döner (2026-09-27'den sonraki backend uç çağrısının `filters` parametresini 400 ile reddeder; workflow tablo adımı hâlâ sessizce 'eq' yapar); ad büyük/küçük harfe duyarlıdır — doğru işleci yazın";
363
314
  function unknownOperatorFindings(ruleId, owner, filters) {
364
- const unknownOperators = unknownFilterOperators(filters);
315
+ const unknownOperators = flattenFilterTree(filters)
316
+ .filter(filter => filter.operator !== undefined && filter.operator !== null && !filterOperators.has(String(filter.operator).toLowerCase()))
317
+ .map(filter => `${String(filter.fieldSlug ?? filter.fieldId ?? '?')}: '${String(filter.operator)}'`);
365
318
  return unknownOperators.length > 0
366
319
  ? [{
367
320
  ruleId,
368
321
  severity: 'block',
369
- message: `${owner}: bilinmeyen filtre işleci — ${unknownOperators.join(', ')}. ${unknownOperatorConsequence}. Geçerli sözlük: ${[...filterOperators].join(' · ')} ('like' yok — metin araması için 'contains'/'icontains').`,
322
+ message: `${owner}: bilinmeyen filtre operatörü — ${unknownOperators.join(', ')}. Platform bilinmeyen operatörü 400 ile REDDETMEZ, sessizce 'eq'e düşürür (EnumExtensions.GetValueFromDescription null → default) ve uç testten geçip yanlış çalışır. Geçerli sözlük: ${[...filterOperators].join(' · ')} ('like' yok — metin araması için 'contains'/'icontains').`,
370
323
  guide: 'ngapps://guides/microservice'
371
324
  }]
372
325
  : [];
373
326
  }
374
- /**
375
- * Çalışma anında gelen filtre (`row_list.filters`, `microservice_execute` `filters` parametresi): dizi ya
376
- * da JSON dizesi. Bilinmeyen işleç varsa hata METNİ döner — araç isteği göndermeden 400 verir
377
- * (plans/mobil-plantcare-acigi g-03). Ayrıştırılamayan değer backend'e bırakılır.
378
- */
379
- export function filterOperatorError(owner, filters) {
380
- let parsed = filters;
381
- if (typeof filters === 'string') {
382
- try {
383
- parsed = JSON.parse(filters);
384
- }
385
- catch {
386
- return undefined;
387
- }
388
- }
389
- const unknownOperators = Array.isArray(parsed) ? unknownFilterOperators(parsed) : [];
390
- return unknownOperators.length > 0
391
- ? `${owner}: bilinmeyen filtre işleci — ${unknownOperators.join(', ')}. İstek GÖNDERİLMEDİ. ${unknownOperatorConsequence}. Geçerli sözlük: ${[...filterOperators].join(' · ')}.`
392
- : undefined;
393
- }
394
327
  function isReadOperation(parameters) {
395
328
  const operation = String(parameters?.operation ?? '').toLowerCase();
396
329
  return !writeOperations.has(operation);
@@ -500,27 +433,6 @@ const isRecord = (value) => Boolean(value) && typeof value === 'object' && !Arra
500
433
  const functionsGuide = 'ngapps://guides/functions';
501
434
  /** FN-006: bu kadar dolu satırdan uzun gövde yorumsuz kalmaz; tek satırlık `return` yorum istemez. */
502
435
  const FUNCTION_COMMENT_MIN_LINES = 5;
503
- /**
504
- * BPM-022: `process.*` sistem işlemi karşılığı olan `Page.bpm` üyeleri (backend
505
- * `SystemOperationConstants`, zeyrek-backend/docs/bpm/sablon-paketleri.md §Sistem işlemleri).
506
- * `start`, `cases`, `documents`, `analytics`, `exportLog`, `offline`, `legalHold(s)` karşılıksızdır;
507
- * onları kullanan akışa uyarı vermek yol gösteremeyen gürültüdür.
508
- */
509
- const PAGE_BPM_SYSTEM_MEMBERS = new Set([
510
- 'definitions', 'users', 'directory', 'tasks', 'task', 'instances', 'instance', 'timeline', 'signal',
511
- 'batch', 'batchOperation', 'delegations', 'delegate', 'delegation', 'handover', 'notifications',
512
- 'notification', 'preferences', 'override', 'report'
513
- ]);
514
- /**
515
- * BPM-022: karşılığı olan üyenin sistem işlemi OLMAYAN alt çağrıları (bpm.runtime.ts). Bunlar ve
516
- * `batch('start', …)` eski yolda kalır; taze bağlam incelemesi (2026-09-23) üye düzeyindeki bakışın
517
- * `instance(id).exportLedger()` gibi rehberin kendi önerdiği çağrıları uyardığını buldu.
518
- */
519
- const PAGE_BPM_UNMAPPED_CALLS = new Set([
520
- 'tasks.calendar', 'task.comment', 'task.workedMinutes', 'task.assistant', 'instance.exportLedger',
521
- 'instance.watch', 'instance.unwatch', 'instance.comments', 'handover.history', 'override.conflicts',
522
- 'batchOperation.get'
523
- ]);
524
436
  export const policyRules = [
525
437
  {
526
438
  id: 'MS-001',
@@ -800,7 +712,7 @@ export const policyRules = [
800
712
  return [{
801
713
  ruleId: 'WF-005',
802
714
  severity: 'block',
803
- message: `'${stepLabel(step)}' step'i (${step.type}) ${kind} tipinde kullanılamaz. İzin matrisi: variable/set-user/setcookie/redirect yalnız middleware; convert yalnız workflow; revert yalnız automation; response workflow+middleware; process workflow+automation.`,
715
+ message: `'${stepLabel(step)}' step'i (${step.type}) ${kind} tipinde kullanılamaz. İzin matrisi: variable/set-user/setcookie/redirect yalnız middleware; convert yalnız workflow; revert yalnız automation; response workflow+middleware.`,
804
716
  guide: 'ngapps://guides/workflow'
805
717
  }];
806
718
  });
@@ -2339,25 +2251,6 @@ export const policyRules = [
2339
2251
  }];
2340
2252
  })
2341
2253
  },
2342
- {
2343
- id: 'FLOW-028',
2344
- module: 'flow',
2345
- appliesTo: ['create', 'update'],
2346
- sourceRef: "Yetki şablonu (access.json 1.7.0) 33 kod adımında platformun oturum uçlarına ham fetch atıyordu ('/api/' + project + '/runtime/' + application + '/auth/me' ve '/auth/sign-in'). Ham istek ng-apps-flow/src/api/instance.ts'in yaptıklarını atlar: X-Environment çözümü (resolveRuntimeEnvironment; elle ayrıştırma /preview şeridinde index -1 verir), CSRF başlığı (çerezli POST 403 CsrfTokenMismatchException — S2-37 · S3-7), 401'de tek refresh + yeniden deneme, ve ExecuteMicroserviceBehavior'ın microservice.execute kararı ile gölge günlüğü. Düzeltme 2026-09-22: giriş ve oturum bilgisi access.session.create / access.session.get system operation'larına taşındı (backend ADR 0004). Dış API'ye fetch meşrudur; kural yalnız göreli platform yollarını (/api/, /m/, /runtime/) görür",
2347
- check: definition => flowAllSteps(definition)
2348
- .filter(step => step.type === 'code')
2349
- .flatMap((step) => {
2350
- const body = String((step.args ?? {}).value ?? '');
2351
- if (!/\bfetch\s*\(|XMLHttpRequest/.test(body) || !/['"`]\/(api|m|runtime)\/|\/runtime\//.test(body))
2352
- return [];
2353
- return [{
2354
- ruleId: 'FLOW-028',
2355
- severity: 'warn',
2356
- message: `'${flowStepLabel(step)}' code adımı platformun kendi ucuna ham istek atıyor. Bu yol runtime'ın istek katmanını atlar: X-Environment elle kurulur, CSRF başlığı yoktur (çerezli POST 403 CsrfTokenMismatchException), 401'de oturum yenilenmez ve istek microservice.execute kararını ve gölge günlüğünü hiç görmez. Platform davranışını çağırmanın yolu microservice adımıdır: karşılığı olan bir system operation varsa (microservice_system_operation_list — giriş için access.session.create, oturumdaki kullanıcı için access.session.get) source:'system' bir uç açın ve akışa type:'microservice' adımı koyun; sonuç Steps.<adım>.data'dadır, kod adımı yalnız onu biçimler.`,
2357
- guide: 'ngapps://guides/page'
2358
- }];
2359
- })
2360
- },
2361
2254
  {
2362
2255
  id: 'FLOW-020',
2363
2256
  module: 'flow',
@@ -2481,7 +2374,7 @@ export const policyRules = [
2481
2374
  id: 'FLOW-022',
2482
2375
  module: 'flow',
2483
2376
  appliesTo: ['create', 'update'],
2484
- sourceRef: "alert.ts `const { message, alertType, description } = task.argument` → toast.error(message, { description }) / dialog.alert(message); confirm.ts `dialog.confirm(message, { title, confirmText, cancelText })` (boş çerçeve metni dialog.functions.ts resolveDialogFrame'de sabit metne düşer). Argüman Runtime.svelte'de HAM geçer (`argument: step.args`) — bu alanlarda hiçbir ifade değerlendirilmez, yazılan metin ekranda harfi harfine görünür (2026-09-06·2 koşusu S-13'ün ikinci turu: rehber hata mesajını göstermek için alert adımını öneriyordu). share adımında (2026-09-25) yalnız `title` düz metindir: @ng-apps/flow resolveShareContent onu olduğu gibi verir, `message` ve `path` ifadedir",
2377
+ sourceRef: "alert.ts `const { message, alertType, description } = task.argument` → toast.error(message, { description }) / dialog.alert(message); confirm.ts `dialog.confirm(message, { title, confirmText, cancelText })` (boş çerçeve metni dialog.functions.ts resolveDialogFrame'de sabit metne düşer). Argüman Runtime.svelte'de HAM geçer (`argument: step.args`) — bu alanlarda hiçbir ifade değerlendirilmez, yazılan metin ekranda harfi harfine görünür (2026-09-06·2 koşusu S-13'ün ikinci turu: rehber hata mesajını göstermek için alert adımını öneriyordu)",
2485
2378
  check: definition => flowAllSteps(definition)
2486
2379
  .flatMap((step) => {
2487
2380
  const type = String(step.type ?? '');
@@ -2494,164 +2387,16 @@ export const policyRules = [
2494
2387
  .map(field => ({
2495
2388
  ruleId: 'FLOW-022',
2496
2389
  severity: 'warn',
2497
- message: type.startsWith('notification-')
2498
- ? `'${flowStepLabel(step)}' ${type} adımının '${field}' alanı ifade içeriyor ama bu alan DÜZ METİNDİR (kök ADR 0003): ${field === 'name' ? 'bildirimin kimliği' : field === 'path' ? 'açılacak sayfanın slug\'ı' : 'bildirim başlığı'} olduğu gibi kullanılır, ifade değerlendirilmez. Değişen içeriği ifade olan 'message' (gövde) ya da 'query' (sayfanın sorgusu) alanına yazın.`
2499
- : type === 'share'
2500
- ? `'${flowStepLabel(step)}' share adımının '${field}' alanı ifade içeriyor ama bu alan DÜZ METİNDİR: başlık paylaşım penceresine olduğu gibi gider (iOS'ta e-posta konusu, Android'de seçici başlığı), ifade değerlendirilmez. Değişen içeriği ifade olan 'message' alanına yazın — ör. message: "'Şuna bak: ' + Page.properties.name"; bağlantı 'path' alanındadır.`
2501
- : `'${flowStepLabel(step)}' ${type} adımının '${field}' alanı ifade içeriyor ama bu alan DÜZ METİNDİR: ${type}.ts task.argument.${field}'i doğrudan ekrana geçirir ve args hiçbir yerde değerlendirilmez (Runtime.svelte \`argument: step.args\`). Kullanıcı ifadenin sonucunu değil ifadenin KENDİSİNİ görür. Ucun mesajını göstermek için bir setter (ya da code) adımı kullanın — value { type: 'code', ref: 'Steps.error?.message' }; hata metninin nerede durduğu page.md §hata yolu'nda.`,
2390
+ message: `'${flowStepLabel(step)}' ${type} adımının '${field}' alanı ifade içeriyor ama bu alan DÜZ METİNDİR: ${type}.ts task.argument.${field}'i doğrudan ekrana geçirir ve args hiçbir yerde değerlendirilmez (Runtime.svelte \`argument: step.args\`). Kullanıcı ifadenin sonucunu değil ifadenin KENDİSİNİ görür. Ucun mesajını göstermek için bir setter (ya da code) adımı kullanın — value { type: 'code', ref: 'Steps.error?.message' }; hata metninin nerede durduğu page.md §hata yolu'nda.`,
2502
2391
  guide: 'ngapps://guides/page'
2503
2392
  }));
2504
2393
  })
2505
2394
  },
2506
- {
2507
- id: 'FLOW-035',
2508
- module: 'flow',
2509
- appliesTo: ['create', 'update'],
2510
- sourceRef: "share adımının argümanı StepManagementArgument'ın Title/Message/Path alanlarında saklanır (StepType.cs `share`, kök docs/adr/0001-share-akis-adimi.md); url/link/text gibi anahtarlar sözleşmede YOKTUR ve platform onları 200 ile sessizce düşürür — adım hiçbir şey paylaşmadan akış sürer. `message` ve `path` İFADEDİR (@ng-apps/flow resolveShareContent → runCode): tırnaksız 'https://…' JS'te etiket + yorumdur, undefined döner",
2511
- check: definition => flowAllSteps(definition)
2512
- .filter(step => step.type === 'share')
2513
- .flatMap((step) => {
2514
- const args = (step.args ?? {});
2515
- const filled = (key) => typeof args[key] === 'string' && String(args[key]).trim().length > 0;
2516
- const findings = [];
2517
- const strayLinks = ['url', 'link', 'href'].filter(filled);
2518
- const strayTexts = ['text', 'body', 'content'].filter(filled);
2519
- if (strayLinks.length > 0) {
2520
- findings.push({
2521
- ruleId: 'FLOW-035',
2522
- severity: filled('path') ? 'warn' : 'block',
2523
- message: `'${flowStepLabel(step)}' share adımının bağlantısı args.${strayLinks.join('/args.')} alanında: bu anahtar StepManagementArgument sözleşmesinde YOK, platform onu 200 ile sessizce düşürür ve adım bağlantısız kalır. Bağlantıyı args.path'e ifade olarak yazın — ör. "'https://ornek.app/urun/' + Page.queryParams.id".`,
2524
- guide: 'ngapps://guides/page'
2525
- });
2526
- }
2527
- if (strayTexts.length > 0) {
2528
- findings.push({
2529
- ruleId: 'FLOW-035',
2530
- severity: filled('message') ? 'warn' : 'block',
2531
- message: `'${flowStepLabel(step)}' share adımının metni args.${strayTexts.join('/args.')} alanında: bu anahtar StepManagementArgument sözleşmesinde YOK, platform onu sessizce düşürür. Metni args.message'a ifade olarak yazın — ör. "'Şuna bak: ' + Page.properties.name".`,
2532
- guide: 'ngapps://guides/page'
2533
- });
2534
- }
2535
- for (const key of ['message', 'path']) {
2536
- const value = typeof args[key] === 'string' ? String(args[key]).trim() : '';
2537
- if (/^[a-z][a-z\d+\-.]*:\/\//i.test(value)) {
2538
- findings.push({
2539
- ruleId: 'FLOW-035',
2540
- severity: 'block',
2541
- message: `'${flowStepLabel(step)}' share adımının '${key}' alanı tırnaksız bir adres: '${value}'. Bu alan İFADEDİR — tırnaksız adres JS'te etiket + yorumdur, undefined döner ve hiçbir şey paylaşılmaz. Dize olarak yazın: "'${value}'".`,
2542
- guide: 'ngapps://guides/page'
2543
- });
2544
- }
2545
- }
2546
- return findings;
2547
- })
2548
- },
2549
- {
2550
- id: 'FLOW-029',
2551
- module: 'flow',
2552
- appliesTo: ['create', 'update'],
2553
- sourceRef: "Cihaz yeteneği adımlarının argümanı StepManagementArgument'ın mevcut alanlarındadır (kök docs/adr/0003-cihaz-yetenegi-adimlari.md): haptic.value = stil, location.value = doğruluk, location.isRaw = adres çözülmesin. İkisi de DÜZ METİNDİR (@ng-apps/flow hapticStyle/locationAccuracy), kümede olmayan değer backend FlowDtoValidator'da 400 alır; style/accuracy/reverseGeocode gibi anahtarlar sözleşmede YOKTUR ve platform onları 200 ile sessizce düşürür — adım varsayılanla (medium / balanced / adresli) koşar",
2554
- check: definition => flowAllSteps(definition)
2555
- .filter(step => step.type === 'haptic' || step.type === 'location')
2556
- .flatMap((step) => {
2557
- const args = (step.args ?? {});
2558
- // Backend (FlowDtoValidator) yalnız tamamen boşluk olanı boş sayar; kümeyle karşılaştırmayı kırpmadan yapar.
2559
- const raw = typeof args.value === 'string' ? args.value : '';
2560
- const value = raw.trim() ? raw : '';
2561
- const haptic = step.type === 'haptic';
2562
- const allowed = haptic ? hapticStyles : locationAccuracies;
2563
- const field = haptic ? 'stil' : 'doğruluk';
2564
- const findings = [];
2565
- const stray = (haptic ? ['style', 'type', 'feedback'] : ['accuracy', 'precision'])
2566
- .filter(key => args[key] !== undefined && args[key] !== null && args[key] !== '');
2567
- if (value && !allowed.has(value)) {
2568
- const unquoted = value.replace(/^['"`](.*)['"`]$/, '$1');
2569
- const trimmed = value.trim();
2570
- findings.push({
2571
- ruleId: 'FLOW-029',
2572
- severity: 'block',
2573
- message: allowed.has(unquoted)
2574
- ? `'${flowStepLabel(step)}' ${step.type} adımının ${field} değeri tırnaklı yazılmış: ${value}. Bu alan DÜZ METİNDİR, ifade değil — args.value: '${unquoted}' yazın.`
2575
- : allowed.has(trimmed)
2576
- ? `'${flowStepLabel(step)}' ${step.type} adımının ${field} değerinin çevresinde boşluk var: '${value}'. Platform kırpmadan karşılaştırır ve 400 döner — args.value: '${trimmed}' yazın.`
2577
- : `'${flowStepLabel(step)}' ${step.type} adımının ${field} değeri '${value}' tanınmıyor; platform 400 döner. Kullanılabilir: ${[...allowed].join(', ')} (boş → ${haptic ? 'medium' : 'balanced'}).`,
2578
- guide: 'ngapps://guides/mobile'
2579
- });
2580
- }
2581
- if (stray.length > 0) {
2582
- findings.push({
2583
- ruleId: 'FLOW-029',
2584
- severity: value ? 'warn' : 'block',
2585
- message: `'${flowStepLabel(step)}' ${step.type} adımının ${field} değeri args.${stray.join('/args.')} alanında: bu anahtar StepManagementArgument sözleşmesinde YOK, platform onu 200 ile sessizce düşürür ve adım varsayılanla (${haptic ? 'medium' : 'balanced'}) koşar. Değeri args.value'ya düz metin olarak yazın — ör. args.value: '${haptic ? 'success' : 'high'}'.`,
2586
- guide: 'ngapps://guides/mobile'
2587
- });
2588
- }
2589
- if (!haptic && ['reverseGeocode', 'address', 'geocode'].some(key => args[key] !== undefined)) {
2590
- findings.push({
2591
- ruleId: 'FLOW-029',
2592
- severity: 'warn',
2593
- message: `'${flowStepLabel(step)}' location adımında adres anahtarı sözleşmede YOK ve sessizce düşer. Adres varsayılan olarak çözülür (cihazda; web'de hep null); kapatmak için args.isRaw: true yazın.`,
2594
- guide: 'ngapps://guides/mobile'
2595
- });
2596
- }
2597
- return findings;
2598
- })
2599
- },
2600
- {
2601
- id: 'FLOW-030',
2602
- module: 'flow',
2603
- appliesTo: ['create', 'update'],
2604
- sourceRef: "Yerel bildirim adımlarının argümanı StepManagementArgument'ın mevcut alanlarındadır (kök docs/adr/0003-cihaz-yetenegi-adimlari.md): notification-schedule name = kimlik (düz metin, aynı kimlik eskisinin yerini alır), title düz metin, message ve value İFADE, path sayfa; notification-cancel name = kimlik ('*' hepsi). Zamanın türü value'nun sonucunun şeklinden okunur (@ng-apps/flow notificationTrigger): 'HH:mm' her gün, { weekday: 1-7, time: 'HH:mm' } her hafta (1 = Pazartesi), ISO tarih-saat bir kez. Eksik name/value backend FlowDtoValidator'da 400 alır; id/at/daily/weekly/body gibi anahtarlar sözleşmede YOKTUR ve platform onları 200 ile sessizce düşürür",
2605
- check: definition => flowAllSteps(definition)
2606
- .filter(step => step.type === 'notification-schedule' || step.type === 'notification-cancel')
2607
- .flatMap((step) => {
2608
- const args = (step.args ?? {});
2609
- const text = (key) => typeof args[key] === 'string' ? String(args[key]).trim() : '';
2610
- const findings = [];
2611
- const schedule = step.type === 'notification-schedule';
2612
- const stray = ['id', 'identifier', 'at', 'daily', 'weekly', 'time', 'body', 'text']
2613
- .filter(key => args[key] !== undefined && args[key] !== null && args[key] !== '');
2614
- if (!text('name')) {
2615
- findings.push({
2616
- ruleId: 'FLOW-030',
2617
- severity: 'block',
2618
- message: `'${flowStepLabel(step)}' ${step.type} adımının kimliği yok: args.name düz metin olarak yazılmalı (ör. 'sulama')${schedule ? ' — aynı kimlikle yeniden planlama eskisinin yerini alır' : " — '*' bütün planlı bildirimleri siler"}. Platform eksik kimliği 400 ile reddeder.`,
2619
- guide: 'ngapps://guides/mobile'
2620
- });
2621
- }
2622
- if (schedule && !text('value')) {
2623
- findings.push({
2624
- ruleId: 'FLOW-030',
2625
- severity: 'block',
2626
- message: `'${flowStepLabel(step)}' notification-schedule adımının zamanı yok: args.value bir İFADEDİR ve sonucu 'HH:mm' (her gün), { weekday: 1-7, time: 'HH:mm' } (her hafta, 1 = Pazartesi) ya da ISO tarih-saattir (bir kez) — ör. "tp_saat.value" ya da "'08:30'".`,
2627
- guide: 'ngapps://guides/mobile'
2628
- });
2629
- }
2630
- const literal = /^'([^']*)'$/.exec(text('value'))?.[1];
2631
- if (schedule && literal !== undefined && !/^([01]?\d|2[0-3]):[0-5]\d$/.test(literal) && Number.isNaN(Date.parse(literal))) {
2632
- findings.push({
2633
- ruleId: 'FLOW-030',
2634
- severity: 'block',
2635
- message: `'${flowStepLabel(step)}' notification-schedule adımının zamanı '${literal}' okunamaz: 'HH:mm' (00:00–23:59), ISO tarih-saat ya da { weekday, time } nesnesi yazın. Çalışmada adım error dalına düşer (status: 'invalid').`,
2636
- guide: 'ngapps://guides/mobile'
2637
- });
2638
- }
2639
- if (stray.length > 0) {
2640
- findings.push({
2641
- ruleId: 'FLOW-030',
2642
- severity: 'warn',
2643
- message: `'${flowStepLabel(step)}' ${step.type} adımında args.${stray.join('/args.')} sözleşmede YOK ve platform onu sessizce düşürür. Kimlik args.name, zaman args.value (ifade), metin args.message (ifade), başlık args.title.`,
2644
- guide: 'ngapps://guides/mobile'
2645
- });
2646
- }
2647
- return findings;
2648
- })
2649
- },
2650
2395
  {
2651
2396
  id: 'FLOW-023',
2652
2397
  module: 'flow',
2653
2398
  appliesTo: ['create', 'update'],
2654
- sourceRef: "Adım tipi sözlüğü backend'indir (StepType.cs) ama koşan tipler barındırıcıdan gelir: flow-engine.ts start·setter·code·condition·microservice·validation·flow-trigger register eder, web Runtime.svelte alert·confirm·redirect·download·storage·setcookie ekler, mobil @ng-apps/ui-native runtime-tasks.ts alert·confirm·redirect·navigate·storage·setcookie·download ekler. navigate web'de YOKTUR; end ve query hiçbir barındırıcıda yoktur (Studio kataloğu da bunu visibility ile söyler: navigate 'mobile', End eklenebilir adımlar arasında değil — EventActionsAdd.svelte). Register edilmemiş tipe gelen akış SESSİZCE durur: flow-engine.ts process() callback bulamazsa hiçbir şey yapmaz (next yok, completed/stopped yok, hata yok, log yok), run() Promise'i çözülmez ve flowRunFinished() hiç koşmaz — __ngAppsFlowActivity.running sıfıra inmez, page_screenshot'ın hazır bekleyişi her eylemde bütçesini sonuna kadar yakar",
2399
+ sourceRef: "Adım tipi sözlüğü backend'indir (StepType.cs) ama koşan tipler barındırıcıdan gelir: flow-engine.ts start·setter·code·condition·microservice·validation·flow-trigger register eder, web Runtime.svelte alert·confirm·redirect·download·storage·setcookie ekler, mobil ScreenRuntime.tsx alert·redirect·navigate·storage·setcookie ekler. navigate web'de, confirm/download mobilde YOKTUR; end ve query hiçbir barındırıcıda yoktur (Studio kataloğu da bunu visibility ile söyler: navigate 'mobile', confirm/download 'web'; End eklenebilir adımlar arasında değil — EventActionsAdd.svelte). Register edilmemiş tipe gelen akış SESSİZCE durur: flow-engine.ts process() callback bulamazsa hiçbir şey yapmaz (next yok, completed/stopped yok, hata yok, log yok), run() Promise'i çözülmez ve flowRunFinished() hiç koşmaz — __ngAppsFlowActivity.running sıfıra inmez, page_screenshot'ın hazır bekleyişi her eylemde bütçesini sonuna kadar yakar",
2655
2400
  check: definition => {
2656
2401
  const steps = flowAllSteps(definition);
2657
2402
  // Studio her akış tuvaline dekoratif bir End düğümü koyar ve onu sildirmez; zararlı olan
@@ -2977,29 +2722,6 @@ export const policyRules = [
2977
2722
  return findings;
2978
2723
  })
2979
2724
  },
2980
- {
2981
- id: 'BPM-022',
2982
- module: 'flow',
2983
- appliesTo: ['create', 'update'],
2984
- sourceRef: "bpm-management 1.1.0 sayfaları süreç çalışma zamanına yalnız source: system mikroservislerle gider (plans/bpm-sistem-mikroservis D-1 a, ADR-0004); Page.bpm aynı uçlara mikroservissiz gider, rehberi okuyan ajanlar yine de yazdı (plans/bpm/demo koşuları)",
2985
- check: definition => flowAllSteps(definition).flatMap((step) => {
2986
- const calls = [...new Set(flowExpressionSites(step)
2987
- .flatMap(site => [...site.expression.matchAll(/\bPage\s*\.\s*bpm\b(?:\s*\.\s*([A-Za-z_$][\w$]*))?(\s*\((?:[^()]|\([^()]*\))*\))?(?:\s*\.\s*([A-Za-z_$][\w$]*))?/g)])
2988
- .filter(([, member = '', callArguments = '', subCall]) => member === ''
2989
- || (PAGE_BPM_SYSTEM_MEMBERS.has(member)
2990
- && !(subCall && PAGE_BPM_UNMAPPED_CALLS.has(`${member}.${subCall}`))
2991
- && !(member === 'batch' && /^\s*\(\s*['"]start['"]/.test(callArguments))))
2992
- .map(([, member, , subCall]) => (member ? `Page.bpm.${member}${subCall ? `(…).${subCall}` : ''}` : 'Page.bpm')))];
2993
- return calls.length === 0
2994
- ? []
2995
- : [{
2996
- ruleId: 'BPM-022',
2997
- severity: 'warn',
2998
- message: `'${flowStepLabel(step)}' adımı Page.bpm çağırıyor (${calls.join(', ')}). Sayfa akışı süreç çalışma zamanıyla source: system mikroservis üzerinden konuşur: microservice_system_operation_list ile process.* işlemini seçin, microservice_create { source: 'system', systemOperation } ile ucu kurun ve çağrıyı bir microservice adımına taşıyın; sonucu okuyan code adımı Steps.<adım>.data / .error'dan okur. Page.bpm eski yoldur — izin ve görünürlük kararı sistem işleminde aynı servisten gelir, uç Studio'da ve microservice_execute ile görünür.`,
2999
- guide: 'ngapps://guides/bpm'
3000
- }];
3001
- })
3002
- },
3003
2725
  {
3004
2726
  id: 'MS-013',
3005
2727
  module: 'microservice',
@@ -3241,30 +2963,10 @@ export const policyRules = [
3241
2963
  }];
3242
2964
  }
3243
2965
  },
3244
- {
3245
- id: 'MW-006',
3246
- module: 'workflow',
3247
- appliesTo: ['create', 'update', 'preview'],
3248
- sourceRef: "Kimlik devri değeri triggerSource'ta DEĞİL context'te durur: WorkflowContext.SetTriggerSource triggerSource'a { type, id, name, slug, roles, pathAndQuery }, context'e { type, name, roles, path, impersonatedUserId, language } yazar (WorkflowContext.cs:216-235). triggerSource.impersonatedUserId her zaman undefined okunur ve önizleme hep jeton yoluna düşer (ZM-22, koşu 37)",
3249
- check: (definition) => {
3250
- const readers = workflowSteps(definition).filter(step => /\btriggerSource\s*\.\s*impersonatedUserId\b/.test(JSON.stringify(step.rule ?? {})));
3251
- return readers.length === 0
3252
- ? []
3253
- : [{
3254
- ruleId: 'MW-006',
3255
- severity: 'warn',
3256
- message: `'${readers.map(stepLabel).join(', ')}' kimlik devrini triggerSource.impersonatedUserId'den okuyor; bu alan yok, değer hep undefined gelir. Doğrusu context.impersonatedUserId — ve yalnız start adımının impersonation dalında: değer yalnız doğrulanmış Studio önizlemesinde dolar, başka yerde yetki kararı için kullanılmaz (platform_guide('middleware') Tarif 1c).`,
3257
- guide: 'ngapps://guides/middleware'
3258
- }];
3259
- }
3260
- },
3261
2966
  // Backend doğrulayıcılarının aynası (ENT-015…018, MS-017, WF-026, QRY/VIEW/DTO/ROW/DS/PRJ/TR/FLD/FILE/EXT):
3262
2967
  // tek liste `backendConstraints.ts`'te durur, buradan yalnız politika motoruna katılır.
3263
2968
  ...themePolicyRules,
3264
- ...backendPolicyRules(),
3265
- // Organizasyon şeması, erişim politikası ve alan koruması (ORG/ACC/PROT) — `access.ts`.
3266
- ...accessPolicyRules(),
3267
- ...processPolicyRules()
2969
+ ...backendPolicyRules()
3268
2970
  ];
3269
2971
  /**
3270
2972
  * WF-MF-001'in ikinci yarısı. Bir adımın koşup koşmayacağı yalnız GÖVDEDEN anlaşılamaz: karar
@@ -49,13 +49,6 @@ function referenceName(node) {
49
49
  return referenceName(allOf[0]);
50
50
  return undefined;
51
51
  }
52
- /**
53
- * `System.Text.Json.Nodes.JsonNode` gibi serbest JSON değerlerinin üretilen şeması katıdır
54
- * (`options/parent/root`); içine inilirse meşru anahtarlar "platform yok sayıyor" diye raporlanır.
55
- */
56
- function isFreeFormJson(node) {
57
- return /(^|.)Json(Node|Object|Array|Value|Element)$/.test(referenceName(node) ?? '');
58
- }
59
52
  function resolve(document, node) {
60
53
  if (!node || typeof node !== 'object')
61
54
  return undefined;
@@ -83,8 +76,6 @@ function walk(document, schema, value, path, into) {
83
76
  if (!schema || !value || typeof value !== 'object')
84
77
  return;
85
78
  if (Array.isArray(value)) {
86
- if (isFreeFormJson(schema.items))
87
- return;
88
79
  const items = resolve(document, schema.items);
89
80
  value.forEach((entry, index) => walk(document, items, entry, `${path}[${index}]`, into));
90
81
  return;
@@ -104,8 +95,6 @@ function walk(document, schema, value, path, into) {
104
95
  into.push(child);
105
96
  continue;
106
97
  }
107
- if (isFreeFormJson(properties[key]))
108
- continue;
109
98
  walk(document, resolve(document, properties[key]), entry, child, into);
110
99
  }
111
100
  }