@appaflytech/zeyrek-ai-mcp 0.0.1

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 (88) hide show
  1. package/.env.example +46 -0
  2. package/README.md +260 -0
  3. package/dist/config.js +128 -0
  4. package/dist/index.js +88 -0
  5. package/dist/knowledge/componentCatalog.js +438 -0
  6. package/dist/knowledge/componentEvents.js +164 -0
  7. package/dist/knowledge/coverage.js +60 -0
  8. package/dist/knowledge/normalize.js +1309 -0
  9. package/dist/knowledge/outlines.js +167 -0
  10. package/dist/knowledge/policy.js +44 -0
  11. package/dist/knowledge/reservedTables.js +75 -0
  12. package/dist/knowledge/rules.js +1725 -0
  13. package/dist/observability/trace.js +337 -0
  14. package/dist/platform/errors.js +132 -0
  15. package/dist/platform/http.js +169 -0
  16. package/dist/platform/responses.js +94 -0
  17. package/dist/platform/token.js +79 -0
  18. package/dist/resources/examples/entity-pair-m2m.json +105 -0
  19. package/dist/resources/examples/flow-list-to-form.json +65 -0
  20. package/dist/resources/examples/flow-load-table.json +178 -0
  21. package/dist/resources/examples/microservice-table-list.json +49 -0
  22. package/dist/resources/examples/middleware-authenticate.json +194 -0
  23. package/dist/resources/examples/page-detail-profile.json +95 -0
  24. package/dist/resources/examples/page-dynamic-form.json +221 -0
  25. package/dist/resources/examples/page-form-upsert.json +279 -0
  26. package/dist/resources/examples/page-html-embed.json +106 -0
  27. package/dist/resources/examples/page-sign-in.json +194 -0
  28. package/dist/resources/examples/workflow-basic.json +94 -0
  29. package/dist/resources/guides/component.md +108 -0
  30. package/dist/resources/guides/entity.md +348 -0
  31. package/dist/resources/guides/expressions.md +139 -0
  32. package/dist/resources/guides/getting-started.md +109 -0
  33. package/dist/resources/guides/html.md +106 -0
  34. package/dist/resources/guides/microservice.md +313 -0
  35. package/dist/resources/guides/middleware.md +271 -0
  36. package/dist/resources/guides/modify-existing.md +35 -0
  37. package/dist/resources/guides/page.md +1574 -0
  38. package/dist/resources/guides/view.md +89 -0
  39. package/dist/resources/guides/workflow.md +359 -0
  40. package/dist/resources/knowledge.js +44 -0
  41. package/dist/resources/schemas/CreateDatasourceCommand.json +54 -0
  42. package/dist/resources/schemas/CreateDiscoveredEntitiesCommand.json +133 -0
  43. package/dist/resources/schemas/CreateEntityCommand.json +387 -0
  44. package/dist/resources/schemas/CreateMicroserviceCommand.json +528 -0
  45. package/dist/resources/schemas/CreateQueryCommand.json +43 -0
  46. package/dist/resources/schemas/CreateViewCommand.json +158 -0
  47. package/dist/resources/schemas/CreateWorkflowCommand.json +1719 -0
  48. package/dist/resources/schemas/Filter.json +124 -0
  49. package/dist/resources/schemas/GetRowsQuery.json +122 -0
  50. package/dist/resources/schemas/PreviewMicroserviceCommand.json +565 -0
  51. package/dist/resources/schemas/PreviewQueryCommand.json +74 -0
  52. package/dist/resources/schemas/PreviewWorkflowCommand.json +981 -0
  53. package/dist/resources/schemas/StepDto.json +900 -0
  54. package/dist/resources/schemas/UpdateDatasourceCommand.json +58 -0
  55. package/dist/resources/schemas/UpdateEntityCommand.json +679 -0
  56. package/dist/resources/schemas/UpdateMicroserviceCommand.json +512 -0
  57. package/dist/resources/schemas/UpdateQueryCommand.json +86 -0
  58. package/dist/resources/schemas/UpdateViewCommand.json +153 -0
  59. package/dist/resources/schemas/UpdateWorkflowCommand.json +1719 -0
  60. package/dist/resources/schemas.js +40 -0
  61. package/dist/server.js +63 -0
  62. package/dist/tools/access.js +27 -0
  63. package/dist/tools/applications.js +59 -0
  64. package/dist/tools/automations.js +103 -0
  65. package/dist/tools/common.js +18 -0
  66. package/dist/tools/components.js +280 -0
  67. package/dist/tools/datasources.js +82 -0
  68. package/dist/tools/dependencies.js +17 -0
  69. package/dist/tools/deployments.js +17 -0
  70. package/dist/tools/dtos.js +54 -0
  71. package/dist/tools/entities.js +166 -0
  72. package/dist/tools/files.js +138 -0
  73. package/dist/tools/flows.js +226 -0
  74. package/dist/tools/folders.js +51 -0
  75. package/dist/tools/layouts.js +105 -0
  76. package/dist/tools/microservices.js +198 -0
  77. package/dist/tools/organizations.js +65 -0
  78. package/dist/tools/pages.js +597 -0
  79. package/dist/tools/platformInfo.js +44 -0
  80. package/dist/tools/projects.js +152 -0
  81. package/dist/tools/queries.js +48 -0
  82. package/dist/tools/rows.js +115 -0
  83. package/dist/tools/screens.js +97 -0
  84. package/dist/tools/templates.js +65 -0
  85. package/dist/tools/variables.js +94 -0
  86. package/dist/tools/views.js +58 -0
  87. package/dist/tools/workflows.js +196 -0
  88. package/package.json +49 -0
@@ -0,0 +1,438 @@
1
+ export const componentKnowledge = {
2
+ html: {
3
+ summary: 'Kaçış kapısı: hazır komponentler yetmediğinde ham HTML + Mustache şablonu + scoped CSS + satır içi script + flow köprüsüyle her gereksinimi kapatır.',
4
+ guide: 'html',
5
+ behavior: [
6
+ "content `{{` içeriyorsa Mustache şablonu olarak context prop'uyla render edilir; şablon hatasında ham içerik basılır (sayfa ölmez).",
7
+ "Flow'dan HTML'e veri DÖNER: setter adımı context prop'una yazınca içerik otomatik yeniden render olur — dinamik gösterimin doğru yolu budur.",
8
+ "HTML içinden flow tetikleme: actions dizisine { key, text, flow } satırı ekle, HTML'de fireEvent('<key>', {...}) çağır. Flow'da event.name = key, event.data = ikinci argüman.",
9
+ "Satır içi <script> etiketleri çalışır ve içerik her değiştiğinde yeniden çalışır; script gövdesinde komponent-bağlı fireEvent / onCleanup(fn) / loadScript(url) yerelleri hazırdır.",
10
+ "<script src=...> bilinçli olarak YÜKLENMEZ (öznitelik kopyalanmaz) — harici kütüphane loadScript(url) ile çekilir (Promise döner, url bazında tekilleştirir).",
11
+ "Script'ler flow ifade bağlamına (Page, Steps, komponent adları) erişemez; köprü yalnız fireEvent (dışarı) ve context (içeri).",
12
+ "Şema olayı yalnız mount'tur; aksiyonlar set_event ile DEĞİL kendi flow prop'uyla bağlanır (type:'flow', ref:<flowId>)."
13
+ ],
14
+ propNotes: {
15
+ content: "Ham HTML ya da Mustache şablonu. type:'code' + {{ }} ifadesiyle dinamik de beslenebilir.",
16
+ context: 'Mustache değişken sözlüğü (nesne). Setter ile yazmak içeriği yeniden render eder.',
17
+ style: "emotion css() bloğu: iç seçiciler ve &:hover çalışır, üretilen sınıf komponente scope'ludur.",
18
+ actions: "[{ key, text, flow }] — key fireEvent adıdır (text'ten snake üretilir), flow çalıştırılacak akıştır."
19
+ }
20
+ },
21
+ table: {
22
+ summary: 'Etkileşimli veri ızgarası: satır seçimi, çift tık, hücre içi düzenleme, kolon filtreleme/sıralama — her etkileşim AYRI olay olarak akışa bağlanır.',
23
+ behavior: [
24
+ 'Süzme/sıralama/sayfalama sunucu taraflıdır: filters/sortField/offset akışla uca gider, dönen satırlar rows prop’una setter ile yazılır.',
25
+ "isPaginated:true + akışta limit/offset parametreleri + pagination olayı üçlüsü birlikte kurulmalı; biri eksikse tablo tek sayfa kalır (platform_guide('page') Kural 1c)."
26
+ ],
27
+ propNotes: {
28
+ rows: 'Satır dizisi; mount/filter/sort/pagination akışlarının setter adımıyla doldurulur.',
29
+ totalRows: "Toplam kayıt: Number(Steps.<adım>?.headers?.[\"total-count\"] ?? 0) guard'lı ifadesiyle yazılır.",
30
+ rowSelection: "none | single | multi — seçim self.selectedRow / self.selectedRows prop'larından okunur.",
31
+ columns: "Kolon tanımları; mapping anahtarları kolonların name'iyle birebir eşleşmeli.",
32
+ isEditable: 'Hücre içi düzenleme; değişen satır rowChange olayında self.rows üzerinde güncellenir.'
33
+ }
34
+ },
35
+ datatable: {
36
+ summary: 'Kendi filtre paneli/sıralaması/sayfalaması İÇİNDE olan tablo: tek mount akışı yazılır, komponent etkileşimde prop’larını güncelleyip mount’u yeniden tetikler.',
37
+ behavior: [
38
+ "Tek olay yayması tasarımdır: kullanıcı süzünce/sıralayınca filters/sortField/sortType/offset prop'larını node'a yazar ve mount'u yeniden tetikler — akış bu prop'ları uca parametre geçirir. Yani mount/filter/sort/pagination için AYRI akışlar kurmak gerekmez (table'da gerekir).",
39
+ 'Zengin kolon biçimlendirme (renk haritası, prefix/suffix, tarih formatı, avatar) kolon şemasındadır; satır seçimi/çift tık YOKTUR — gerekiyorsa table kullan.',
40
+ "Liste→form geçişi satır AKSİYONUYLA kurulur: actions:[{ text, kind, icon, flow:{ type:'flow', ref:<flowId> } }]. doubleClick/select bağlamak 200 döner ama bağ ölüdür (gateway PAGE-008 keser).",
41
+ "Aksiyona tıklanınca komponent ÖNCE tıklanan satırı kendi selectedRow prop'una yazar, SONRA akışı çalıştırır (Table.svelte:72 setNode + onEmit) — akışta satır '<elementId>.selectedRow.<alan>' ile okunur. selectedRow katalogda hidden'dır; setter ile yazılmaz, komponent doldurur."
42
+ ],
43
+ propNotes: {
44
+ actions: "Satır aksiyonları. kind sözlüğü BUTON'unkinden farklıdır: error · information · solid · transparent · dark · danger · warning (butonda success/error/info/primary/warning). Yanlış sözlükten değer invalid-enum-value verir.",
45
+ selectedRow: "Salt okunur: satır aksiyonu tıklanınca komponentin kendisi doldurur; akış ifadesinde '<elementId>.selectedRow' ile okunur."
46
+ }
47
+ },
48
+ form: {
49
+ summary: "Alanları saran kapsayıcı; submit olayı yayar ve doğrulama hatalarını errorElementId'deki form-validation-errors komponentinde toplar.",
50
+ behavior: [
51
+ "Düzen prop'ları (layout/direction/gap/horizontalAlign…) YOKTUR — onlar container'a aittir. Form çocukları ızgara koordinatıyla (blocks[].position + size.w) dizilir; 'layout' yazmak unknown-prop ile reddedilir.",
52
+ "Alan doğrulaması komponentin kendi validations dizisindedir: [{ type: 'required'|'email'|'max-length'…, message, value, isActive }] — dördü de zorunlu, eski 'maxLength' yazımı kaydedilir ama runtime doğrulayıcı onu TANIMAZ ve sessizce hiçbir şey doğrulamaz."
53
+ ],
54
+ propNotes: {
55
+ errorElementId: "Sayfadaki form-validation-errors komponentinin elementId'si — bağlanmazsa alan doğrulama mesajları görünmez."
56
+ }
57
+ },
58
+ container: {
59
+ summary: "Genel kapsayıcı; children'ını ya FLEX akışıyla (yeni kapsayıcıların varsayılanı) ya da 12 kolonluk IZGARA ile dizer. Her sayfanın kökünde silinemeyen page_container bundandır ve o da aynı düzen prop'larını alır.",
60
+ behavior: [
61
+ "states.isWrapper:true iken salt düzen elemanıdır: title ve __header bloğu ÇİZİLMEZ — kart başlığı gerekiyorsa içine text komponenti koy (platform_guide('page') Bilinen sınırlar).",
62
+ "page_container'ın isLoading prop'u sayfa açılış akışının yükleniyor bayrağıdır.",
63
+ "layout:'flex' çocukları akışa alır (RenderComponent düzeni .ng-app__node-children sarmalına yazar): sıra blocks[].position'dan gelir (önce y, sonra x) ama y BOŞLUKLARI yok sayılır — flex'te dikey konum yalnız sıradır, ızgara koordinatı değil.",
64
+ "Flex çocuğun GENİŞLİĞİ yine 12 kolonluk blocks[].size.w'dur (row'da flex-basis w/12, column'da width w/12) — içerik genişliği DEĞİL. Yani ızgara↔flex geçişi kayıpsızdır ve genişlik şemadan kurulabilir.",
65
+ "Flex kapsayıcının yüksekliği içeriğinden gelir; verticalAlign'ın dağıtacak boşluğu olması için appearance.heightType:'fixed' + size.h vermek gerekir. İstisna: states.isWrapper:true olan page_container zaten min-height:80vh ile sayfa boyu durur, onda dikey hizalama boşluksuz da çalışır.",
66
+ "layout:'grid' iken diğer altı prop okunmaz — Studio panelinde de gizlenir. Katalogda tanımlı oldukları için doğrulama duvarı susar: ızgara kapsayıcıya direction yazmak sessizce hiçbir şey yapmaz (gateway PAGE-015 ile uyarır).",
67
+ "Katalog varsayılanı 2026-08-25'te grid → FLEX oldu ama varsayılan düğüm KURULURKEN props'a yazılır (Studio bırakma yolu definition.defaults'u kopyalar), renderer'da geriye dönük bir etkisi YOKTUR: layout prop'u hiç olmayan düğüm — bütün eski kayıtlar — ızgara çizilmeye devam eder. Yani şemayı sen kuruyorsan varsayılana güvenme, layout'u açıkça yaz."
68
+ ],
69
+ propNotes: {
70
+ layout: "'flex' (katalog varsayılanı; akış) | 'grid' (12 kolonluk ızgara). Prop hiç yazılmamışsa renderer IZGARA çizer — varsayılan yalnız düğüm kurulurken materyalize olur. Aşağıdaki altı prop YALNIZ 'flex' iken etkilidir.",
71
+ direction: "'row' (varsayılan) | 'column' → flex-direction. Hangi hizalamanın ana eksen olduğunu bu belirler.",
72
+ horizontalAlign: "left | center | right | stretch. row'da ANA eksen (justify-content), column'da ÇAPRAZ eksen (align-items). stretch: ana eksende space-between, çapraz eksende tam doldurma.",
73
+ verticalAlign: "top | middle | bottom | stretch. row'da ÇAPRAZ eksen, column'da ANA eksen — horizontalAlign ile rollerini değiştirirler.",
74
+ size: "'shrink' (çocuklar flex: 0 1 auto, varsayılan) | 'grow' (flex: 1 1 auto — çocuklar boşluğu paylaşır).",
75
+ gap: "none | small | medium (varsayılan) | large → 0 / 8 / 16 / 32px. Çocuk genişlik formülünden payı düşülür, böylece w toplamı 12 olan satır tam kapanır.",
76
+ wrap: "flex-wrap: wrap. Kapalıyken (varsayılan) satıra sığmayan çocuklar sıkışır, alt satıra inmez.",
77
+ title: "isWrapper:false kapta başlık çizer; page_container'da ise tarayıcı sekmesinin adını yazar (browserTitle).",
78
+ isLoading: 'Gövdeyi 100px’e kısar ve spinner gösterir; sayfa açılış akışında bayrak olarak kullanılır.'
79
+ }
80
+ },
81
+ repeater: {
82
+ summary: 'Kart listesi: rows dizisindeki her satır için children şablonunu yineler; satır bağlamı item/Row olarak çocuklara iner.',
83
+ propNotes: {
84
+ rows: 'Yinelenen veri; çocuk komponent ifadelerinde satıra item / Row ile erişilir.',
85
+ selectedIndex: 'change olayında seçilen kartın sırası.'
86
+ }
87
+ },
88
+ modal: {
89
+ summary: 'Ortalanmış katman; şemanın KÖKÜNDE page_container’ın kardeşi olarak durur, içeriği (kendi formu ve submit akışı dahil) children’ına eklenir.',
90
+ behavior: ["open/close olayları akışa bağlanabilir; açma/kapama isHidden ile değil kendi open state'iyle yürür (setter ile isOpen yaz)."]
91
+ },
92
+ drawer: {
93
+ summary: 'Yandan açılan katman; modal ile aynı kurallar: şema kökünde yaşar, kendi children ve akışlarını taşır.'
94
+ },
95
+ dropdown: {
96
+ summary: 'Tek seçim listesi; options statik verilebilir ya da mount/search akışıyla uzaktan doldurulur.',
97
+ propNotes: {
98
+ value: "Seçilen option'ın value'su — ilişki alanlarında etiket değil id yazılır/okunur.",
99
+ options: '[{ label, value }] dizisi; akışla doldurulacaksa setter hedefi budur.'
100
+ }
101
+ },
102
+ 'multi-select': {
103
+ summary: 'Aranabilir çoklu seçim; value bir değer dizisidir, search olayı sunucu taraflı arama kurmaya yarar.'
104
+ },
105
+ 'tag-input': { summary: 'Etiket listesi girişi; value etiket dizisidir, renkli etiket destekler.' },
106
+ textinput: { summary: 'Tek satır metin girişi; value prop’u yazılabilir, change olayı { value } taşır.' },
107
+ textarea: { summary: 'Çok satırlı metin girişi.' },
108
+ texteditor: { summary: 'Zengin metin editörü; onChange değeri HTML string’dir. Olay adları istisnadır: onMount/onChange (on önekli).' },
109
+ numberinput: { summary: 'Sayı girişi; change olayı number taşır.' },
110
+ incrementalinput: { summary: 'Otomatik kod üretici (önek + ayraç + sayaç); bir sonraki kodu runtime’da çeker.' },
111
+ password: { summary: 'Parola girişi; textinput ile aynı olay sözleşmesi.' },
112
+ checkbox: { summary: 'İki durumlu kutu; change/checked/unchecked olayları boolean taşır.' },
113
+ switch: { summary: 'Anahtar; checkbox ile aynı sözleşme, görsel fark.' },
114
+ radio: { summary: 'Tek seçim düğme grubu; change seçilen değeri taşır.' },
115
+ datepicker: { summary: 'Tarih seçici; change yükü { value, HH, mm }.' },
116
+ datetimepicker: { summary: 'Tarih+saat seçici; değer event.data’da değil self.value’dadır.' },
117
+ daterangepicker: { summary: 'Tarih aralığı; change yükü { valueFrom, valueTo, HH, mm }.' },
118
+ datetimerangepicker: { summary: 'Tarih+saat aralığı; daterangepicker ile aynı yük.' },
119
+ fileUpload: { summary: 'Sürükle-bırak dosya yükleme (dropzone); seçim self.value’dan okunur.' },
120
+ fileInput: { summary: 'Dosya seç girişi; change yükü { value: [{ type, value }], fileName }.' },
121
+ filebutton: { summary: 'Buton görünümlü dosya seçici; fileInput ile aynı yük.' },
122
+ 'file-viewer': { summary: 'Dosya önizleyici (pdf/görsel); file prop’una drive dosyası bağlanır.' },
123
+ button: { summary: 'Tıklama kaynağı; click olayı veri taşımaz, bağlam gerekiyorsa ifadede komponent adlarıyla okunur.' },
124
+ 'dropdown-button': { summary: 'Menülü buton; clickItem olayı tıklanan menü öğesini taşır.' },
125
+ compound: { summary: 'İkincil metinli büyük buton (compound button); click yayar.' },
126
+ 'confirm-bar': { summary: 'Satır içi onay şeridi; click olayı tıklanan buton tanımını taşır.' },
127
+ card: {
128
+ summary: 'Görsel + başlık + açıklama + buton metni taşıyan hazır KART; click yayar.',
129
+ behavior: [
130
+ "KAPSAYICI DEĞİLDİR: çocuk kabul etmez (not-droppable). Kutu içinde serbest içerik göstermek için container kullanın (istenirse states.isWrapper:true).",
131
+ 'Yükseklik 10-50 aralığındadır (min 10, max 20 varsayılan, max 50); aralık dışı blocks[].size.h invalid-size ile reddedilir.'
132
+ ]
133
+ },
134
+ 'qm-card': { summary: 'QM gösterge kartı; click yayar.' },
135
+ tabs: { summary: 'Sekmeler; tab olayı seçilen sekme anahtarını taşır, her view children sırasıyla eşleşir.' },
136
+ 'collapsible-container': { summary: 'Aç/kapa kapsayıcı; collapsed/expanded olayları yayar.' },
137
+ 'tree-view': {
138
+ summary: 'Hiyerarşik liste: data ağacını çizer, satır tıklamasını click olayıyla akışa verir, satır başına aksiyon menüsü ve isteğe bağlı istemci-tarafı arama taşır.',
139
+ behavior: [
140
+ "click yükü komponentin KENDİ prop'larına yazılır (onEmit → setNode): tıklanan satırın key'i self.selected'a, satırın TAMAMI self.currentItem'a — akışta ikisi de self ile okunur.",
141
+ 'selected akıştan yazıldığında o düğüme giden dallar KENDİLİĞİNDEN açılır (yalnız açar; kullanıcının elle açtıklarını kapatmaz). Satır verisindeki isExpanded:true de kendi başına açar.',
142
+ "actions komponent düzeyinde BİR KEZ tanımlanır, her satır aynı menüyü çizer; bir satır farklılaşacaksa veri öğesine _actions dizisi konur ve SIRA numarasıyla şablonun üstüne biner (o satırda gizleme / etiket değiştirme).",
143
+ "Aksiyonlar set_event ile DEĞİL kendi flow prop'larıyla bağlanır (emptystate/html deseni); tıklanan satır akışa self.currentItem olarak geçer, ayrı bir şema olayı yayılmaz.",
144
+ 'isSearchable:true arama kutusunu + tümünü aç/kapat düğmelerini açar. Süzme text ve subtle alanlarında geçer, eşleşenin ataları yerinde kalır, eşleşenin alt ağacı bütün görünür ve süzme sürerken dallar açık çizilir. Süzme İSTEMCİ tarafındadır: sunucuda arama gerekiyorsa kutuyu kapatıp kendi textinput + akış çiftini kur.',
145
+ 'isLoading iskelet satır çizer; veri (ya da arama sonucu) boşsa emptyText basılır.',
146
+ 'Satır ikonu icon > image > varsayılan klasör ikonu sırasıyla seçilir; satırdaki isHidden satırı hiç çizmez, isDisabled tıklamayı yutar.'
147
+ ],
148
+ propNotes: {
149
+ data: '[{ key, text, subtle, icon, image, isExpanded, isHidden, isDisabled, children[], _actions[] }] — key satırın kimliğidir, selected onunla eşleşir.',
150
+ selected: 'Seçili satırın key’i; setter ile dışarıdan da sürülebilir (o dala kadar ağaç açılır).',
151
+ currentItem: 'Gizli prop: son tıklanan / aksiyon alınan satırın tamamı.',
152
+ isSearchable: 'İstemci tarafı arama kutusu + tümünü aç/kapat araçları.',
153
+ searchPlaceholder: 'Arama kutusunun ipucu metni.',
154
+ emptyText: 'Veri ya da arama sonucu boşken basılan metin.',
155
+ actionsTitle: 'Aksiyon menüsünün başlığı.',
156
+ isActionsShowAlways: 'Aksiyon düğmesi sürekli görünür (varsayılan: satırın üstüne gelince).'
157
+ }
158
+ },
159
+ text: {
160
+ summary: 'Tek satırlık metin gösterimi; değer type:code prop’uyla ifadeye bağlanabilir.',
161
+ behavior: [
162
+ "Yükseklik SABİTTİR: maxSize.h = 1 (katalog varsayılanı 8'dir ve olduğu gibi kopyalanırsa reddedilir; gateway 1'e çeker ve gatewayNormalized ile bildirir). Çok satırlı metin için textarea ya da html kullanın."
163
+ ]
164
+ },
165
+ image: { summary: 'Görsel; click yayar, src ifadeyle beslenebilir.' },
166
+ video: { summary: 'Video oynatıcı; play/pause/ended olayları yayar.' },
167
+ qrcode: { summary: 'QR kod üretimi; value prop’undan çizer.' },
168
+ tags: { summary: 'Salt gösterim etiket listesi (tag-input’un okunur akrabası).' },
169
+ notification: {
170
+ summary: 'Sayfa içi geri bildirim kutusu; akışlarda alert adımı yerine bu komponent kullanılır.',
171
+ behavior: [
172
+ "isHidden bu komponentin KATALOĞUNDA YOKTUR: şemaya props.isHidden yazmak unknown-prop ile reddedilir (altın örnekte bir dönem yanlış duruyordu). Runtime'da gizleme çalışır — RenderComponent her komponentte props.isHidden'a bakar — ama prop'u oraya SETTER yazar, şema değil.",
173
+ "appearance.isHidden bir çözüm DEĞİLDİR: kaydedilir ama runtime hiçbir yerde okumaz (renderer yalnız props.isHidden'a bakar).",
174
+ 'Başlangıçta gizli bir bildirim istiyorsanız komponenti şemada bırakın ve içeriğini/görünürlüğünü akıştaki setter ile yönetin; timeout verilirse kendini kapatır.'
175
+ ],
176
+ propNotes: {
177
+ kind: 'information | error | success | warning (buton kind sözlüğünden farklıdır: orada info/primary vardır)'
178
+ }
179
+ },
180
+ 'form-validation-errors': { summary: 'Formun doğrulama hatalarını listeler; form.errorElementId buraya işaret eder.' },
181
+ breadcrumb: { summary: 'Sayfa yolu; currentTitle setter ile kip etiketine (Yeni/Düzenle) çevrilir.' },
182
+ 'page-header': { summary: 'Sayfa başlığı bandı; yalnız mount yayar.' },
183
+ header: { summary: 'Uygulama üst çubuğu (layout parçası); navigation dizisi iç içe Prop sarmalı ister.' },
184
+ sidebar: { summary: 'Yan menü (layout parçası).' },
185
+ 'auth-layout': { summary: 'Giriş ekranı kabuğu: logo kolonu + form slotu; primaryClick/secondaryClick olayları yayar.' },
186
+ layout: { summary: 'Layout kök komponenti; logout olayı yayar, sayfalar slot’una yerleşir.' },
187
+ slot: { summary: 'Layout’ta sayfa içeriğinin yerleştiği delik — slot’suz layout’a bağlanan sayfa BOŞ görünür.' },
188
+ view: { summary: 'Tabs/switcher altındaki görünüm kapsayıcısı; children gruplamaya yarar.' },
189
+ 'widget-area': { summary: 'Widget’ların yerleştirildiği alan.' },
190
+ 'audit-basic': { summary: 'Kayıt meta kutusu (oluşturan/güncelleyen); meta prop’u tek setter ile beslenir.' },
191
+ 'audit-history': { summary: 'Kayıt geçmişi listesi.' },
192
+ 'document-editor': { summary: 'Office şablon doldurma/görüntüleme editörü; file prop’una drive dosyası bağlanır.' },
193
+ 'qm-header': { summary: 'QM uygulama başlığı: global arama, bildirimler, hesap menüsü, mega menü.' },
194
+ 'qm-sidebar': { summary: 'QM yan menüsü.' },
195
+ 'qm-content': { summary: 'QM içerik kapsayıcısı.' },
196
+ // — 2026-08-25 eşleme turu: ng-apps-ui kataloğunda olup burada kaydı olmayan 22 komponent.
197
+ // Kaynak: packages/ng-apps-ui/src/components/<ad>/{schema.ts,*.svelte,*-logic.ts} +
198
+ // zeyrek-frontend/docs/components/*.md davranış sözleşmeleri.
199
+ autocomplete: {
200
+ summary: "Öneri listeli SERBEST METİN girişi. dropdown'dan farkı: value seçilen option'ın değeri değil, KULLANICININ YAZDIĞI metindir.",
201
+ behavior: [
202
+ "Öneriler iki kaynaktan gelir: statik options prop'u yerel olarak süzülür; komponente search olayına akış bağlıysa liste akıştan geldiği gibi gösterilir (dropdown deseninin aynısı).",
203
+ "Seçilen option'ın ID'sine ihtiyacın varsa select olayını dinle: value prop'una ETİKET yazılır, id yalnız select yükünde gelir.",
204
+ "strict:true serbest metni bulanıklaştırmaz, blur'da eşleşmeyen metni BOŞALTIR — şehir/ülke gibi yalnız geçerli değer isteyen alanlar içindir.",
205
+ "debounce yalnız akış tabanlı search'i geciktirir; yerel süzme senkrondur ve debounce'u yok sayar."
206
+ ],
207
+ propNotes: {
208
+ value: "Yazılan metin (change her tuş vuruşunda yayılır). Option değeri DEĞİLDİR.",
209
+ options: '[{ label, value, caption?, icon? }] — akışla doldurulacaksa setter hedefi budur.',
210
+ minChars: 'Liste bu karakter sayısından önce açılmaz (openOnFocus zaten açtıysa yok sayılır).',
211
+ openOnFocus: 'Odakta mevcut options listesini gösterir; YENİ bir search tetiklemez.',
212
+ strict: 'Blur’da options ile eşleşmeyen metni siler.',
213
+ maxSuggestions: 'Listede gösterilecek azami öneri (iki modda da geçerli).'
214
+ }
215
+ },
216
+ avatar: {
217
+ summary: 'Kullanıcı avatarı: src yoksa isimden baş harf üretir; items verilirse üst üste binen grup ve "+N" kuyruğu çizer.',
218
+ behavior: ["click olayı yalnız bağlıysa komponent tıklanabilir hâle gelir (image deseni)."],
219
+ propNotes: {
220
+ src: 'Görsel URL’i ya da drive dosyası; yüklenemezse baş harflere düşer.',
221
+ items: 'Grup kipi: her öğe kendi src/name’ini taşır, maxCount üstü "+N" olur.'
222
+ }
223
+ },
224
+ badge: {
225
+ summary: 'Sayaç/durum rozeti: maxCount üstü "99+" olur, 0 showZero verilmedikçe gizlenir, isDot ile salt nokta çizer. Olay YAYMAZ.',
226
+ behavior: [
227
+ 'value SAYIYSA sayaç kuralları işler (0 gizlenir, maxCount aşılırsa "99+"); sayıya çevrilemeyen metin ("Yeni", "Beta") olduğu gibi basılır — durum rozeti böyle kurulur.',
228
+ 'isDot:true iken value · icon · maxCount OKUNMAZ, yalnız renkli nokta çizilir; nokta tek başına anlam taşıyorsa dotLabel doldurulmalı (yoksa ekran okuyucuya aria-hidden geçilir).',
229
+ 'isPulsing nabız animasyonu ekler ve prefers-reduced-motion açık kullanıcıda kendiliğinden durur.'
230
+ ],
231
+ propNotes: {
232
+ value: 'Sayı ya da metin; boş string rozeti tamamen gizler.',
233
+ icon: 'Metnin soluna küçük ikon; nokta kipinde çizilmez.',
234
+ dotLabel: 'Nokta kipinin erişilebilir etiketi (title + aria-label).',
235
+ isPulsing: 'Nabız animasyonu — canlı/bekleyen durum vurgusu.',
236
+ variant: 'solid | soft | outline — soft ve outline rengi metne taşır, zemini şeffaflaştırır.',
237
+ size: 'sm | md | lg — yalnız ölçü değişir, sayaç kuralları aynı kalır.'
238
+ }
239
+ },
240
+ 'breadcrumb-title': {
241
+ summary: 'Kalın sayfa başlığı + önünde daralan kırıntı izi; eski mustache "doküman başlık" HTML widget’ının komponent karşılığı.',
242
+ behavior: [
243
+ "Son maxVisibleItems öğe satır içinde kalır, öncekiler '…' menüsüne toplanır (varsayılan 1; 0 = izin tamamı menüde).",
244
+ "Öğeye tıklamak önce öğenin KENDİ flow'unu çalıştırır, sonra clickItem yayar (dropdown-button sözleşmesi).",
245
+ 'rootHref verilmişse kök ikonu ona gider ve rootFlow ÇALIŞMAZ — href akışı ezer.'
246
+ ],
247
+ propNotes: {
248
+ items: '[{ text, flow, isHidden }] — sıralı iz; isHidden olanlar sayımdan önce elenir.',
249
+ maxVisibleItems: 'Satır içinde kalacak öğe sayısı (varsayılan 1).'
250
+ }
251
+ },
252
+ carousel: {
253
+ summary: 'Ok/nokta/altyazı ve isteğe bağlı otomatik oynatmalı görsel slider.',
254
+ behavior: [
255
+ "activeIndex tek doğruluk kaynağıdır: her gezinme slideChange yayar ve indeksi komponentin kendi prop'una yazar; akıştan atanan aralık dışı değer SARILMAZ, son slayta kırpılır.",
256
+ 'Slaytta href ya da flow varsa slayt tıklanabilir <a> olur; slideClick yükü tıklanan slaytı ve indeksini taşır.',
257
+ 'autoplay + interval (saniye, en az 1) ve pauseOnHover birlikte çalışır; loop kapalıyken uçtaki ok pasifleşir.'
258
+ ],
259
+ propNotes: {
260
+ items: '[{ src, title, description, alt, href, flow }] — src drive dosyası ya da URL.',
261
+ activeIndex: 'Görünen slayt; setter ile dışarıdan da sürülebilir.',
262
+ fit: 'cover | contain | fill | none (card.imageFit ile aynı sözleşme).'
263
+ }
264
+ },
265
+ chart: {
266
+ summary: 'ECharts tabanlı grafik (bar/line/area/pie/donut + waterfall, histogram, pareto, bullet, tornado, radial). VERİ ÇEKMEZ: satırlar rows prop’una akışla yazılır.',
267
+ behavior: [
268
+ "Veri prop'u data DEĞİL rows'tur (data eski adıdır, yalnız geriye uyumluluk için duruyor). Kategori categoryField, değerler series[].valueField ile çözülür.",
269
+ 'seriesField + valueField birlikte verilirse satırlar "kategori+seri başına bir satır" sayılıp geniş biçime pivotlanır; series dizisi o zaman prop’tan değil veriden türetilir.',
270
+ 'aggregate/sort/topN/nullMode veriyi çizimden ÖNCE dönüştürür — aynı işi akışta yapmana gerek yok.',
271
+ 'isDrillDown:true iken veri noktasına tıklamak kırıntı seviyesi ekler; dataPointClick yükü kaynak satırın TAMAMINI (row) taşır, böylece alt seviye sorgusu tek olayla kurulur. Geri dönüş breadcrumbClick ile bildirilir ve yeniden sorgulamak akışın işidir.',
272
+ 'isExportable "tablo olarak gör" + dışa aktarma araç çubuğunu açar; showRefresh refresh olayını yayan bir yenile düğmesi ekler.'
273
+ ],
274
+ propNotes: {
275
+ rows: 'Satır dizisi; mount/filter akışlarının setter hedefi.',
276
+ categoryField: 'Kategori ekseni alan adı (varsayılan "label").',
277
+ series: "[{ valueField, type?, axis?, color?, stack?, lowField/highField?, targetField? }] — yFields'ın yerini aldı.",
278
+ stackMode: 'none | stacked | percent.',
279
+ isDrillDown: 'Veri noktası tıklamasını kırıntı seviyesine çevirir; sorguyu akış yeniler.'
280
+ }
281
+ },
282
+ checkboxgroup: {
283
+ summary: 'Değeri DİZİ olan çoklu kutu grubu (multi-select’in liste hâlinde açılmış hâli).',
284
+ behavior: ['Zorunluluk/en az-en çok seçim kuralları formun validations’ından gelir (required · minItems · maxItems).'],
285
+ propNotes: {
286
+ value: 'string[] — akıştan gelen dizide string olmayan öğeler elenir.',
287
+ options: '[{ label, value }]; direction ile dikey/yatay dizilir.'
288
+ }
289
+ },
290
+ emptystate: {
291
+ summary: 'Boş ekran/liste bloğu: görsel ya da ikon + başlık + açıklama + aksiyon düğmeleri.',
292
+ behavior: [
293
+ "actions[].flow doğrudan çalışır (emit'in flowId'si üzerinden) ve ayrıca actionClick yayılır — table'ın boş durum aksiyonlarıyla aynı sözleşme.",
294
+ 'image verilirse icon ÇİZİLMEZ (görsel ikonu ezer); ikisi birden gösterilmez.',
295
+ 'isDisabled aksiyon tıklamayı yutar: ne kendi flow’u çalışır ne actionClick yayılır.'
296
+ ],
297
+ propNotes: {
298
+ image: 'Drive dosyası ya da URL; verildiğinde icon yok sayılır.',
299
+ size: 'sm | md | lg — ikon/görsel ölçüsünü ve dikey boşluğu birlikte ölçekler (dar kartta sm).',
300
+ actions: '[{ text, icon, kind, variant, flow, isHidden, isDisabled }] — boş bırakılan alanlar hiç çizilmez.'
301
+ }
302
+ },
303
+ iframe: {
304
+ summary: 'Sandbox’lı dış sayfa gömme. javascript:/data:/vbscript:/file: şemaları engellenir.',
305
+ behavior: [
306
+ "isSandboxed (varsayılan AÇIK) allow-scripts allow-forms allow-popups verir ama allow-same-origin VERMEZ — gömülü sayfa uygulamanın çerezine/depolamasına erişemez.",
307
+ 'Yalnız mount yayar: çapraz kaynak içerikte load/error olayı üretilemez.'
308
+ ]
309
+ },
310
+ jsonviewer: {
311
+ summary: 'Bağlanan veriyi katlanabilir JSON ağacı olarak çizer (hata ayıklama/detay ekranı). Olay YAYMAZ.',
312
+ behavior: [
313
+ "data STRING gelir ve '{' ya da '[' ile başlarsa JSON olarak parse edilip ağaç çizilir — uçtan metin olarak dönen gövdeyi akışta ayrıca çözmeye gerek yok; parse edilemezse düz metin gibi gösterilir.",
314
+ 'Boş veri (null · undefined · "" · {} · []) ağaç yerine emptyText satırını çizer ve araç çubuğu gizlenir.',
315
+ 'expandDepth çalışma anında değişirse ağaç YENİDEN kurulur: elle açıp kapattıkların sıfırlanır, düğümler yeni derinliğe göre açılır.',
316
+ 'Araç çubuğu (showToolbar) tümünü aç / tümünü kapat / JSON kopyala düğmeleridir; her düğümün kendi kopyala düğmesi de vardır. Kopyalama panoya güvenli bağlam ister; izin yoksa sessizce hiçbir şey olmaz.',
317
+ '60 karakteri aşan string yaprakları önizlemede kırpılır ("…"); yaprağa tıklamak tam değeri açar.'
318
+ ],
319
+ propNotes: {
320
+ data: 'Nesne/dizi ya da JSON metni; döngüsel referanslar "[Circular]" yaprağına düşer.',
321
+ expandDepth: 'Açılışta açık kalacak seviye sayısı (0 = her şey kapalı).',
322
+ emptyText: 'Veri boşken basılan metin.',
323
+ showToolbar: 'Aç/kapat/kopyala araç çubuğu (varsayılan AÇIK).'
324
+ }
325
+ },
326
+ 'language-selector': {
327
+ summary: 'Son kullanıcının sayfa dilini değiştirdiği açılır liste; projenin aktif dillerini kendi ana dil adlarıyla listeler.',
328
+ behavior: [
329
+ "change olayında runtime machine.setLanguage(value) çağırır: seçim localStorage'a (zeyrek:{appSlug}:lang) yazılır ve çeviri bağlı bütün prop'lar SAYFA YENİLENMEDEN yeniden çözülür.",
330
+ 'Projede dil tanımlı değilse liste boş çizilir — önce proje dillerini (Translations paneli) kur.'
331
+ ]
332
+ },
333
+ otpinput: {
334
+ summary: 'Tek haneli kutulardan oluşan tek kullanımlık kod girişi (2–12 hane); yapıştırma kutulara dağılır.',
335
+ behavior: ['Bütün kutular dolduğunda change’e EK olarak complete olayı yayılır — doğrulama akışını buna bağla.'],
336
+ propNotes: {
337
+ value: 'Birleşik string; ortadaki kutu silinince sonraki haneler sola kayar.',
338
+ digitCount: '2–12 arası kutu sayısı.',
339
+ isMasked: 'Haneleri nokta olarak gösterir.'
340
+ }
341
+ },
342
+ pagination: {
343
+ summary: 'table/datatable’ın içindeki sayfalayıcının BAĞIMSIZ hâli: repeater, kart listesi ya da özel düzen için offset/limit üretir.',
344
+ behavior: [
345
+ "Her gezinme change yayar ve offset/limit'i komponentin kendi prop'una yazar. Akışta bu değerleri event.data'dan DEĞİL self.offset / self.limit'ten (ya da value type:'property' ile) oku — event.data boş gelir ve sorgu LIMIT/OFFSET null ile TÜM satırları döndürür.",
346
+ 'limit değişince offset her zaman 0’a sıfırlanır (eski offset yeni sayfa boyunda anlamsızdır).',
347
+ 'Sayfalama durumunu ya bu komponentin prop’unda tut ve sorguyu {{pagination.offset}} ile bağla, YA DA sayfa değişkeninde tut ve change akışında setter adımıyla yaz. Komponentin prop’unu sayfa değişkenine bağlayıp otomatik geri yazma beklemek ÇALIŞMAZ.',
348
+ 'totalRows/offset/limit adları table/datatable ile birebir aynıdır; aynı sorgu bağları ikisiyle de çalışır.'
349
+ ],
350
+ propNotes: {
351
+ totalRows: 'Toplam kayıt; sayfa sayısı bundan hesaplanır.',
352
+ variant: 'numbers (numaralı düğmeler) | simple (düzenlenebilir sayfa kutusu, varsayılan) | compact (salt "3 / 12").',
353
+ limitOptions: 'Sayfa boyu seçenekleri; geçersizler elenir, hiçbiri kalmazsa [10,20,30,40,50] kullanılır.',
354
+ infoTemplate: '{from} {to} {total} {page} {pages} yer tutucuları; boşsa yerelin varsayılan metni.'
355
+ }
356
+ },
357
+ progress: {
358
+ summary: 'Çubuk ya da daire biçiminde ilerleme göstergesi; eşiğe göre renk değiştirir. Olay YAYMAZ.',
359
+ propNotes: {
360
+ value: '0..max arası; yüzde kırpılarak hesaplanır.',
361
+ colorMap: '{ "0": "error", "50": "warning", "80": "success" } — yüzdeye eşit/altındaki EN BÜYÜK eşiğin rengi kazanır, yoksa color prop’u.'
362
+ }
363
+ },
364
+ rating: {
365
+ summary: 'Yıldız (ya da seçilen ikon) ile puanlama girişi.',
366
+ behavior: ['Mevcut değere yeniden tıklamak puanı 0’a düşürür; allowHalf açıkken yıldızın sol yarısı yarım puan verir.'],
367
+ propNotes: { value: '0..max arası sayı; akıştan gelen değer bu aralığa kırpılır.' }
368
+ },
369
+ result: {
370
+ summary: 'Durum bloğu (success/error/warning/info): büyük ikon + başlık + alt başlık + aksiyonlar — işlem sonucu ekranları için.',
371
+ behavior: ["actions[].flow doğrudan çalışır ve actionClick yayılır (emptystate ile aynı sözleşme)."]
372
+ },
373
+ slider: {
374
+ summary: 'minValue–maxValue arasında sayısal kaydırıcı (tek değer; iki tutamaklı aralık YOKTUR).',
375
+ behavior: ['change sürüklerken sürekli, changed yalnız bırakıldığında yayılır — pahalı akışı changed’e bağla.'],
376
+ propNotes: {
377
+ value: 'Sayı; akıştan gelen değer [minValue, maxValue] aralığına kırpılır (0 geçerli sınırdır).',
378
+ showTicks: 'datalist ile çentik gösterir (yalnız ≤50 çentikte).'
379
+ }
380
+ },
381
+ statcard: {
382
+ summary: 'KPI kartı: büyük değer + ikon + trend oku + satır içi sparkline + alt bilgi bağlantısı.',
383
+ behavior: [
384
+ 'value SAYIYA çözülüyorsa valueFormat ile biçimlenir, çözülmüyorsa ("N/A", "3 gün") olduğu gibi basılır; boş değer "—" çizer.',
385
+ 'invertTrend yalnız RENGİ ters çevirir (hata oranı gibi "azalan iyidir" metrikleri için); ok yönü değişmez.',
386
+ 'Kartın kendisi click, alt bilgi satırı ayrı footerClick yayar; footerHref verilmişse alt bilgi bağlantı olur ve footerFlow yerine ona gider.'
387
+ ],
388
+ propNotes: {
389
+ value: 'Sayı ya da metin; sayıysa valueFormat uygulanır.',
390
+ sparkline: 'Sayı dizisi; kendi min/max’ına göre ölçeklenir (sıfır tabanlı değil).',
391
+ trend: 'Yüzde değişim; 0 nötrdür ve panelden temizlenemez.'
392
+ }
393
+ },
394
+ switcher: {
395
+ summary: 'İki durumu YAN YANA gösteren boolean kontrol (switch’in kolu yerine iki segment); aktif olan vurgulanır.',
396
+ behavior: [
397
+ 'Olay sözleşmesi switch ile aynıdır: change · checked · unchecked, hepsi boolean taşır.',
398
+ 'Yan etiket (label) ve description YOKTUR — içerik iki segmentin kendi trueLabel/trueIcon ve falseLabel/falseIcon alanlarıdır.'
399
+ ]
400
+ },
401
+ timeline: {
402
+ summary: 'Durum renkli işaretçilerle tarihli olay listesi (audit-history’nin serbest veriyle çalışan genel hâli).',
403
+ behavior: [
404
+ 'reverse sıralamayı maxCount kırpmasından ÖNCE uygular, böylece "ters + N kayıt" gerçekten EN YENİ N kaydı gösterir.',
405
+ 'maxCount üstü kayıtlar atılmaz: "Show more" çıkar, showMore olayı yayılır ve kalanların tamamı açılır; items yeni bir diziyle değişince görünüm kırpılmış hâline döner.',
406
+ "Öğede href/flow varsa satır tıklanabilir; clickItem yükü öğeyi ve indeksini taşır, öğenin kendi flow'u da doğrudan çalışır."
407
+ ],
408
+ propNotes: {
409
+ items: '[{ title, subtitle, description, date, status, icon, avatar, href, flow, isPending }] — boş alanlar çizilmez.',
410
+ dateFormat: 'absolute (varsayılan) | relative ("2 gün önce").',
411
+ maxCount: 'Görünür kayıt sınırı; aşıldığında Show more çıkar.'
412
+ }
413
+ },
414
+ timepicker: {
415
+ summary: 'Bağımsız saat seçici; değer tam olarak HH:mm biçimindedir.',
416
+ behavior: ['minTime/maxTime dışındaki seçenekler listeden ATILMAZ, pasifleştirilir; minutesStep seçenek adımını belirler.'],
417
+ propNotes: { value: "'HH:mm' — Time doğrulamaları ve formun saat karşılaştırmaları bu biçimi bekler." }
418
+ },
419
+ toast: {
420
+ summary: 'Geçici bildirim TETİKLEYİCİSİ: sayfada yer kaplamaz (0×0), isOpen true’ya çekildiğinde bir toast atar.',
421
+ behavior: [
422
+ "Tetikleme isOpen'ın YÜKSELEN KENARIDIR: komponent toast'ı gösterdikten sonra isOpen'ı kendi prop'unda false'a geri yazar. Akışta setter ile true yaz, sıfırlamayı düşünme.",
423
+ 'Süre kind’a göre gelir (success/info/default 4sn, warning 6sn, error 8sn, loading süresiz); duration verirsen o kazanır, isSticky ise kapanmaz.',
424
+ "actions[].flow doğrudan çalışır ve actionClick yayılır; keepOpen verilmedikçe tıklama toast'ı kapatır.",
425
+ 'Toast alanını runtime her uygulamada bir kez kurar — ikinci bir toast komponenti eklemek bildirimleri ÇİFTLEMEZ, her tetikleyici kendi toast’ını atar.'
426
+ ],
427
+ propNotes: {
428
+ isOpen: 'Setter ile true yaz → bir toast; komponent false’a geri döner.',
429
+ kind: 'default | info | success | error | warning | loading.',
430
+ position: '9 çapa: top/bottom × left/center/right, center, top-full/bottom-full (tam genişlik bant).',
431
+ actions: '[{ text, flow, keepOpen, showCountdown }] — en çok 2 düğme.'
432
+ }
433
+ }
434
+ };
435
+ export const knowledgeNote = 'knowledge alanı elle doğrulanmış davranış bilgisidir; kayıt yoksa davranış sözlüğe henüz işlenmemiştir — prop/olay semantiği tahmin etmeyin, gerekirse NgApps.UI kaynağına bakın.';
436
+ export function knowledgeFor(slug) {
437
+ return slug ? componentKnowledge[slug] : undefined;
438
+ }
@@ -0,0 +1,164 @@
1
+ const NO_DATA = { payload: {} };
2
+ const valueChange = (type) => ({ payload: { value: type } });
3
+ export const componentEventContracts = {
4
+ table: {
5
+ mount: NO_DATA,
6
+ pagination: { payload: { offset: 'number', limit: 'number' } },
7
+ filter: { payload: { filters: 'Array<{ field, operator, value, filterType, conditionType }>', offset: 'number' } },
8
+ sort: { payload: { sortField: 'string (kolonun name alanı)', sortType: "'asc' | 'desc' | '' (temizlendi)", offset: 'number' } },
9
+ select: { payload: {}, reads: 'self.selectedRow' },
10
+ selectionChange: { payload: {}, reads: 'self.selectedRows (dizi) + self.selectedRow' },
11
+ doubleClick: { payload: {}, reads: 'self.selectedRow' },
12
+ rowChange: { payload: {}, reads: 'self.rows (düzenlenen satır yerinde güncellenir)' }
13
+ },
14
+ datatable: {
15
+ mount: { payload: {}, reads: 'self.filters · self.sortField · self.sortType · self.offset · self.limit' }
16
+ },
17
+ button: { click: NO_DATA },
18
+ card: { click: NO_DATA },
19
+ compound: { click: NO_DATA },
20
+ image: { click: NO_DATA },
21
+ 'qm-card': { click: NO_DATA },
22
+ form: { mount: NO_DATA, submit: NO_DATA },
23
+ container: { mount: NO_DATA },
24
+ 'auth-layout': { mount: NO_DATA, primaryClick: NO_DATA, secondaryClick: NO_DATA },
25
+ layout: { mount: NO_DATA, logout: NO_DATA },
26
+ textinput: { mount: NO_DATA, change: valueChange('string'), blur: NO_DATA },
27
+ textarea: { mount: NO_DATA, change: valueChange('string'), blur: NO_DATA },
28
+ password: { mount: NO_DATA, change: valueChange('string'), blur: NO_DATA },
29
+ numberinput: { mount: NO_DATA, change: valueChange('number'), blur: NO_DATA },
30
+ incrementalinput: { mount: NO_DATA, change: valueChange('string'), blur: NO_DATA },
31
+ texteditor: { onMount: NO_DATA, onChange: valueChange('string (HTML)') },
32
+ checkbox: { change: valueChange('boolean'), checked: valueChange('boolean'), unchecked: valueChange('boolean') },
33
+ switch: { change: valueChange('boolean'), checked: valueChange('boolean'), unchecked: valueChange('boolean') },
34
+ radio: { change: valueChange('string') },
35
+ dropdown: { mount: NO_DATA, change: valueChange('seçilen option değeri'), search: { payload: { searchText: 'string' } }, focus: NO_DATA },
36
+ 'multi-select': { mount: NO_DATA, change: valueChange('değer dizisi'), search: { payload: { searchText: 'string' } }, focus: NO_DATA },
37
+ 'tag-input': { mount: NO_DATA, change: valueChange('etiket dizisi'), focus: NO_DATA },
38
+ datepicker: { mount: NO_DATA, change: { payload: { value: 'string (tarih)', HH: 'string', mm: 'string' } } },
39
+ datetimepicker: { mount: NO_DATA, change: { payload: {}, reads: 'self.value' } },
40
+ daterangepicker: { mount: NO_DATA, change: { payload: { valueFrom: 'string', valueTo: 'string', HH: 'string', mm: 'string' } } },
41
+ datetimerangepicker: { mount: NO_DATA, change: { payload: { valueFrom: 'string', valueTo: 'string', HH: 'string', mm: 'string' } } },
42
+ fileUpload: { change: { payload: {}, reads: 'self.value' } },
43
+ fileInput: { change: { payload: { value: 'Array<{ type, value }>', fileName: 'string' } } },
44
+ filebutton: { change: { payload: { value: 'Array<{ type, value }>', fileName: 'string' } } },
45
+ 'file-viewer': { mount: NO_DATA },
46
+ modal: { open: NO_DATA, close: NO_DATA },
47
+ drawer: { open: NO_DATA, close: NO_DATA },
48
+ repeater: { mount: NO_DATA, change: { payload: { selectedIndex: 'number' }, reads: 'item / Row (satır bağlamı)' } },
49
+ tabs: { mount: NO_DATA, tab: { payload: { selected: 'string (sekme anahtarı)' } } },
50
+ 'tree-view': {
51
+ mount: NO_DATA,
52
+ click: {
53
+ payload: { selected: 'string (tıklanan satırın key’i)', currentItem: 'tıklanan satırın tamamı ({ key, text, subtle, icon, image, children… })' },
54
+ reads: "aksiyon menüsü AYRI olay yaymaz: aksiyonun kendi flow'u çalışır ve satır yine self.currentItem'a yazılır"
55
+ }
56
+ },
57
+ 'dropdown-button': { mount: NO_DATA, click: NO_DATA, clickItem: { payload: { currentItem: 'tıklanan menü öğesi' } } },
58
+ 'confirm-bar': { mount: NO_DATA, click: { payload: { currentItem: 'tıklanan buton tanımı' } } },
59
+ 'collapsible-container': { mount: NO_DATA, collapsed: NO_DATA, expanded: NO_DATA },
60
+ 'audit-basic': { mount: NO_DATA },
61
+ 'audit-history': { mount: NO_DATA },
62
+ 'form-validation-errors': { mount: NO_DATA },
63
+ 'page-header': { mount: NO_DATA },
64
+ header: { mount: NO_DATA },
65
+ sidebar: { mount: NO_DATA },
66
+ html: { mount: NO_DATA },
67
+ view: { mount: NO_DATA },
68
+ 'widget-area': { mount: NO_DATA },
69
+ 'document-editor': { mount: NO_DATA },
70
+ video: { mount: NO_DATA, click: NO_DATA, play: NO_DATA, pause: NO_DATA, ended: NO_DATA },
71
+ // — 2026-08-25 eşleme turu: ng-apps-ui'da olay YAYAN ama burada kaydı olmayan komponentler.
72
+ // Yükler kaynaktaki dispatch('emit', { name, data }) / machine.onEmit(id, { event, data })
73
+ // çağrılarından birebir çıkarıldı. Olay yaymayan komponentler (badge · breadcrumb · jsonviewer ·
74
+ // notification · progress · qrcode · slot · tags · text) bilinçli olarak kayıtsızdır.
75
+ autocomplete: {
76
+ mount: NO_DATA,
77
+ change: valueChange('string (YAZILAN metin — option değeri değil)'),
78
+ select: { payload: { value: "seçilen option'ın değeri", label: "seçilen option'ın etiketi" }, reads: 'self.value etiketi taşır; id gerekiyorsa bu olaydaki value' },
79
+ search: { payload: { searchText: 'string' } },
80
+ enter: { payload: { value: 'string (Enter anındaki metin; vurgulu öneri yokken)' } },
81
+ focus: NO_DATA,
82
+ blur: NO_DATA
83
+ },
84
+ avatar: { click: NO_DATA },
85
+ 'breadcrumb-title': {
86
+ mount: NO_DATA,
87
+ clickItem: { payload: { currentItem: '{ text, flow, isHidden } — tıklanan iz öğesi' } },
88
+ clickRoot: NO_DATA
89
+ },
90
+ carousel: {
91
+ mount: NO_DATA,
92
+ slideChange: { payload: { activeIndex: 'number' } },
93
+ slideClick: { payload: { currentItem: 'slayt nesnesi', index: 'number' } }
94
+ },
95
+ chart: {
96
+ mount: NO_DATA,
97
+ dataPointClick: { payload: { name: 'string (kategori)', seriesName: 'string', value: 'number | null', dataIndex: 'number', row: 'kaynak satırın TAMAMI | null' } },
98
+ breadcrumbClick: { payload: { filterValue: 'hedef seviyenin filtre değeri (kök seviyede undefined)' } },
99
+ selectionChange: { payload: { selected: 'seçili veri noktaları' } },
100
+ legendClick: { payload: { name: 'string (seri adı)', selected: 'seri → görünürlük haritası' } },
101
+ axisLabelClick: { payload: { value: 'string (tıklanan eksen etiketi)' } },
102
+ zoom: { payload: { start: 'number (görünen aralığın başlangıç yüzdesi)', end: 'number (bitiş yüzdesi)' }, reads: "ECharts dataZoom params'ı olduğu gibi geçer; sürüme göre batch/startValue/endValue de gelebilir" },
103
+ refresh: NO_DATA,
104
+ retry: NO_DATA
105
+ },
106
+ checkboxgroup: { mount: NO_DATA, change: valueChange('string[] (seçili değerler)') },
107
+ emptystate: { actionClick: { payload: { text: 'string (aksiyonun metni)', index: 'number' }, reads: "aksiyonun kendi flow'u zaten doğrudan çalışır" } },
108
+ iframe: { mount: NO_DATA },
109
+ 'language-selector': { change: { payload: { value: 'string (dil kodu)' }, reads: 'runtime ayrıca machine.setLanguage(value) çağırır' } },
110
+ otpinput: {
111
+ mount: NO_DATA,
112
+ change: valueChange('string (birleşik kod)'),
113
+ complete: { payload: { value: 'string (tüm haneler dolduğunda)' } }
114
+ },
115
+ pagination: { mount: NO_DATA, change: { payload: { offset: 'number', limit: 'number' }, reads: 'self.offset · self.limit (sorguyu bunlara bağla)' } },
116
+ rating: { mount: NO_DATA, change: valueChange('number (0..max; allowHalf ile yarım)') },
117
+ result: { actionClick: { payload: { text: 'string (aksiyonun metni)', index: 'number' }, reads: "aksiyonun kendi flow'u zaten doğrudan çalışır" } },
118
+ slider: {
119
+ mount: NO_DATA,
120
+ change: valueChange('number (sürüklerken sürekli)'),
121
+ changed: valueChange('number (tutamak bırakıldığında — pahalı akışı buna bağla)')
122
+ },
123
+ statcard: { mount: NO_DATA, click: NO_DATA, footerClick: { payload: {}, reads: "footerFlow zaten doğrudan çalışır; footerHref varsa tıklama ona gider" } },
124
+ switcher: { change: valueChange('boolean'), checked: valueChange('boolean'), unchecked: valueChange('boolean') },
125
+ timeline: {
126
+ mount: NO_DATA,
127
+ clickItem: { payload: { currentItem: 'tıklanan olay öğesi', index: 'number' }, reads: "öğenin kendi flow'u da doğrudan çalışır" },
128
+ showMore: NO_DATA
129
+ },
130
+ timepicker: { mount: NO_DATA, change: valueChange("string 'HH:mm' (temizlenince '')") },
131
+ toast: {
132
+ open: NO_DATA,
133
+ close: NO_DATA,
134
+ click: NO_DATA,
135
+ actionClick: { payload: { text: 'string (aksiyonun metni)', index: 'number' }, reads: "aksiyonun kendi flow'u zaten doğrudan çalışır" }
136
+ },
137
+ 'qm-header': {
138
+ mount: NO_DATA,
139
+ languageChange: { payload: { selectedLang: 'string (dil kodu)' } },
140
+ notificationClick: NO_DATA,
141
+ notificationSelect: { payload: { currentItem: 'seçilen bildirim kaydı' } },
142
+ notificationsClear: NO_DATA,
143
+ search: { payload: { searchValue: 'string (kırpılmış arama metni)' } },
144
+ searchResultClick: { payload: {}, reads: "tıklanan kayıt yalnız emit params'ında (item) taşınır ve ifade kapsamına GİRMEZ — kayıt id'si gerekiyorsa aramayı kendi komponentinle kur" }
145
+ },
146
+ 'qm-sidebar': { mount: NO_DATA, collapsed: { payload: {}, reads: "daralma durumu emit'in value alanındadır; motor yalnız data'yı prop'a yazdığı için akışa ULAŞMAZ" } },
147
+ 'qm-content': { mount: NO_DATA }
148
+ };
149
+ export const eventPayloadNote = "Olay yükü motorda komponentin KENDİ prop'una yazılır (FlowMachine.onEmit → setNode) ve akışta " +
150
+ "self.<anahtar> ile okunur — payload anahtarları aynı zamanda o prop'ların adıdır. " +
151
+ "event.data komponent olaylarında BOŞ gelir: motor akışı emit'in params'ıyla başlatır ve " +
152
+ "event.data = params.data'dır (yalnız html actions/fireEvent bu yoldan doldurur). " +
153
+ "payload boşsa olay veri taşımaz; 'reads' verilmişse değer yükte değil komponentin başka bir prop'undadır. " +
154
+ "self yerine value { type:'property', ref:{ source:'component', element:'<elementId>', property:'<prop>' } } de kullanılabilir. " +
155
+ "payload alanı yoksa yük sözlüğe henüz işlenmemiştir; tahmin etmeyin.";
156
+ export function eventContractsFor(slug, names) {
157
+ const contracts = slug ? componentEventContracts[slug] : undefined;
158
+ return names.map(name => {
159
+ const contract = contracts?.[name];
160
+ if (!contract)
161
+ return { name };
162
+ return { name, payload: contract.payload, ...(contract.reads ? { reads: contract.reads } : {}) };
163
+ });
164
+ }