@devoplus/one-sdk 0.2.0-next.112 → 0.2.0-next.117

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 (2) hide show
  1. package/README.md +43 -44
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -5,8 +5,7 @@ servislerine **ince istemcisi**. SDK sır taşımaz, kiracı seçmez ve
5
5
  belirteç üretmez: kimliği platform kapısının yazdığı başlıklardan **okur**, backend'e kullanıcının uygulama
6
6
  belirteciyle gider, dosyayı kuruluma bağlı dosya deposuna yazar.
7
7
 
8
- Platformun tamamı: `devoplus/devoplus-one` (mimari `docs/architecture.md`); kararlar
9
- `devoplus-root/docs/devoplus-one-karar-defteri.md`; örnek uygulama `apps/hello`.
8
+ Platformun tamamı: `devoplus/devoplus-one` (mimari `docs/architecture.md`, örnek uygulama `apps/hello`).
10
9
 
11
10
  ## Kurulum
12
11
 
@@ -23,23 +22,23 @@ Paket yalnız **ESM** dağıtılır (`dist/index.js` + `dist/index.d.ts`); Node
23
22
 
24
23
  ### Yerel geliştirme: `one` komutu
25
24
 
26
- Paket `one` komutunu da getirir (D-72); uygulamanın kök dizininde çalışır ve `one.manifest.json`'u okur:
25
+ Paket `one` komutunu da getirir; uygulamanın kök dizininde çalışır ve `one.manifest.json`'u okur:
27
26
 
28
27
  | Komut | Ne yapar |
29
28
  |---|---|
30
29
  | `one dev [--port n] [--api-base url]` | Uygulamayı yerelde çalıştırır. Devoplus servisleri varsayılan olarak test ortamındadır (`ONE_API_BASE` ile değişir). İstekler Portal'dan geçmediği için kimlik başlıklarını (`X-One-*`) elle gönderirsiniz. |
31
30
  | `one migrate` | `migrations/` altındaki SQL dosyalarını **yerel** veritabanına uygular (`one dev` aynı veriyi görür). |
32
31
  | `one build` | Yükleme provası: kodu paketler, hiçbir yere göndermez (çıktı `.one/dist/`). |
33
- | `one data generate [--check]` | `one.data.json` veri modelinden yeni migration + `src/data/types.ts` üretir; yalnız ekleyen değişiklik ([Veri modeli](#veri-modeli-ve-kayıt-işlemleri-d-84-️-geliştirici-onayı-bekliyor)). |
32
+ | `one data generate [--check]` | `one.data.json` veri modelinden yeni migration + `src/data/types.ts` üretir; yalnız ekleyen değişiklik ([Veri modeli](#veri-modeli-ve-kayıt-işlemleri)). |
34
33
 
35
34
  Yerel yapılandırma ve veri `.one/` altındadır, depoya girmez ve her komutta manifest'ten yeniden üretilir. Gerçek
36
35
  yükleme Devoplus GitLab hattıyla yapılır; geliştirici makinesinden yükleme yoktur. Komutun ekrana yazdığı ayrıntılar
37
36
  (araç adı, sürüm satırı) yerel çalışma ortamına aittir ve gizlenmez.
38
37
 
39
- ### Erişim talebi: `one login`, `one request`, `one requests` (D-75)
38
+ ### Erişim talebi: `one login`, `one request`, `one requests`
40
39
 
41
40
  Uygulamanız bir kuruluma, DEXA sorgusuna, uygulama izni atamasına ya da yetki alanına ihtiyaç duyduğunda izni
42
- yöneticiden komut satırından isteyebilirsiniz. Talep izni kendiliğinden VERMEZ; yönetici Admin Console'da onaylar ve
41
+ yöneticiden komut satırından isteyebilirsiniz. Talep izni kendiliğinden VERMEZ; yönetici Devoplus Console'da onaylar ve
43
42
  sonuç size e-postayla bildirilir.
44
43
 
45
44
  | Komut | Ne yapar |
@@ -55,7 +54,7 @@ One.Hello.Manage="Yönetir"` (tekrar edilebilir, en çok 16; İngilizce ad `--pe
55
54
  portalın şirket yöneticisi, yetki alanı talebini platform yöneticisi onaylar. Kayıt talebi dışındaki türleri yalnız uygulamanın sahibi gönderebilir. Vekalet ya da Yerine Görüntüle oturumuyla talep
56
55
  gönderilemez. Aynı istemci Devoplus One MCP sunucusunda da kullanılır (`@devoplus/one-sdk/access-request`).
57
56
 
58
- ### Yayın ve kullanım panosu: `one publish`, `one promote`, `one rollback`, `one deployments`, `one status` (D-86, D-87)
57
+ ### Yayın ve kullanım panosu: `one publish`, `one promote`, `one rollback`, `one deployments`, `one status`
59
58
 
60
59
  Kod yine bu bilgisayardan yüklenmez: komut Devoplus'a bir **yayın isteği** bırakır, Devoplus isteği kaydeder ve yayın
61
60
  hattını kendisi başlatır; hattın kapılarının hiçbiri atlanmaz. Komutlar `one login` oturumuyla çalışır; uygulamanın
@@ -74,8 +73,8 @@ kısa adı `one.manifest.json`'dan okunur (`--app` ile değişir), `--json` ham
74
73
  sayısı istek gönderilmeden denetlenir; tanınmayan bir seçenek (`--portl`) açık hatadır.
75
74
  - Yanıt *"Yayın hattı bu ortamda yapılandırılmamış"* ya da *"Kullanım ve hata panosu bu ortamda yapılandırılmamış"*
76
75
  ise o ortamda bu özellik henüz kullanılamıyor demektir.
77
- - Aynı istemci Devoplus One MCP sunucusunun `one_publish`, `one_deployments` ve `one_app_health` araçlarında da
78
- kullanılır (`@devoplus/one-sdk/app-ops`).
76
+ - Aynı istemci Devoplus One MCP sunucusunun yayın ve kullanım panosu araçlarında da kullanılır
77
+ (`@devoplus/one-sdk/app-ops`).
79
78
 
80
79
  ## Hızlı başlangıç
81
80
 
@@ -128,20 +127,20 @@ export default {
128
127
  |---|---|
129
128
  | `readContext(headers): OneContext` | `X-One-App`, `X-One-Portal-Key`, `X-One-Portal`, (`X-One-Auth=user` ya da kuyruk işinde `job` + `X-One-Sub`, `X-One-Scope`, `X-One-Global-Admin`, `X-One-Permissions`, `X-One-Admin`). Üç kurulum başlığından biri yoksa `ONE-SDK-E-001` (500): istek dispatch üzerinden gelmemiştir. |
130
129
  | `OneContext` | `{ app, portalKey, portalId, user: OneUser \| null, actor?: OneActor \| null, mode?, admin?, jobServices? }`. `portalId` kiracıdır (24-hex); veri her zaman buna bağlıdır. `mode`: `'user'` (kullanıcının isteği), `'job'` (kuyruk / zamanlanmış iş), `'agent'` (Devoplus ajanının araç çağrısı). `admin` = `user.admin` (oturumsuzda ve işte `false`). `jobServices`: işte manifest `jobs.services` beyanı, diğer yollarda boş. |
131
- | `OneActor`, `isActingSession(ctx)` | Vekalet / Yerine Görüntüle oturumu (D-76 U3; `X-One-Actor-Sub` + `X-One-Session-Kind`): `{ sub, kind: 'delegation' \| 'impersonation' }`. `user.sub` adına çalışılan kişidir (veri onundur), `actor.sub` oturumu kullanan kişidir; "kim yaptı" kaydına bu yazılır. Kendi oturumunda `null`. ⛔ Bu oturumlar varsayılan **salt-okunurdur**: platform GET/HEAD dışındaki isteği uygulamaya ulaşmadan **403 `ONE-DSP-E-009`** ile reddeder; uygulama manifest'te `"actingSessions": "write"` beyan ederse yazma isteği geçer. |
132
- | `OneUser` | `{ sub, scope: readonly string[], globalAdmin, permissions: readonly string[], admin }`. `sub` devoplus-auth kimlik uzayıdır (`UserAccount._id`), Organization Schema `User._id` DEĞİLDİR. `permissions` yalnız bu uygulamanın ad alanındaki (`One.<Uygulama>.*`) izinlerdir (D-49); `admin` = şirket ya da küresel yönetici rolü. |
130
+ | `OneActor`, `isActingSession(ctx)` | Vekalet / Yerine Görüntüle oturumu (`X-One-Actor-Sub` + `X-One-Session-Kind`): `{ sub, kind: 'delegation' \| 'impersonation' }`. `user.sub` adına çalışılan kişidir (veri onundur), `actor.sub` oturumu kullanan kişidir; "kim yaptı" kaydına bu yazılır. Kendi oturumunda `null`. ⛔ Bu oturumlar varsayılan **salt-okunurdur**: platform GET/HEAD dışındaki isteği uygulamaya ulaşmadan **403 `ONE-DSP-E-009`** ile reddeder; uygulama manifest'te `"actingSessions": "write"` beyan ederse yazma isteği geçer. |
131
+ | `OneUser` | `{ sub, scope: readonly string[], globalAdmin, permissions: readonly string[], admin }`. `sub` devoplus-auth kimlik uzayıdır (`UserAccount._id`), Organization Schema `User._id` DEĞİLDİR. `permissions` yalnız bu uygulamanın ad alanındaki (`One.<Uygulama>.*`) izinlerdir; `admin` = şirket ya da küresel yönetici rolü. |
133
132
  | `requireUser(ctx): OneUser` | anonimse `ONE-SDK-E-002` (401). |
134
133
  | `requireScope(ctx, scope): OneUser` | belirteçte scope yoksa `ONE-SDK-E-003` (403). Onaya bağlı scope'ta metin kullanıcıya izni nereden vereceğini de söyler. |
135
134
  | `requireServiceScope(ctx, scope)` | Devoplus servisinin yerel kapısı, üç yolu ayırır (bkz. "Devoplus servisleri arka plan işinde ve ajan aracında"): kullanıcıda `requireScope`; ajan aracında süreli onay gerektiren scope'lar hiç kullanılamaz; işte kullanıcı gerekmez, scope `jobs.services`'te beyanlı olmalı. İhlal `ONE-SDK-E-003` (403); asıl karar sunucudadır. |
136
- | `CONSENT_SCOPES`, `awaitsUserConsent(ctx, scope): boolean` | Kullanıcının **ayrıca ve süreli** onay vermesi gereken scope'lar (D-59): `dexa.write`, `mail.execute`, `sms.execute` ve `push.execute`. `awaitsUserConsent` scope onaya bağlıysa ve belirteçte yoksa `true` döner; ilgili düğmeyi kapatıp kullanıcıya "portaldaki İzinleri incele düğmesiyle izin verin" demek için. ⚠️ Manifest'te hiç beyan edilmemiş scope için de `true` döner (beyan uygulamanın bilgisidir). |
137
- | `hasPermission(ctx, code): boolean` | uygulama izni (D-49): kullanıcıda kod varsa ya da `admin` ise `true` (backend'in yönetici baypasıyla aynı); anonimde `false`. Kod manifest `permission`/`permissions` içinde beyan edilir, atamayı portal yöneticisi Yetki Yönetimi'nde kullanıcı gruplarına (org düğümlerine) yapar. ⚠️ Ad alanı süzgeci bir kolaylıktır, gizlilik sınırı değildir: `Authorization` belirteci kullanıcının bütün izinlerini taşır. |
135
+ | `CONSENT_SCOPES`, `awaitsUserConsent(ctx, scope): boolean` | Kullanıcının **ayrıca ve süreli** onay vermesi gereken scope'lar: `dexa.write`, `mail.execute`, `sms.execute` ve `push.execute`. `awaitsUserConsent` scope onaya bağlıysa ve belirteçte yoksa `true` döner; ilgili düğmeyi kapatıp kullanıcıya "portaldaki İzinleri incele düğmesiyle izin verin" demek için. ⚠️ Manifest'te hiç beyan edilmemiş scope için de `true` döner (beyan uygulamanın bilgisidir). |
136
+ | `hasPermission(ctx, code): boolean` | uygulama izni: kullanıcıda kod varsa ya da `admin` ise `true` (backend'in yönetici baypasıyla aynı); anonimde `false`. Kod manifest `permission`/`permissions` içinde beyan edilir, atamayı portal yöneticisi Yetki Yönetimi'nde kullanıcı gruplarına (org düğümlerine) yapar. ⚠️ Ad alanı süzgeci bir kolaylıktır, gizlilik sınırı değildir: `Authorization` belirteci kullanıcının bütün izinlerini taşır. |
138
137
  | `requirePermission(ctx, code): OneUser` | oturum yoksa 401, izin yoksa `ONE-SDK-E-004` (403). |
139
138
  | `OneError` | `status`, `code`, `message` (kullanıcıya görünen Türkçe metin). |
140
139
 
141
140
  Uygulama kodu `X-One-*` başlıklarını **asla kendisi yazmaz**; dispatch istemciden gelenleri siler ve belirteçten
142
141
  yeniden kurar.
143
142
 
144
- **Kullanıcı onayı (D-59, 16.10.2026).** ERP'ye veri yazma (`dexa.write`) ve kullanıcı adına e-posta/SMS/mobil bildirim
143
+ **Kullanıcı onayı.** ERP'ye veri yazma (`dexa.write`) ve kullanıcı adına e-posta/SMS/mobil bildirim
145
144
  (`mail.execute`, `sms.execute`, `push.execute`) manifest'te beyan edilmiş ve kullanıcının yetkisi olsa bile, kullanıcı bu uygulamaya
146
145
  **o portalda** ayrıca onay vermeden belirtece girmez. Onay bir kez verilir, **30 gün** geçerlidir; portal uygulamanın
147
146
  üstünde bir uyarı ve "İzinleri incele" düğmesi gösterir, onay devoplus-auth ekranında verilir ve oradaki "Yetkili
@@ -150,7 +149,7 @@ yüzden bu işleri yapan rotalar `requireScope` ile korunmalı, arayüz `awaitsU
150
149
  yönlendirme yazabilir. Onay kaldırılınca sonraki her belirteç hassas scope'u taşımaz (devoplus-auth onayı güçlü tutarlı
151
150
  bir Durable Object'te tutar); daha önce verilmiş belirteç iptal edilmez, en çok ömrü kadar (10 dk) geçerli kalır.
152
151
 
153
- ## Portal köprüsü ve görsel dil (D-76)
152
+ ## Portal köprüsü ve görsel dil
154
153
 
155
154
  Uygulama sayfası Portal'da iframe içinde açılır. Sayfa üç dosyayı **kendi** adresinden yükler; satır içi betik
156
155
  platformda kapalıdır (`script-src 'self'`) ve `one-ci validate` satır içi ya da harici (`https://...`) betiği yayından önce
@@ -176,9 +175,9 @@ if (url.pathname === '/shell.js') return scriptResponse(renderShellScript(NAVIGA
176
175
 
177
176
  | Sunucu üyesi | Açıklama |
178
177
  |---|---|
179
- | `clientAssetResponse(pathname): Response \| null` | `/one-bridge.js` (`ONE_BRIDGE_SCRIPT`, `text/javascript`), `/one-components.js` (`ONE_COMPONENTS_SCRIPT`, hazır bileşenler, D-83) ve `/one-ui.css` (`ONE_UI_CSS`, `text/css`); başka yolda `null`. |
178
+ | `clientAssetResponse(pathname): Response \| null` | `/one-bridge.js` (`ONE_BRIDGE_SCRIPT`, `text/javascript`), `/one-components.js` (`ONE_COMPONENTS_SCRIPT`, hazır bileşenler) ve `/one-ui.css` (`ONE_UI_CSS`, `text/css`); başka yolda `null`. |
180
179
  | `scriptResponse(body)` | Sayfa betiği için doğru içerik türüyle yanıt. |
181
- | `navigationFromManifest(manifest)` | Manifest `navigation` alanı: bozuk/yinelenen öğe atlanır, en çok `NAVIGATION_MAX_ITEMS` (12). Yol kuralı `ROUTE_PATH_RE` / `isRoutePath` (manifest şemasıyla aynı). Sekme izni (`permission`, S10) korunur; biçimi bozuk izinli öğe atlanır. |
180
+ | `navigationFromManifest(manifest)` | Manifest `navigation` alanı: bozuk/yinelenen öğe atlanır, en çok `NAVIGATION_MAX_ITEMS` (12). Yol kuralı `ROUTE_PATH_RE` / `isRoutePath` (manifest şemasıyla aynı). Sekme izni (`permission`) korunur; biçimi bozuk izinli öğe atlanır. |
182
181
  | `visibleNavigation(items, access)` | Kişinin görebildiği sekmeler (`access`: `{ permissions, admin }` ya da `null` = yalnız izinsiz sekmeler); dönen öğeler izin kodu taşımaz. |
183
182
 
184
183
  Tarayıcıdaki `window.one` (tip: `OneBridge`):
@@ -186,7 +185,7 @@ Tarayıcıdaki `window.one` (tip: `OneBridge`):
186
185
  | Üye | İleti | Açıklama |
187
186
  |---|---|---|
188
187
  | `one.start({ navigation })` | `one:ready` + `one:navigation` | Sayfa hazır olunca **bir kez**; yükseklik bildirimini de başlatır (`one:resize`). Menü sözleşmeye uymuyorsa fırlatır. İzinli sekmeler (`permission`) erişim bildirilene kadar gönderilmez. |
189
- | `one.setNavigationAccess({ permissions, admin })` | `one:navigation` | Oturumdaki kişinin uygulama izinleri (S10): görebildiği izinli sekmeler menüye eklenir (menü değiştiyse ileti yeniden gönderilir; Portal son iletiyi geçerli sayar). Yönetici her sekmeyi görür. Oturum bilgisini okuyunca çağırın (`GET /api/session`). |
188
+ | `one.setNavigationAccess({ permissions, admin })` | `one:navigation` | Oturumdaki kişinin uygulama izinleri: görebildiği izinli sekmeler menüye eklenir (menü değiştiyse ileti yeniden gönderilir; Portal son iletiyi geçerli sayar). Yönetici her sekmeyi görür. Oturum bilgisini okuyunca çağırın (`GET /api/session`). |
190
189
  | `one.token`, `one.onToken(fn)`, `one.fetch(yol, init)` | `one:token` | Belirteç yalnız Portal'dan gelir; `one.fetch` `Authorization: Bearer ...` ekler. |
191
190
  | `one.context`, `one.onContext(fn)`, `one.actor` | `one:context` | `{ theme, lang, autoHeight, actor: { kind } \| null, design }`. Köprü `data-theme`'i köke yazar, tasarım değerlerini (`primary`, `primaryContrast`, `fontFamily`, `radius`; biçimi tutmayan değer yazılmaz) `--one-primary` ve benzeri değişkenlere geçirir, `autoHeight` gelince sayfanın kendi dikey taşmasını gizler (yatay taşma kaydırılabilir kalır; yatay kaydırma çubuğu bildirilen yüksekliğe eklenir). `one.actor` yalnız gösterim içindir; yazma kapısı sunucudadır. |
192
191
  | `one.onNavigate(fn)`, `one.path` | `one:navigate` | Portal sekmesine tıklandı; görünümü değiştirin. Adres geçmiş kaydı eklenmeden güncellenir; geri bildirim gönderilmez. |
@@ -210,7 +209,7 @@ sınıflar: `one-btn` (`-primary`, `-danger`, `-text`), `one-field` + `one-label
210
209
  `-error`), içerik sekmeleri `one-tabs` + `one-tab` (`aria-selected`), `one-row`, `one-stack`, `one-muted`, `one-empty`,
211
210
  `one-loading`, `one-sr-only`. ⚠️ `one-tabs` içerik içi gruplama içindir; uygulama menüsünü Portal çizer.
212
211
 
213
- ## Hazır arayüz bileşenleri (D-83)
212
+ ## Hazır arayüz bileşenleri
214
213
 
215
214
  Liste, form, süzgeç, kişi seçimi, dosya yükleme ve grafik için hazır bileşenler `/one-components.js`'tedir. Bileşenler
216
215
  bağımlılıksızdır, uygulamanın **kendi** adresinden yüklenir (satır içi betik gerekmez), `/one-ui.css` görsel dilini
@@ -328,7 +327,7 @@ Backend "kullanıcı yetkisi ∩ scope" kuralını kendisi uygular; SDK ek bir y
328
327
 
329
328
  ## Dosya servisi
330
329
 
331
- Manifest'te `services.files: true` ise platform kurulum başına bir dosya deposu açar ve `env.FILES`'a bağlar (D-32).
330
+ Manifest'te `services.files: true` ise platform kurulum başına bir dosya deposu açar ve `env.FILES`'a bağlar.
332
331
  İzolasyon depo sınırındadır: anahtara `portalId` eklenmez, başka kurulumun deposu görünmez.
333
332
 
334
333
  | Üye | Açıklama |
@@ -343,7 +342,7 @@ Manifest'te `services.files: true` ise platform kurulum başına bir dosya depos
343
342
 
344
343
  ## Önbellek servisi
345
344
 
346
- Manifest'te `services.cache: true` ise platform kurulum başına bir önbellek açar ve `env.CACHE`'e bağlar (D-35). İzolasyon
345
+ Manifest'te `services.cache: true` ise platform kurulum başına bir önbellek açar ve `env.CACHE`'e bağlar. İzolasyon
347
346
  önbellek sınırındadır. Bu bir **önbellektir**: nihai tutarlıdır (yazma başka bölgelerde 60 sn'ye kadar gecikebilir).
348
347
  Sayaç, kilit ya da kalıcı kayıt için kullanılmaz; kalıcı veri veritabanındadır.
349
348
 
@@ -367,9 +366,9 @@ yalnız hiçbir ileti kuyruğa girmez **ve** atlananların tamamı `rate-limited
367
366
  girmeyen istek **200** + `queued: 0` alır. Sonucu `skipped[].reason` ile denetleyin (backend `OneServiceHandlers`,
368
367
  okundu 15.10.2026).
369
368
 
370
- **Org kimliğiyle alıcı (D-47):** `toOrgUserIds` alanı org şemasındaki kullanıcı kimliğini (legacy `User._id`, 24-hex) kabul eder. Yönetici zinciri ve grup üyeleri bu uzayda geldiği için onlara `sub` bulmadan bildirim gönderilebilir. `toSubjects` ile birlikte verilebilir; toplam alıcı en çok 50'dir, aynı kişi iki kez sayılmaz. Biçimi bozuk org kimliği `invalid-org-user`, portalın aktif kullanıcısı olmayan kimlik `not-in-portal` ile atlanır. ⛔ İki kimlik uzayını karıştırmayın: `ctx.user.sub` org kimliği DEĞİLDİR (ikisi de 24-hex; karışırsa hata vermez, kişi `not-in-portal` ile sessizce atlanır).
369
+ **Org kimliğiyle alıcı:** `toOrgUserIds` alanı org şemasındaki kullanıcı kimliğini (legacy `User._id`, 24-hex) kabul eder. Yönetici zinciri ve grup üyeleri bu uzayda geldiği için onlara `sub` bulmadan bildirim gönderilebilir. `toSubjects` ile birlikte verilebilir; toplam alıcı en çok 50'dir, aynı kişi iki kez sayılmaz. Biçimi bozuk org kimliği `invalid-org-user`, portalın aktif kullanıcısı olmayan kimlik `not-in-portal` ile atlanır. ⛔ İki kimlik uzayını karıştırmayın: `ctx.user.sub` org kimliği DEĞİLDİR (ikisi de 24-hex; karışırsa hata vermez, kişi `not-in-portal` ile sessizce atlanır).
371
370
 
372
- ### Mobil bildirim (D-55; ⚠️ geliştirici onayı bekliyor)
371
+ ### Mobil bildirim
373
372
 
374
373
  `sendPush(api, { toSubjects, toOrgUserIds?, title, text })`, `POST One/services/push` ucunu çağırır; scope `push.execute`. Devoplus
375
374
  Portal mobil uygulamasına **yalnız başlık + metin** gider (başlık 1-100, metin 1-300 karakter; bu sınırı sunucu uygular, SDK
@@ -379,7 +378,7 @@ Portal mobil uygulamasına **yalnız başlık + metin** gider (başlık 1-100, m
379
378
  ⚠️ Push bugün **hiçbir ortamda açık değildir**: uç kuyruğa almadan `OneError` `ONE-APP-E-029` ile reddeder (kapalı
380
379
  kanal sessiz başarı gibi görünmesin). Kodunuz bu hatada çalışmayı sürdürmeli; `notify` kanalları bağımsız gönderir.
381
380
 
382
- ### Hazır bildirim senaryoları (D-47)
381
+ ### Hazır bildirim senaryoları
383
382
 
384
383
  `approvalRequest`, `approvalResult`, `reminder`, `systemNotice`, `operationResult`, `verificationCode` aynı girdiden e-posta konusu + gövdesi ve SMS metni üretir (`ScenarioMessage { subject, text, smsText }`; Türkçe resmi "siz" ya da `lang: 'en'`). Metinler backend sınırlarına göre kırpılır (konu ≤ 200, SMS ≤ 300; e-posta gövdesi 10.000'i aşarsa `ONE-SDK-E-062`). Bağlantı yalnız `https` olabilir ve kullanıcı adı/parola taşıyamaz (`normalizeLink`, `ONE-SDK-E-061`). `notify(api, message, { toSubjects?, toOrgUserIds?, channels })` kanalları (`mail`, `sms`, `push`) **bağımsız** gönderir: SMS ya da push düşse de e-posta gider; sonuç kanal adıyla döner, düşen kanal `{ error }` taşır. `toPush(message, to)` başlığı e-posta konusundan (≤ 100, `PUSH_TITLE_MAX_LENGTH`), metni SMS metninden (≤ 300, `PUSH_TEXT_MAX_LENGTH`) kurar; kırpma bir emojiyi ortasından bölmez.
385
384
 
@@ -397,11 +396,11 @@ if (me) {
397
396
  }
398
397
  ```
399
398
 
400
- ### Doğrulama kodu (D-47)
399
+ ### Doğrulama kodu
401
400
 
402
401
  `generateVerificationCode(digits = 6)` (4-10 hane, yanlılıksız); `generateSalt()`; `hashVerificationCode({ code, salt, purpose, sub })`; `verificationCodeMatches({ ..., hash })` (sabit süreli karşılaştırma). Özet **amaca ve kişiye** bağlıdır: başka bir işlem ya da başka bir kişi için üretilmiş kod kabul edilmez. Kodun kendisini değil `salt + hash + son kullanma + deneme sayısı`nı uygulamanın **veritabanında** saklayın (önbellek nihai tutarlıdır; deneme sayacı ve tek kullanım orada güvenilir değildir). Süreyi ve deneme tavanını (ör. 5) uygulama uygular; doğru koddan sonra kaydı silin.
403
402
 
404
- ## Organizasyon şeması (D-47)
403
+ ## Organizasyon şeması
405
404
 
406
405
  Scope `orgschema.read` (salt okuma) + kullanıcının kendi `Portal.Generic.Read` izni. Veri aktif portalın aktif kayıtlarıdır.
407
406
 
@@ -418,9 +417,9 @@ Saf yardımcılar (ağ yok): `managerOf(users, orgUserId, kind?)`; `approvalChai
418
417
  ## DEXA (ERP okuma) servisi
419
418
 
420
419
  `queryDexa(api, key, parameters?)`, `POST One/services/dexa/query` ucunu çağırır. Uygulama ERP verisini **yalnız önceden tanımlı
421
- QueryStore anahtarlarıyla** okur (D-09; uç D-42, ⚠️ geliştirici onayı bekliyor): serbest SQL, ERP'ye yazan anahtar ya
420
+ QueryStore anahtarlarıyla** okur: serbest SQL, ERP'ye yazan anahtar ya
422
421
  da desteklenmeyen sorgu türü çalıştırılamaz. Hangi anahtarın çalışabileceğinin **tek kaynağı platform kayıt
423
- defteridir**: anahtarları Admin Console'da uygulamanın kaydına yönetici ekler; kayıtta olmayan anahtar 403
422
+ defteridir**: anahtarları Devoplus Console'da uygulamanın kaydına yönetici ekler; kayıtta olmayan anahtar 403
424
423
  `ONE-APP-E-024` alır. Manifest `services.dexa.queryKeys` yalnız **beyandır** (çalışma anında okunmaz) ve `scopes`
425
424
  içinde `dexa.read` ile birlikte yazılır; biri eksikse manifest doğrulaması düşer. Belirteçte `dexa.read` yoksa
426
425
  backend 403 `ONE-APP-E-017` döner.
@@ -473,7 +472,7 @@ başına saatte 600 sorgu); 400 `ONE-APP-E-076` (gönderilen bağlam kodu geçer
473
472
  karakteri içeriyor); 403 `ONE-APP-E-077` (gönderilen `UserCode` ya da `CompanyCode` kurulumun portalında tanımlı değil);
474
473
  400 `ONE-APP-E-078` (arka plan işinde sorgu bir bağlam kodu istiyor ve uygulama onu göndermedi).
475
474
 
476
- ### Bağlam kodları: `UserCode`, `CompanyCode`, `CostCenterCode` (C7)
475
+ ### Bağlam kodları: `UserCode`, `CompanyCode`, `CostCenterCode`
477
476
 
478
477
  Sorgu bu kodlardan birini bildiriyorsa değer şu sırayla belirlenir:
479
478
 
@@ -498,14 +497,14 @@ Sorgu bu kodlardan birini bildiriyorsa değer şu sırayla belirlenir:
498
497
  const stock = await queryDexa(api, 'Ornek.MagazaStok', { CompanyCode: '01', StoreCode: storeCode })
499
498
  ```
500
499
 
501
- ## DEXA işlemleri: ERP'ye veri yazma (D-56; ⚠️ geliştirici onayı bekliyor)
500
+ ## DEXA işlemleri: ERP'ye veri yazma
502
501
 
503
502
  `runDexaCommand(api, key, parameters, { idempotencyKey })`, `POST One/services/dexa/command` ucunu `Idempotency-Key`
504
503
  başlığıyla çağırır; `getDexaCommandStatus(api, idempotencyKey)` ise `GET One/services/dexa/command/{anahtar}` ucunu. Scope **`dexa.write`**.
505
504
  Okuma sorgularından (`queryDexa`) ayrıdır: bu uç ERP'ye **VERİ YAZAR**. Çalışması dört kapının kesişimidir:
506
505
 
507
506
  1. Belirteçte `dexa.write` (yoksa 403 `ONE-APP-E-017`).
508
- 2. Anahtar uygulamanın kayıt defterindeki işlem izin listesinde (`dexaCommandKeys`, Admin Console; yoksa 403 `ONE-APP-E-030`).
507
+ 2. Anahtar uygulamanın kayıt defterindeki işlem izin listesinde (`dexaCommandKeys`, Devoplus Console; yoksa 403 `ONE-APP-E-030`).
509
508
  3. Anahtar koddaki ERP komut kataloğunda **One uygulamalarına açık** (yoksa 404 `ERPCMD-APP-E-006`; açmak backend kod
510
509
  değişikliğidir; ⚠️ bugün açık hiçbir işlem yoktur).
511
510
  4. Kullanıcının o işleme özgü izni (yoksa 403 `ERPCMD-APP-E-0xx`).
@@ -568,10 +567,10 @@ Sorgulardaki ayrılmış bağlam parametresi yasağı (`LangCode` vb.) işlemler
568
567
  uygulamıyor. 4xx yanıtların hepsi ERP'ye **hiçbir şey gönderilmediği** anlamına gelir; ayrıca 429 `ONE-APP-E-018`
569
568
  (kurulum başına saatte 300 işlem).
570
569
 
571
- ## Zamanlanmış görev ve kuyruk (D-80)
570
+ ## Zamanlanmış görev ve kuyruk
572
571
 
573
572
  Uygulama işi manifest `jobs` ile **beyan eder** ve işleyicisini yazar; işi platform tetikler. Ayrıntı ve örnek:
574
- ajan belgesi `/docs/jobs.md`; manifest kuralları `docs/manifest.md` içindeki `jobs` bölümünde.
573
+ belgelerdeki `/docs/jobs` sayfası; manifest kuralları `/docs/manifest` sayfasındaki `jobs` bölümünde.
575
574
 
576
575
  | Üye | Açıklama |
577
576
  |---|---|
@@ -587,7 +586,7 @@ taşınmaz. Zamanlanmış iş kullanıcısızdır (`ctx.user` null). İkisinde d
587
586
  çağrılır (bkz. aşağıdaki bölüm). `/__one/` yolu platforma ayrılmıştır ve internetten kapalıdır. Yerelde (`one dev`) zamanlama
588
587
  tetiklenmez ve `enqueue` 503 döner.
589
588
 
590
- ## Devoplus servisleri arka plan işinde ve ajan aracında (C6)
589
+ ## Devoplus servisleri arka plan işinde ve ajan aracında
591
590
 
592
591
  İşte ve ajan aracında tarayıcıdan gelen bir belirteç yoktur; servis istemcileri (`BackendClient`) yine de çağrı yapar:
593
592
  platform çıkış katmanı isteği doğru kimlikle Devoplus'a taşır (`new BackendClient({ baseUrl, authorization: null })` ya
@@ -610,9 +609,9 @@ Devoplus'a **iletilmez**.
610
609
  `logEvent(ctx, level, message, data?)` sistem/çalışma zamanı olayı; `logError(ctx, message, error, data?)` beklenmeyen
611
610
  hata (ad, ileti ve en çok 4.000 karakterlik yığın; `OneError` kodu ve durumu korunur); `logAudit(ctx, action, target?,
612
611
  data?)` kritik kullanıcı işlemi; aktör zorunludur (anonim bağlamda fırlatır). Hepsi tek satır JSON olarak yazılır ve
613
- **platform günlüğünde saklanır**: platform her kurulumda günlüğü açar (D-45), örnekleme manifest
612
+ **platform günlüğünde saklanır**: platform her kurulumda günlüğü açar, örnekleme manifest
614
613
  `observability.headSamplingRate` (varsayılan 1). Satırları platform ekibi kurulum (uygulama × portal) süzgeciyle
615
- görür; uygulama geliştiricisine açık bir görüntüleme ekranı bu sürümde yoktur.
614
+ görür; uygulamanın son hata kayıtları kısaltılmış olarak kullanım ve hata panosunda görünür (`one status`).
616
615
 
617
616
  Koruma: `data` içinde adı parola, token, secret, authorization, cookie, API anahtarı, private key, credential ya da
618
617
  parola/şifre geçen alanların değeri `"[gizli]"` olur (her derinlikte, girdi değişmez; `redact`); JSON'u 8 KiB'ı aşan
@@ -624,7 +623,7 @@ metin döner.
624
623
  ## Denetim günlüğü (kalıcı)
625
624
 
626
625
  `recordAudit(api, ctx, action, target?, data?)`, `logAudit` izini yazar **ve** `POST One/services/audit` ile
627
- Devoplus denetim günlüğüne kaydeder (scope `audit.write`; D-36). Kayıt Admin Console Denetim Günlüğü'nde "Devoplus
626
+ Devoplus denetim günlüğüne kaydeder (scope `audit.write`). Kayıt Devoplus Console Denetim Günlüğü'nde "Devoplus
628
627
  One uygulaması" türüyle, `reason = {slug}:{action}`, `targetLabel = target`, `details = data` olarak görünür; aktör
629
628
  ve portal istekle gönderilmez, backend doğrulanmış bağlamdan alır. Kurallar sunucuyla birebir: `action`
630
629
  `^[a-z0-9][a-z0-9._:-]*$` ≤ 64, `target` ≤ 200, `data` JSON nesnesi ≤ 4 KiB (`buildAuditRequest`; ihlal
@@ -632,7 +631,7 @@ ve portal istekle gönderilmez, backend doğrulanmış bağlamdan alır. Kuralla
632
631
  `{ recorded: false }` + uyarı olayı döner, isteğiniz düşmez. ⛔ `target`/`data`ya kişisel veri ya da sır yazmayın
633
632
  (365 gün saklanır).
634
633
 
635
- ## Yapay zeka servisi (D-88 a; ⚠️ öneri, geliştirici onayı bekliyor)
634
+ ## Yapay zeka servisi
636
635
 
637
636
  `completeAi(api, ctx, istek)` (eşdeğeri `ai.complete`), `POST One/services/ai` ucunu çağırır (scope `ai.use`; kullanıcıdan ayrıca
638
637
  onay istenmez). Diğer `One/services/*` uçlarıyla aynı kapıdan geçer; kullanıcı, portal ve uygulama istekle GÖNDERİLMEZ.
@@ -658,7 +657,7 @@ olup olmadığı Devoplus'tadır: kapalı/yapılandırılmamış portalda 503, k
658
657
  hesaplamaz** ve **kayıt yazmaz**: tutar/toplam/tarih farkı kodda hesaplanıp `input`'a hazır verilir; çıktı bir öneridir,
659
658
  veritabanına yazmadan önce kod doğrular. `input`'a sır ya da işin gerektirmediği kişisel veri konmaz.
660
659
 
661
- ## Devoplus yapay zekasına açılan araçlar (D-88 b; ⚠️ öneri, geliştirici onayı bekliyor)
660
+ ## Devoplus yapay zekasına açılan araçlar
662
661
 
663
662
  Devoplus yapay zekası, kullanıcı Devoplus'ta bir soru sorduğunda uygulamanın verisine ve işlemlerine yalnız manifest
664
663
  `agent.tools[]` ile beyan edilen **araçlarla**, kullanıcının kendi kimliğiyle ulaşır. Her araç üç yerde durur: manifest
@@ -700,7 +699,7 @@ Girdi şeması JSON Schema'nın dar bir alt kümesidir: `type` (`object`, `strin
700
699
  `app: { slug, name }` + `agent`) ve `GET /.well-known/one-agent.md` (`AGENT_GUIDE.md`, ≤ 256 KiB) sunar; manifest'te
701
700
  `agent` yoksa 404. Rehbere kullanıcı verisi, sır ya da iç adres yazılmaz.
702
701
 
703
- ## Veri modeli ve kayıt işlemleri (D-84; ⚠️ geliştirici onayı bekliyor)
702
+ ## Veri modeli ve kayıt işlemleri
704
703
 
705
704
  Kayıt tutan uygulamada tabloyu, tipleri ve uçları elle yazmak yerine `one.data.json`'da **varlıkları ve alanları**
706
705
  tanımlayın; gerisini `one data generate` ve `createCrudHandler` yapar.
@@ -791,7 +790,7 @@ modelden seçilir.
791
790
  bulunur. ⚠️ Bir metin alanını **elle yazdığınız SQL ile güncelliyorsanız** arama kolonunu da yazın
792
791
  (`"<alan>_fold" = ?` + `foldSearchText(değer)`) ya da `NULL` yapın; yoksa arama eski metne göre bulur.
793
792
 
794
- ## Rapor ve dışa aktarma (D-85; ⚠️ geliştirici onayı bekliyor)
793
+ ## Rapor ve dışa aktarma
795
794
 
796
795
  `toCsv(rows, columns, { lang, delimiter, timeZone })`; `toXlsx(rows, columns, { lang, sheetName, timeZone })`;
797
796
  `exportResponse(içerik, { fileName, format: 'csv' | 'xlsx' | 'html' })`; `renderPrintableReport({ title, subtitle,
@@ -814,8 +813,8 @@ columns, rows, totals, lang })`. Sütun: `{ key, title: { tr, en }, type?: 'text
814
813
  |---|---|---|
815
814
  | `ONE-SDK-E-001` | 500 | Platform bağlamı eksik (dispatch dışından çağrı) |
816
815
  | `ONE-SDK-E-002` | 401 | Oturum gerekli |
817
- | `ONE-SDK-E-003` | 403 | Scope yok (onaya bağlı scope'ta kullanıcı henüz izin vermemiş olabilir, D-59) |
818
- | `ONE-SDK-E-004` | 403 | Uygulama izni yok (`requirePermission`, D-49) |
816
+ | `ONE-SDK-E-003` | 403 | Scope yok (onaya bağlı scope'ta kullanıcı henüz izin vermemiş olabilir) |
817
+ | `ONE-SDK-E-004` | 403 | Uygulama izni yok (`requirePermission`) |
819
818
  | `ONE-SDK-E-010...013` | 400 | Dosya anahtarı / adı geçersiz |
820
819
  | `ONE-SDK-E-014` | 413 | Dosya boyut tavanı (`put` ve `readBoundedBody`) |
821
820
  | `ONE-SDK-E-015` | 500 | Dosya yazılamadı |
@@ -879,7 +878,7 @@ Backend'den dönen kodlar (`ONE-APP-E-*`, `USRDIR-*` vb.) `OneError.code` ile ol
879
878
  ## Sürümleme
880
879
 
881
880
  SemVer; `0.x` boyunca küçük sürüm artışı kırıcı olabilir; `CHANGELOG.md` **Kırıcı** başlığına bakın. Paket iki
882
- kanaldan otomatik yayımlanır (`Publish SDK (npm)` iş akışı, D-60 ve D-94):
881
+ kanaldan otomatik yayımlanır (`Publish SDK (npm)` iş akışı):
883
882
 
884
883
  | Kanal | Ne zaman | Sürüm | npm etiketi |
885
884
  |---|---|---|---|
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devoplus/one-sdk",
3
- "version": "0.2.0-next.112",
3
+ "version": "0.2.0-next.117",
4
4
  "description": "Devoplus One SDK — uygulamaların kimlik bağlamı, Devoplus servisleri, dosya ve önbellek depoları ile iletişim (e-posta/SMS/bildirim) istemcisi",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",