From 21fc481568d09b6d1f0631f07009ab36b4dc7d91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tayfun=20Y=C4=B1lmaz?= Date: Sun, 14 Jun 2026 20:40:57 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20v0.0.60=20release=20notes=20+=20T=C3=BC?= =?UTF-8?q?rk=C3=A7e=20migration=20rehberi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v0.0.60 sürümü için dokümantasyon: - Release v0.0.60 notları (blog/): sys-mappings/custom helpers, state alias, FunctionScope (403), production Swagger kapatma, async transition modları, schema 0.0.46. scripts.helpers örneği gerçek obje şekline düzeltildi. - Türkçe ayrıntılı Migration Rehberi (blog-migration/v0060-migration): 5 feature için ne değişti / migrasyon adımları / örnek + cross-link. - v0.0.55 "neler değişti" dokümanı Migration Guides bölümüne taşındı; eski /blog/v0055-neler-degisti URL'i için client-redirect eklendi (@docusaurus/plugin-client-redirects). - v0.0.55 release notundaki taşınan dosyaya işaret eden iç link güncellendi. npm run build başarılı; kırık link yok. Co-Authored-By: Claude Opus 4.8 --- .../2026-05-21-v0-0-55-duyuru.md | 0 .../2026-06-13-v0-0-60-migration.md | 252 ++++++++++++++++++ blog/2026-05-21-v0-0-55.md | 2 +- blog/2026-06-01-v0-0-58.md | 2 - blog/2026-06-13-v0-0-60.md | 153 +++++++++++ docusaurus.config.ts | 11 + package-lock.json | 25 ++ package.json | 1 + 8 files changed, 443 insertions(+), 3 deletions(-) rename {blog => blog-migration}/2026-05-21-v0-0-55-duyuru.md (100%) create mode 100644 blog-migration/2026-06-13-v0-0-60-migration.md create mode 100644 blog/2026-06-13-v0-0-60.md diff --git a/blog/2026-05-21-v0-0-55-duyuru.md b/blog-migration/2026-05-21-v0-0-55-duyuru.md similarity index 100% rename from blog/2026-05-21-v0-0-55-duyuru.md rename to blog-migration/2026-05-21-v0-0-55-duyuru.md diff --git a/blog-migration/2026-06-13-v0-0-60-migration.md b/blog-migration/2026-06-13-v0-0-60-migration.md new file mode 100644 index 0000000..8e92608 --- /dev/null +++ b/blog-migration/2026-06-13-v0-0-60-migration.md @@ -0,0 +1,252 @@ +--- +slug: v0060-migration +title: "vNext v0.0.60 Migration Rehberi" +authors: [vnext-team] +tags: [migration] +date: 2026-06-13 +--- + +Bu rehber, **vNext v0.0.60** ile gelen yeni yetenekleri ve mevcut bir domain projesini bu sürüme taşırken atılması gereken adımları anlatır. Sürüm beş ana başlık getiriyor: yeniden kullanılabilir **sys-mappings** bileşeni ve sandbox'lı **custom C# helper**'lar, **rol bazlı state alias**, tutarlı **FunctionScope** zorunluluğu, **Operations & Observability** sıkılaştırmaları ve **yapılandırılabilir asenkron transition** işletimi. + +Bu sürümle birlikte bileşen şeması **0.0.46**'ya yükseldi. Doğrulama yapmadan önce domain projenizde `@burgan-tech/vnext-schema` paketini güncelleyin. + +> Teknik release notları için: [Release v0.0.60](/blog/release-v0-0-60). + +{/* truncate */} + +--- + +## 1. Mappings Bileşeni & Custom C# Helper'lar + +vNext'e yeni bir sistem bileşeni eklendi: **`sys-mappings`** (kısaca *Mappings*). Mapping bileşeni, script mapping kodlarının **yeniden kullanılabilir**, **versiyonlanabilir** ve daha verimli kullanılmasını sağlar. Ayrıca plugin özelliği ile 3rd-party kütüphane/DLL'leri embed ederek kullanım sağlar — bu da business case'lerinde sıkça ihtiyaç duyulan ayrı "utilities API" gereksinimini ortadan kaldırır. + +### Ne değişti + +- Geliştiriciler kendi C# yardımcı sınıflarını `.csx` olarak — tıpkı flow, task ve view'lar gibi — bir **bileşen** olarak yükleyebilir. +- Bu helper'lar bir flow tanımının mapping'inden referans verilir; runtime önce helper sınıflarını derler, ardından mapping'i bunlara karşı derleyip çalıştırır. +- Helper'lar **sandbox** altında, içerik hash'i ile cache'lenerek çalıştırılır. + +### Bileşen ağacı ve `vnext.config.json` + +Domain bileşen ağacına `Mappings/` dizini eklendi: + +```plaintext +├── / +│ ├── Extensions/ +│ ├── Functions/ +│ ├── Schemas/ +│ ├── Tasks/ +│ ├── Views/ +│ ├── Mappings/ # YENİ +│ └── Workflows/ +├── vnext.config.json +``` + +`vnext.config.json` `paths` ve `exports` blokları `mappings` ile genişletildi: + +```json +{ + "domain": "my-domain", + "paths": { + "mappings": "Mappings" + }, + "exports": { + "mappings": [] + } +} +``` + +### Mapping objesindeki `scripts` bloğu + +Tüm mapping objelerinde (`viewRule`, `rule`, transition mapping, subflow mapping, task mapping, extension/function task mapping) yeni bir **`scripts`** objesi tanımlanabilir. `scripts.helpers[]` bir **referans dizisidir** (string değil — `key`/`version`/`domain`/`flow` alanları olan objeler), `scripts.allowedAssemblies[]` ise o mapping'e özel sandbox izinlerini global temel listenin üzerine ekler: + +```json +{ + "mapping": { + "location": "./src/UserSessionMapping.csx", + "code": "", + "encoding": "NAT", + "scripts": { + "helpers": [ + { + "key": "json-helper", + "version": "1.0.0", + "domain": "core", + "flow": "sys-mappings" + } + ], + "allowedAssemblies": [ + "Newtonsoft.Json" + ] + } + } +} +``` + +Aynı `scripts` bloğu flow konfigürasyonuna da (`attributes.scripts`) eklenebilir: + +```json +{ + "attributes": { + "type": "F", + "scripts": { + "helpers": [ + { "key": "rsa-crypto", "version": "1.0.0", "domain": "core", "flow": "sys-mappings" } + ], + "allowedAssemblies": [ "System.Security.Cryptography" ] + } + } +} +``` + +### `REF` encoding + +`code` encoding tipine yeni bir değer eklendi: **`REF`**. Bir mapping, kod gömmek yerine bir `sys-mappings` bileşenine referans verebilir: + +```json +{ + "mapping": { + "encoding": "REF", + "code": { + "key": "initial-mapping", + "version": "1.0.0", + "flow": "sys-mappings", + "domain": "core" + } + } +} +``` + +> **Kısıt:** `sys-mappings` bileşeninin kendisi `REF` kullanamaz — referans hedefinin kendisidir, kendine referans veremez. + +### Sandbox + +Helper'lar iki katmanlı derleme zamanı kapısı (reference allow-list + yasaklı API analizörü) ile kısıtlanır ve paylaşımlı, toplanabilir bir `AssemblyLoadContext` içinde derlenir. `allowedAssemblies` ile mapping bazında verilen izinler global temel listenin (`Scripting:Sandbox:AllowedAssemblies`) üzerine eklenir — yani bir flow, herkesin temel listesini genişletmeden yalnızca kendi helper'ının ihtiyacı olan assembly'yi açar. + +### Migrasyon adımları + +1. `vnext.config.json`'a `paths.mappings` ve `exports.mappings` alanlarını ekleyin; `Mappings/` dizinini oluşturun. +2. Tekrar eden mapping kodlarını `sys-mappings` bileşenlerine çıkarın; flow/mapping'lerden `scripts.helpers[]` ile referans verin. +3. Helper'ınızın baz dışı bir assembly'ye ihtiyacı varsa `scripts.allowedAssemblies[]` ile tanımlayın. Sandbox ayarları (varsayılan ban listesi, `using`'ler, referanslar) için [Scripting / Sandbox Yapılandırması](/docs/configuration/scripting) sayfasına bakın. + +> İlgili dokümanlar: [Mapping Bileşeni (sys-mappings)](/docs/components/mapping-component) · [Mapping Rehberi](/docs/components/mappings) · [Scripting / Sandbox Yapılandırması](/docs/configuration/scripting) + +--- + +## 2. State Alias — Rol Bazlı State Görünürlüğü + +State Function, client tarafında **long-polling** ile süreç durumunu döner. Client'ta başlayan bir iş akışı backoffice'e geçtiğinde **Fraud, KPS, Limit** gibi iç kontrol state'lerine uğrar. Client bu noktada sorgulama yaptığında ham `state.key` döner — iç süreç adımlarının client'a sızması bir **güvenlik açığı** oluşturabilir. + +### Ne değişti + +State'lere opsiyonel bir **`alias[]`** dizisi tanımlanabilir. Alias, aktör/rol bazlı yapı sayesinde hangi client'ın ne göreceğini belirler; aynı zamanda **çoklu-dil (multi-localization)** desteği sağlar. İç state kimliği değişmez — alias yalnızca **sunum** katmanını etkiler; transition'lar, kalıcılık ve iş akışı mantığı aynı `state.key` üzerinden çalışmaya devam eder. + +Her `alias` öğesi şu alanları taşır: + +| Alan | Tip | Zorunlu | Açıklama | +|------|-----|---------|----------| +| `name` | string | Evet | Alias adı. İstek diline uygun bir `label` bulunamazsa fallback olarak döner. | +| `roles` | array | Evet | Bu alias'ın geçerli olduğu roller (`minItems: 1`). **DENY her zaman ALLOW'u geçersiz kılar.** | +| `labels` | array | Evet | Alias'ın çoklu-dil etiketleri (`minItems: 1`). | + +```json +{ + "alias": [ + { + "name": "Değerlendirme Aşamasında", + "roles": [ + { "role": "backoffice.operator", "grant": "allow" } + ], + "labels": [ + { "label": "Operasyon İncelemesinde", "language": "tr" }, + { "label": "Under Operational Review", "language": "en" } + ] + } + ] +} +``` + +Birden fazla iç state aynı dış alias'a eşlenebilir. Çözümleme isteği yapan aktörün rollerini her alias'ın `roles` listesine göre değerlendirir; eşleşme varsa istek dilindeki `label`, o dilde label yoksa `alias.name` döner; hiçbir alias eşleşmezse `state.key`'e geri düşer. + +### Migrasyon adımları + +1. Client'a sızması istenmeyen iç state'leri belirleyin (ör. Fraud/KPS/Limit). +2. Bu state'lere uygun `alias[]` tanımları ekleyin; hangi rolün hangi label'ı göreceğini `roles` + `labels` ile belirtin. +3. Çok dilli kullanımda her dil için `labels` girişi ekleyin; rol modeli ve DENY/ALLOW önceliği için [Yetkilendirme](/docs/concepts/authorization) sayfasına bakın. + +> İlgili dokümanlar: [Workflow → State Alias](/docs/components/workflow#state-alias-rol-tabanlı-state-maskeleme) · [Yetkilendirme](/docs/concepts/authorization) + +--- + +## 3. FunctionScope Zorunluluğu ve Tutarlı Yanıt + +`FunctionScope`, fonksiyon çağrısının her iki giriş noktasında (`GetFunctionByKeyAsync` ve `GetFunctionByInstanceAsync`) artık **tutarlı** şekilde uygulanır: + +| Scope | Kural | +|-------|-------| +| `D` (Domain) | Her zaman çalışır — tüm scope kısıtlarından muaftır. | +| `I` (Instance) | Yalnızca bir instance mevcutsa çalışır. | +| `F` (Flow) | Bir instance **ve** fonksiyonun o instance'ın flow'unda tanımlı olması (`workflow.Functions`) gerekir. | + +### Ne değişti + +Eski davranışta scope kısmen uygulanıyordu: guard yalnızca Flow üyeliğini ve yalnızca bir instance varken kontrol ediyordu. Sonuç olarak `Instance`/`Flow` kapsamlı fonksiyonlar domain seviyesindeki uçtan kısıtsız çağrılabiliyor, scope hataları ise tesadüfi **404** olarak sızıyor ve rol kapsamı (authorize role evaluation) ele alınmıyordu. + +Yeni davranışta authorize rol değerlendirmesi yapılır ve scope/tanım eksikliği veya yetki ihlali durumunda **403 Forbidden** (`FunctionScopeNotSatisfied`) döner. + +### Migrasyon adımları + +1. Fonksiyonlarınızın `scope` değerlerini gözden geçirin: `F` kapsamlı bir fonksiyonun ilgili flow'un `workflow.Functions` listesinde tanımlı olduğundan emin olun. +2. Domain seviyesindeki uçtan `Instance`/`Flow` kapsamlı fonksiyon çağıran client'ları güncelleyin. +3. Hata yönetiminde scope ihlallerinin artık **404 değil 403** döndüğünü dikkate alın. + +> İlgili doküman: [Function](/docs/components/functions/) + +--- + +## 4. Operations & Observability + +### `publish` endpoint'i OpenAPI'de gizlendi + +`publish` endpoint'i varsayılan olarak OpenAPI'de expose ediliyordu. Bu, OpenAPI okunarak API'nin **bileşen yükleme** bilgisini açığa çıkarıyordu. Endpoint artık API Explorer / OpenAPI çıktısında gizlidir. + +### Production'da Swagger UI kapalı + +Swagger arayüzü **production** ortamında tüm API host'larında kapatıldı; public production yüzeyi artık API explorer'ı sunmaz. + +### Migrasyon adımları + +1. Production'da Swagger UI'a bağımlı araç/akış varsa bunları kaldırın veya non-production ortamlara taşıyın. +2. `publish` işlemini OpenAPI üzerinden keşfeden entegrasyonları gözden geçirin; endpoint artık API Explorer'da listelenmez. + +--- + +## 5. Yapılandırılabilir Asenkron Transition İşletimi + +`sync=false` (asenkron) işletim için **durable** bir yöntem implemente edildi. Artık asenkron işlemlerde her transition **scale edilebilir** ve **outbox** yapısı ile **retry** edilebilir hale geldi. + +### Ne değişti + +- Continuation'lar inline çalışmak yerine (opsiyonel olarak **outbox** üzerinden) kuyruğa alınarak dayanıklılık (durability) kazanır. +- **Busy** durumundaki instance'lara erişim, bir **chain ownership token** sistemiyle kontrol edilir; eşzamanlı zincirlerin birbirini ezmesi önlenir. +- Heartbeat'i bayatlamış (takılı kalmış) instance'ları otomatik toparlayan bir **chain reaper** servisi devreye alındı. + +### Migrasyon adımları + +1. `sync=true` / `sync=false` davranışı ve karar kriterleri için [Async / Sync Yöntemi](/docs/how-to/async-sync) sayfasına bakın. +2. Bu sürüm, dayanıklılık refactor'ü için EF Core migration'ları içerir — `db-migrator` image'ı ile şema güncellemesini uygulayın. + +> İlgili doküman: [Async / Sync Yöntemi](/docs/how-to/async-sync) + +--- + +## Özet + +- **sys-mappings** bileşeni + sandbox'lı custom C# helper'lar; `scripts.helpers[]` (obje referansı) / `scripts.allowedAssemblies[]` ve `REF` encoding. +- **State alias** ile rol bazlı, çoklu-dil state maskeleme (DENY > ALLOW); iç state'ler client'a sızmaz. +- **FunctionScope** her çağrı yolunda tutarlı; ihlaller artık **403** döner. +- **Operations:** `publish` endpoint'i OpenAPI'de gizli, production Swagger kapalı. +- **Asenkron transition** durable işletim: outbox ile retry, chain ownership token, chain reaper. +- Bileşen **şeması 0.0.46**'ya yükseldi. + +> Teknik release notları: [Release v0.0.60](/blog/release-v0-0-60) diff --git a/blog/2026-05-21-v0-0-55.md b/blog/2026-05-21-v0-0-55.md index 03f74c4..bad3d87 100644 --- a/blog/2026-05-21-v0-0-55.md +++ b/blog/2026-05-21-v0-0-55.md @@ -240,7 +240,7 @@ Configuration for v0.0.55: ## See Also -- [v0.0.55 Duyurusu](/blog/v0055-neler-degisti) — Feature-focused announcement in Turkish +- [v0.0.55 Duyurusu](/blog/migration/v0055-neler-degisti) — Feature-focused announcement in Turkish (Migration Guides) --- diff --git a/blog/2026-06-01-v0-0-58.md b/blog/2026-06-01-v0-0-58.md index a88612d..ee660a6 100644 --- a/blog/2026-06-01-v0-0-58.md +++ b/blog/2026-06-01-v0-0-58.md @@ -10,8 +10,6 @@ date: 2026-06-01 This release closes the gap in **subflow fault handling**: a faulted child now propagates through the parent's error boundary chain instead of leaving the parent stuck in **Busy** ([#699](https://github.com/burgan-tech/vnext/issues/699)). **Function responses and wizard-state behavior** are extended — `acceptedStatusCodes` are honored end-to-end so `rawResponse=true` endpoints can forward structured HTTP 400s, and wizard states resolve transition views first while reporting `hasView` in a loop-safe way ([#697](https://github.com/burgan-tech/vnext/issues/697)). A **hotfix** standardizes instance audit columns via a shared base model and fixes the async reserved-transition lock ([#644](https://github.com/burgan-tech/vnext/issues/644)). The runtime repository's own documentation was rebuilt into an architecture-first structure ([#693](https://github.com/burgan-tech/vnext/issues/693)), and vocabulary-aware runtime schema validation was added (PR [#692](https://github.com/burgan-tech/vnext/pull/692)). This bump also advances the component **schema to 0.0.43**. -A Turkish announcement (**Duyuru**) is included at the end of this post. - {/* truncate */} --- diff --git a/blog/2026-06-13-v0-0-60.md b/blog/2026-06-13-v0-0-60.md new file mode 100644 index 0000000..b17112f --- /dev/null +++ b/blog/2026-06-13-v0-0-60.md @@ -0,0 +1,153 @@ +--- +slug: release-v0-0-60 +title: Release v0.0.60 +authors: [vnext-team] +tags: [release, duyuru] +date: 2026-06-13 +--- + +## Overview + +This release lands two long-tracked capabilities and hardens the transition pipeline. **Sandboxed, component-referenced custom C# script helpers** let consuming teams ship their own helper classes as `.csx` components and reference them from a mapping's `scripts.helpers`, compiled and run under a two-layer sandbox ([#710](https://github.com/burgan-tech/vnext/issues/710)). **State aliases** expose role-scoped, multi-language state labels without touching the internal state identity ([#648](https://github.com/burgan-tech/vnext/issues/648)). The **transition pipeline gains configurable async execution modes** — continuation enqueueing, transition atomicity, chain-ownership gating, and a chain reaper for stuck instances ([#725](https://github.com/burgan-tech/vnext/pull/725)). **`FunctionScope` is now enforced consistently** on every function-invocation entry point ([#709](https://github.com/burgan-tech/vnext/pull/709)). A correctness **fix removes EF compiled queries** (broken under PGBouncer + multi-schema) and makes the duplicate-key check deterministic ([#715](https://github.com/burgan-tech/vnext/issues/715)), and an **operations hardening** pass disables production Swagger and promotes function/mapping failures to `Error`-level logging ([#724](https://github.com/burgan-tech/vnext/pull/724)). This bump also advances the component **schema to 0.0.46**. + +{/* truncate */} + +--- + +## Features + +### Sandboxed, component-referenced custom C# script helpers (#710) + +Consuming developers can now ship their own C# helper classes as **components** — uploaded as `.csx`, just like flows, tasks, and views — reference them from a transition mapping, and have the runtime **build the helper classes first, then compile and run the mapping against them**. Helpers are sandboxed and cached by content hash. + +- **Delivery:** a helper is a component (`.csx`), source-compiled at runtime (not a precompiled DLL) — the only delivery the runtime can sandbox, since it owns the Roslyn compile. +- **Wiring:** referenced from the mapping's `scripts` block via `scripts.helpers[]`. Explicit, per-flow, no global state. `ScriptBase` stays runtime-owned. +- **Sandbox grants:** `scripts.allowedAssemblies[]` makes the reference allow-list **dynamic per-mapping** — merged on top of the global baseline (`Scripting:Sandbox:AllowedAssemblies`), so a flow grants only the assemblies its helpers need without widening the baseline for everyone. +- **Trust:** restricted/sandboxed (best-effort) via a two-layer compile-time gate — reference allow-list plus a banned-API analyzer — compiled into a shared collectible `AssemblyLoadContext`. + +```jsonc +// transition mapping — scripts block +"scripts": { + "helpers": [ // helper component references + { "key": "rsa-crypto", "version": "1.0.0", "domain": "core", "flow": "sys-mappings" } + ], + "allowedAssemblies": [ "System.Security.Cryptography" ] // per-mapping sandbox grant +} +``` + +> **Migration guide:** for a detailed Turkish walkthrough of every v0.0.60 feature and its migration steps, see [vNext v0.0.60 Migration Rehberi](/blog/migration/v0060-migration). + +> **Reference:** issue [#710](https://github.com/burgan-tech/vnext/issues/710) — see also [Mappings](/docs/components/mappings) and the [Mapping component](/docs/components/mapping-component). + +### State aliases with role-based visibility (#648) + +The same internal state can now be presented differently depending on the user's role, while the underlying workflow logic continues to use the **real state identity**. An applicant's case may internally sit in one of several detailed evaluation states, while the customer sees a single simplified alias such as *"Application Under Review"*. + +A state may declare an optional `alias[]` array, where each `stateAlias` carries: + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `name` | string | yes | Alias name. | +| `roles` | `roleGrant[]` | yes | Roles for which this alias applies. **DENY overrides ALLOW.** | +| `labels` | `languageLabel[]` | yes | Multi-language labels shown to matching users. | + +Multiple internal states can map to the same external alias, and alias resolution is layered on top of the existing role model (so DENY grants still win). Internal workflow logic, transitions, and persistence are unaffected — aliases only shape the **presentation** layer of query/response rendering. + +> **Reference:** issue [#648](https://github.com/burgan-tech/vnext/issues/648) — see also [Workflow component](/docs/components/workflow) and [Authorization](/docs/concepts/authorization). + +### Configurable async transition execution modes (#725) + +The transition pipeline gains configurable async execution, controlled by four runtime flags: + +- **Continuation enqueueing** — continuations can be enqueued (optionally via the **outbox**) for improved durability instead of running inline. +- **Transition atomicity** — controls whether a transition and its continuation commit as one unit. +- **Chain ownership gating** — a **chain ownership token** system provides fine-grained control over access to instances in the **Busy** state, preventing concurrent chains from stepping on each other. +- **Stuck-instance recovery** — a new **chain reaper** service automatically resolves instances whose heartbeats have gone stale, releasing ownership so they can resume. + +The change ships with EF Core migrations for the durability refactor schema changes, plus architecture documentation covering the execution modes and operational guidance. + +> **Reference:** PR [#725](https://github.com/burgan-tech/vnext/pull/725) — see also [Sync vs Async execution](/docs/how-to/async-sync). + +### Consistent `FunctionScope` enforcement on invocation (#709) + +`FunctionScope` is now enforced uniformly across both function-invocation entry points (`GetFunctionByKeyAsync` and `GetFunctionByInstanceAsync`), which both funnel through `ExecuteFunctionAsync`: + +| Scope | Rule | +|-------|------| +| **Domain** | Always runs — exempt from every scope restriction. | +| **Instance** | Only runs when an instance exists. | +| **Flow** (`TaskScope.Flow`, `"F"`) | Requires an instance **and** the function to be declared in that instance's flow (`workflow.Functions`). | + +Previously the guard only checked Flow membership, and only when an instance was present — so `Instance`/`Flow`-scoped functions could be invoked through the domain-level endpoint with no restriction, and scope failures leaked out as incidental **404s**. Scope violations now return a deliberate **403 Forbidden** (`FunctionScopeNotSatisfied`, `Function:800002`). + +> **Reference:** PR [#709](https://github.com/burgan-tech/vnext/pull/709), closes [#637](https://github.com/burgan-tech/vnext/issues/637) — see also [Functions](/docs/components/functions/). + +--- + +## Fixes + +### Remove EF compiled queries + deterministic duplicate-key check (#715) + +Two related defects in the EF instance repository layer: + +1. **EF compiled queries break under PGBouncer + multi-schema.** `EF.CompileAsyncQuery` caches the query plan — including the resolved schema — on a `static readonly` delegate shared across all requests. With per-request schema resolution (`ICurrentSchema`) and PGBouncer transaction pooling, the cached delegate could bind to the wrong schema / stale connection state. EF Core already caches non-compiled query plans transparently, so the compiled queries provided no benefit while causing correctness bugs — they are now removed. +2. **Non-deterministic duplicate-key check.** `CheckExistingInstanceAsync` looked up an existing instance with no status filter and no ordering, so when multiple rows shared a key (terminal history plus a live one) Postgres could return an arbitrary row — occasionally allowing a **second active instance with the same key**. The check is now deterministic: a key is considered "in use" only by **non-terminal** (`Active`/`Busy`) instances, guaranteeing at most one live instance per key. + +> **Reference:** issue [#715](https://github.com/burgan-tech/vnext/issues/715) + +--- + +## Operations & Observability + +### Disable production Swagger + harden function/mapping logging (#724) + +- **Swagger off in production.** `UseAetherApiVersioning` now passes `useSwagger`/`useSwaggerUi` as `!IsProduction()` across the four pipelines (`Orchestration`, `Execution`, `InboxWorker`, `OutboxWorker`), so the public production surface no longer exposes the API explorer. The administrative `PublishAsync` endpoint is hidden from the API Explorer via `[ApiExplorerSettings(IgnoreApi = true)]`. +- **Failures are visible.** `FunctionAppService.ExecuteFunctionAsync` now catches task-coordinator exceptions and logs execution and output/script-mapping failures at **`Error`** level (returning a clear failure `Result` when mapping throws). Task business-failure logs in `TaskExecutionEngine` were promoted from `Debug` to `Error`. +- **No more NREs in executor logs.** Direct `context.ScriptContext.Instance.Id` usage was replaced with `Instance?.Id ?? Guid.Empty` across the script / Dapr / HTTP / trigger executors, so custom functions running without an instance context no longer throw `NullReferenceException` while logging. + +> **Reference:** PR [#724](https://github.com/burgan-tech/vnext/pull/724) + +--- + +## Configuration Updates + +Configuration for v0.0.60: + +```json +{ + "runtimeVersion": "0.0.60", + "schemaVersion": "0.0.46" +} +``` + +> **Note:** Schema version advances to **0.0.46** (from `0.0.43`). The bump adds `scripts.helpers[]` / `scripts.allowedAssemblies[]` on transition mappings ([#710](https://github.com/burgan-tech/vnext/issues/710)) and the `alias[]` / `stateAlias` definition on states ([#648](https://github.com/burgan-tech/vnext/issues/648)). Update `@burgan-tech/vnext-schema` in your domain project before validating against this runtime. + +**Container images:** published at tag `0.0.60` under `ghcr.io/burgan-tech/vnext/*` (execution, orchestrator, init, inbox, outbox, db-migrator), Cosign-signed (keyless OIDC) with SBOM + provenance. Immutable digests are listed in the [GitHub release](https://github.com/burgan-tech/vnext/releases/tag/v0.0.60). + +--- + +## Issues Referenced + +- [vnext #710](https://github.com/burgan-tech/vnext/issues/710) — Sandboxed, component-referenced custom C# script helpers. +- [vnext #648](https://github.com/burgan-tech/vnext/issues/648) — State alias support with role-based visibility. +- [vnext #725](https://github.com/burgan-tech/vnext/pull/725) — Configurable async transition execution modes (continuation, atomicity, chain ownership, chain reaper). +- [vnext #709](https://github.com/burgan-tech/vnext/pull/709) — Enforce `FunctionScope` on function invocation (closes #637). +- [vnext #715](https://github.com/burgan-tech/vnext/issues/715) — Remove EF compiled queries; deterministic instance-key check. +- [vnext #724](https://github.com/burgan-tech/vnext/pull/724) — Disable production Swagger; harden function/mapping error logging. + +--- + +## Summary + +- **Custom C# helpers** ship as `.csx` components, referenced via `scripts.helpers[]` and sandboxed per-mapping with `scripts.allowedAssemblies[]`. +- **State aliases** expose role-scoped, multi-language state labels (DENY overrides ALLOW) without changing internal state identity. +- **Async transition modes** add continuation enqueueing (outbox-capable), transition atomicity, chain-ownership tokens, and a chain reaper for stuck instances. +- **`FunctionScope`** is enforced on every invocation path; violations now return **403** instead of incidental 404s. +- **Fix:** EF compiled queries removed (PGBouncer + multi-schema safe); duplicate-key check is deterministic (one live instance per key). +- **Ops:** production Swagger disabled; function/mapping failures logged at `Error`; executor-log NREs eliminated. +- **Schema** advances to **0.0.46**. + +--- + +**vNext Runtime Platform Team** +Released June 13, 2026 diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 5895f43..d375f7a 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -141,6 +141,17 @@ const config: Config = { onUntruncatedBlogPosts: 'warn', }, ], + [ + '@docusaurus/plugin-client-redirects', + { + redirects: [ + { + from: '/blog/v0055-neler-degisti', + to: '/blog/migration/v0055-neler-degisti', + }, + ], + }, + ], ], themes: [ diff --git a/package-lock.json b/package-lock.json index 6f18c04..eb0f31c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@docusaurus/core": "3.10.0", "@docusaurus/faster": "3.10.0", + "@docusaurus/plugin-client-redirects": "^3.10.0", "@docusaurus/preset-classic": "3.10.0", "@docusaurus/theme-mermaid": "^3.10.0", "@easyops-cn/docusaurus-search-local": "^0.55.1", @@ -3698,6 +3699,30 @@ "react-dom": "*" } }, + "node_modules/@docusaurus/plugin-client-redirects": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-3.10.0.tgz", + "integrity": "sha512-P+VLoLoZTc74so8+IbsaPZ33/mkf2BWL1CYXQpPRkl0v1QVCN2CgfsZY/8QtbYjQnx2upXUnv45abDhNcSggNw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.0", + "@docusaurus/logger": "3.10.0", + "@docusaurus/utils": "3.10.0", + "@docusaurus/utils-common": "3.10.0", + "@docusaurus/utils-validation": "3.10.0", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, "node_modules/@docusaurus/plugin-content-blog": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.10.0.tgz", diff --git a/package.json b/package.json index c85450e..6286f6b 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "dependencies": { "@docusaurus/core": "3.10.0", "@docusaurus/faster": "3.10.0", + "@docusaurus/plugin-client-redirects": "^3.10.0", "@docusaurus/preset-classic": "3.10.0", "@docusaurus/theme-mermaid": "^3.10.0", "@easyops-cn/docusaurus-search-local": "^0.55.1",