From ef2d42d4698c476d99d44bcbbde43ae41b0bd319 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sedat=20=C3=96ZT=C3=9CRK?=
<76204082+iamsedatozturk@users.noreply.github.com>
Date: Wed, 30 Sep 2026 10:28:12 +0300
Subject: [PATCH] DevRequest ile WizardFileManager entegre edildi
---
.github/instructions/ai.instructions.md | 5 +
.github/instructions/lowcode.instructions.md | 30 +++-
README.md | 10 +-
.../McpDevRequestTimesheetRecorder.cs | 5 +
.../McpDevelopAppService.cs | 4 +
.../Wizard/IListFormWizardAppService.cs | 9 +-
.../ListForms/Wizard/ListFormWizardDto.cs | 7 +
.../ListForms/Wizard/WizardExportDtos.cs | 3 +
.../ListForms/Wizard/WizardSeedFileDto.cs | 33 +++-
.../ListForms/ListFormWizardAppService.cs | 116 +++++++++++--
.../ListForms/WizardExportCollector.cs | 10 +-
claude.md | 8 +
configs/mcp/local-mcp-settings.md | 9 +
.../host/data/App.Languages.LanguageText.json | 28 ++++
ui/src/proxy/admin/wizard/models.ts | 8 +
ui/src/services/wizard.service.ts | 17 ++
.../listForm/wizard/WizardFileManager.tsx | 154 ++++++++++++++----
17 files changed, 397 insertions(+), 59 deletions(-)
create mode 100644 configs/mcp/local-mcp-settings.md
diff --git a/.github/instructions/ai.instructions.md b/.github/instructions/ai.instructions.md
index 759c3795..48673659 100644
--- a/.github/instructions/ai.instructions.md
+++ b/.github/instructions/ai.instructions.md
@@ -910,6 +910,11 @@ Exporting a wizard produces a zip whose paths are relative to the scope folder
The closure is **recursive** (`WizardExportCollector`): a sub-form's wizard file is queued and its
own dependencies are collected under the same rules, so the archive stands on its own.
+A whole development request exports the same way: every wizard file whose `DevRequest` block
+(written by MCP `deploy_wizard` from the active request) points at the request goes into one
+closure (`export-dev-request`), shared files once with merged rows. Wizards added by hand carry
+no `DevRequest` and are exported one by one.
+
- `wizard/{file}.json` — the screen itself plus the wizard files of the sub-forms it references
through `SubFormsDto[].Code`, recursively
- `data/App.DeveloperKit.CustomComponents/{Id}.json` — `Custom` path; the file is filtered down to the
diff --git a/.github/instructions/lowcode.instructions.md b/.github/instructions/lowcode.instructions.md
index 8b45218e..b2c57228 100644
--- a/.github/instructions/lowcode.instructions.md
+++ b/.github/instructions/lowcode.instructions.md
@@ -506,7 +506,7 @@ ister ve kiracı kullanıcısına hiçbiri açılmaz.
| `get_dev_guide` | Bu dosyanın (`lowcode`) ya da `reference`'ın başlık listesini / bir bölümünü döner | Bölüm numarayla istenir (`4.3`); aynı numarayı iki başlık taşımamalıdır |
| `create_table` | Yeni SQL Server tablosu kurar, `sql/object/{Tablo}.sql` dosyasını yazar | Ek olarak `App.SqlQueryManager` ister; `Id`/`TenantId`/audit kolonlarını kendi ekler (`fullAudited`, `multiTenant` varsayılan açık); var olan tabloyu reddeder. View/SP/fonksiyon kurulamaz |
| `list_wizards` · `get_wizard` | Wizard dosyalarını listeler (menü yolu, bağımlılar) · dosyayı diskteki hâliyle döner | Var olan menü kökünü/izin grubunu bulmak için önce `list_wizards` |
-| `deploy_wizard` | Wizard cevabından ekranın wizard dosyasını ve menü/yetki/dil seed satırlarını yazar; veritabanına yazmaz (§4.0) | Girdi §4.4'teki düz cevap ya da `get_wizard` çıktısıyla aynı dosya biçimi; enum'lar sayı. `replaceFileName` = `EditFileName` (§4.5). List ekranında `Widgets` dolu gelir — en az 3 kart, kiracı tablosunda `"TenantId" = '@TENANTID'` (§4.6.1); kartlardaki her dil anahtarı var olmalı ya da `Language.Texts`'te EN + TR verilmeli, yoksa deploy reddeder. `MenuOrder` yazılmaz — sunucu yeni ekranı kardeşlerinin sonuna koyar, güncellemede yerini korur. İstek demo veri taşıyorsa `SeedData: true` + `seedRows` (§0.10.1). Çıkıştaki `isPending: true` ekranın henüz kurulmadığını söyler — kullanıcı Wizard Manager'da DB Migrate çalıştırır; model migrate'i beklemez |
+| `deploy_wizard` | Wizard cevabından ekranın wizard dosyasını ve menü/yetki/dil seed satırlarını yazar; veritabanına yazmaz (§4.0) | Girdi §4.4'teki düz cevap ya da `get_wizard` çıktısıyla aynı dosya biçimi; enum'lar sayı. `replaceFileName` = `EditFileName` (§4.5). List ekranında `Widgets` dolu gelir — en az 3 kart, kiracı tablosunda `"TenantId" = '@TENANTID'` (§4.6.1); kartlardaki her dil anahtarı var olmalı ya da `Language.Texts`'te EN + TR verilmeli, yoksa deploy reddeder. `MenuOrder` yazılmaz — sunucu yeni ekranı kardeşlerinin sonuna koyar, güncellemede yerini korur. Talep bağı (`DevRequest`) da yazılmaz — sunucu etkin talepten doldurur (§4.0). İstek demo veri taşıyorsa `SeedData: true` + `seedRows` (§0.10.1). Çıkıştaki `isPending: true` ekranın henüz kurulmadığını söyler — kullanıcı Wizard Manager'da DB Migrate çalıştırır; model migrate'i beklemez |
| `delete_wizard` | Wizard'ı ve yalnızca onun ürettiği kayıtları siler; `dropTables: true` ekranın tablosunu da düşürür | Bağımlı wizard varsa reddeder. Tablo kullanıcı açıkça onaylamadan düşürülmez; `App.SqlQueryManager` ister (§4.5) |
| `start_dev_request` | `App.DevRequests` talebini üstlenir: `Ready to Start` durumundaysa `In Progress` durumuna alır, değilse reddeder | Ek olarak `App.DevRequests.Update` ister. Açıklamadaki görseller ayrı resim içeriği olarak gelir (§0.11) |
| `get_dev_request` | Talebi durumuna dokunmadan okur (aynı metin + analiz + resim içerikleri) | Analizden önce ya da yarım kalan talebe dönmek için; `App.DevRequests` ister |
@@ -608,7 +608,8 @@ talebin metnini döndürür. Başlık birden fazla talebe uyuyorsa Id ister. `St
`deploy_wizard`, `delete_wizard`, `save_component`, `delete_component`, `insert_row` /
`update_row` / `delete_row`, `save_dev_request_analysis`, `append_dev_request_note`,
`add_dev_request_subtasks`) o talebe bir satır ekler
- (`IMcpDevRequestTimesheetRecorder`). Açıklama `App.Mcp.Timesheet.*` dil anahtarından **Türkçe**
+ (`IMcpDevRequestTimesheetRecorder`). Etkin talep `deploy_wizard`'ın yazdığı wizard dosyasına da
+ `DevRequest` olarak girer (§4.0); Wizard Manager talebi gösterir ve talebin tamamını export eder. Açıklama `App.Mcp.Timesheet.*` dil anahtarından **Türkçe**
üretilir ("Hr_T_Doctor tablosu oluşturuldu"), süre önceki satırdan ya da talebin açıldığı andan bu
yana ölçülür (en az 1 dakika, saat olarak), çalışan bağlanan kullanıcı, tarih bugündür.
`Timesheets` `update_row` ile yazılmaz.
@@ -905,7 +906,7 @@ hiçbir şey silmez**. Tek çıktısı seed dosyalarıdır:
| Dosya | İçerik |
| --- | --- |
-| `wizard/{WizardName}.json` | Ekranın `ListForm`/`Fields` sözleşmesi, wizard cevapları, `InsertedRecords`, `Pending` |
+| `wizard/{WizardName}.json` | Ekranın `ListForm`/`Fields` sözleşmesi, wizard cevapları, `InsertedRecords`, `Pending`, `DevRequest` |
| `data/App.Menus.Module.json`, `data/App.Menus.Menu.json` | Modül, üst menü, ekranın menüsü |
| `data/Abp.Identity.PermissionGroups.json`, `data/Abp.Identity.Permissions.json` | İzin grubu, okuma yetkisi ve alt yetkileri |
| `data/App.Languages.LanguageText.json` | Menü, başlık, açıklama, grup, alan başlıkları ve `Language.Texts` anahtarlarının (widget başlıkları) EN + TR metinleri (`Id` iş anahtarından v5 GUID, `SeedRowIds.LanguageText`) |
@@ -938,6 +939,13 @@ ekranı da güncel hâline getirir. Kaldırılan yetkinin rol atamaları yalnız
gidiyorsa silinir. `WizardSeedSynchronizer` bekleyen dosyaya yazmaz — dosya ekranın bir sonraki
sürümünü taşır.
+**Talep bağı (`DevRequest`).** MCP `deploy_wizard` dosyaya kullanıcının etkin talebini
+(`get_dev_request` / `start_dev_request` ile açılan, `IMcpDevRequestTimesheetRecorder.GetActiveRequestIdAsync`)
+`{ "Id", "Title" }` olarak yazar. Bağ modelin girdisinden gelmez: `ListFormWizardDto.DevRequestId`
+`[JsonIgnore]`'dur, yalnızca sunucu içinden doldurulur. Aynı wizard'ı sonra başka bir talep deploy
+ederse bağ o talebe geçer; Wizard Manager'dan elle yapılan kayıt önceki bağı korur, hiç talep
+yoksa bölüm dosyaya yazılmaz. Migrate, senkronizasyon ve import bölümü olduğu gibi taşır.
+
### 4.1 Dosya iskeleti
```jsonc
@@ -961,7 +969,8 @@ sürümünü taşır.
"InsertedRecords": { // bu çalıştırmanın GERÇEKTEN yarattığı kayıtlar
"LanguageKeys": [], "PermissionGroupNames": [], "PermissionNames": [],
"MenuCodes": [], "DataSourceCodes": [], "ModuleIds": []
- }
+ },
+ "DevRequest": { "Id": "…", "Title": "…" } // yalnızca MCP talebiyle deploy edildiyse
}
```
@@ -2988,7 +2997,8 @@ ekran kodudur — bileşen ekranı yeniden kurmaz, gömer.
### 7.7 Taşıma
Bir ekranı başka ortama taşımak tek dosya kopyalamak değildir. Wizard File Manager'ın **Export**
-butonu, ekranın **özyinelemeli bağımlılık kapanışını** (`WizardExportCollector`) zip'e koyar:
+butonu, ekranın **özyinelemeli bağımlılık kapanışını** (`WizardExportCollector`) zip'e koyar. Talep
+hücresindeki export düğmesi aynısını bir talebin bütün wizard'ları için tek arşivde yapar (§9.8):
```
wizard/{dosya}.json (ekranın kendisi + SubFormsDto[].Code ile bağlı
@@ -3896,9 +3906,17 @@ Kurallar:
bir ekran açma.
Wizard Manager'ın kendi aksiyonları: liste/kart görünümü, arama, düzenleme (`EditFileName`),
-silme, DB Migrate, Export (zip), Import (diff + rollback). Yetkiler
+silme, DB Migrate, Export (zip), talep export'u, Import (diff + rollback). Yetkiler
`App.Listforms.Wizard{,.Create,.Update,.Delete,.Export,.Import}`.
+Her wizard'ı üreten talep listede görünür (`WizardFileInfoDto.DevRequestId/Title/Url`; başlık
+talepten güncel okunur). Başlık talebin kaydını açar (`/admin/form/App.DevRequests/{Id}`); talep bu
+ortamda yoksa (import edilmiş dosya) dosyadaki başlık bağlantısız gösterilir, elle eklenen wizard'da
+hücre boştur. Yanındaki düğme talebin bütün wizard'larını tek arşivde indirir
+(`api/app/list-form-wizard/export-dev-request{,-analysis}`, `.Export` yetkisi): kapanış tek
+`WizardExportCollector` çağrısında kurulur, paylaşılan dosyalar arşive bir kez ve birleşik satırlarla
+girer. Import çok wizard'lı arşivi zaten tek oturumda uygular.
+
Listede her ekranın üst menü zinciri (`WizardFileInfoDto.MenuPath`, Menu tablosundan; kayıt yoksa
wizard'ın `MenuParentPath` + `MenuParentCode` cevabı) görünür. Bağlı wizard'lar üst ekranın altında gruplanır
(`Dependencies`): List yolunda alt formlar, Custom yolunda component `Dependencies` zinciri —
diff --git a/README.md b/README.md
index dfc6fbfc..761c9015 100644
--- a/README.md
+++ b/README.md
@@ -525,7 +525,8 @@ detayı aynı veri yapısını konuşur ve tasarımcıdaki değişiklikler wizar
yolu, alan başlıklarının dil karşılıkları) taşır; `ListForm`/`Fields` içinde karşılığı olan alanlar
dosyaya yazılmaz, okuma sırasında geri doldurulur. Kalanlar dosyada `Menu`, `Language` ve `Groups`
başlıkları altında toplanır (`WizardSeedFileDto.ToSeedJson` / `FromSeedJson`). Dosya adı `{Ad}.json`'dır (zaman damgası yok);
-uygulama sırası `Wizard.SeededAt` damgasından gelir.
+uygulama sırası `Wizard.SeededAt` damgasından gelir. MCP `deploy_wizard` dosyaya etkin talebi
+`DevRequest` (`Id`, `Title`) olarak yazar; elle yapılan kayıt bu bağı korur, talepsiz wizard'da bölüm yoktur.
**İki yol: `ComponentKind`.** `ListFormWizardDto.ComponentKind` sihirbazın yol ayrımıdır ve seed
dosyasında ilk alandır. Varsayılan `List` olduğu için bu alanı taşımayan eski seed dosyaları
@@ -584,6 +585,9 @@ aynı klasör düzenine doğrudan açılabilir.
Toplama **özyinelemelidir** (`WizardExportCollector`): alt formların wizard dosyaları kuyruğa
eklenir ve onların bağımlılıkları da aynı kurallarla toplanır. Böylece zip tek başına çalışır.
+**Talep export'u** (`api/app/list-form-wizard/export-dev-request{,-analysis}`) bir geliştirme
+talebinin `DevRequest` bağı taşıyan bütün wizard'larını aynı toplayıcıda tek kapanışa koyar;
+paylaşılan dosyalar arşive bir kez, birleşik satırlarla girer ve import arşivi tek oturumda uygular.
| Yol | İçerik |
| --- | --- |
@@ -750,7 +754,7 @@ Teknik kullanıcılar için `/admin/developerkit` altında toplanan araçlar:
| **Custom Component** | `/admin/list/App.DeveloperKit.CustomComponents` | React bileşenini veritabanında saklama; `@babel/standalone` ile tarayıcıda derleyip route'a bağlama. Liste bir ListForm ekranıdır (KPI şeridi, ızgara/kart görünümü, grid'in kendi ekleme/düzenleme formu); satırdaki **Design** butonu `/admin/developerkit/components/design/{id}` tasarımcısını, **Open URL** butonu bileşenin `RoutePath`'ini açar. Kayıtlar `configs/seeds/host/data/App.DeveloperKit.CustomComponents/{Id}.json` klasörüne senkronlanır. Yetkiler `App.DeveloperKit.CustomComponents{,.Create,.Update,.Delete,.Export,.Import}`. |
| **Visual Designer** | `/admin/developerkit/components/design/:id` | Custom Component listesindeki **Design** butonundan açılır; sürükle-bırak kanvas ile bileşen üretimi ve kod üretimi (`visualDesigner/codeGenerator.ts`). |
| **ListForm** | `/admin/list/App.Listforms.Listform` | Var olan ekranların ham tanım listesi; buradan `/admin/listform/edit/{kod}` sekmeli editörüne geçilir. |
-| **Wizard Manager** | `/admin/listform/wizardManager` | Üretilmiş wizard seed dosyalarının listesi/kartı, düzenleme, silme, DB migrate, export/import. Yetki `App.Listforms.Wizard{,.Create,.Update,.Delete,.Export,.Import}`. |
+| **Wizard Manager** | `/admin/listform/wizardManager` | Üretilmiş wizard seed dosyalarının listesi/kartı, düzenleme, silme, DB migrate, export/import. Wizard'ı üreten talep listede görünür ve kaydına bağlanır; talebin bütün wizard'ları tek arşivde export edilir (`export-dev-request`). Yetki `App.Listforms.Wizard{,.Create,.Update,.Delete,.Export,.Import}`. |
> Bu ekranların artefakt şemaları, enum değerleri ve çalışan örnekleri
> [`.github/instructions/lowcode.instructions.md`](.github/instructions/lowcode.instructions.md)
@@ -1446,7 +1450,7 @@ liste süzgeci ve çağrı kapısı aynı kuralı kullanır.
| `get_dev_guide` | Üretim sözleşmesi: `lowcode` / `reference` belgelerinin başlık listesi ya da istenen bölümü (numarayla, örn. `4.2`). Çok büyük bir üst bölüm yalnızca giriş metni + alt başlıklarıyla döner. |
| `create_table` | Yeni tabloyu SQL Query Manager tablo tasarımcısıyla aynı script biçimiyle kurar (`McpTableCreator`): `Id` + `TenantId` + tam audit kolonları şablondan gelir, istemci yalnızca iş kolonlarını verir; tip ve varsayılan değer beyaz listeden geçer, istemci SQL yazamaz. Script `{kapsam}/sql/object/{Tablo}.sql` dosyasına yazılır. Yalnızca oluşturur — tablo varsa reddeder; yalnızca SQL Server. `.Write` + `App.SqlQueryManager` ister. |
| `list_wizards` / `get_wizard` | Wizard File Manager dosyaları; `get_wizard` seed dosyasını diskteki biçimiyle döndürür. |
-| `deploy_wizard` | Wizard'ı Wizard ekranıyla aynı yoldan (`IListFormWizardAppService.Create`) deploy eder. Girdi seed dosyası biçimi (`{"Wizard": …}`) ya da düz cevaplardır; ikisi de `WizardSeedFileDto.FromSeedJson`'dan geçer. Wizard ekranı gibi yalnızca seed dosyalarını yazar; ekran DB Migrate ile kurulur ve çıkıştaki `isPending` o zamana kadar `true` kalır (model migrate'i beklemez; `verify_wizard` bekleyen dosyada `install` kontrolünde durur). `replaceFileName` doluysa güncellemedir (dosyalar yeniden yazılır, önceki kayıtları migrate kaldırır). İstek demo veri taşıyorsa (prompt'taki satırlar, ekran görüntüsü) wizard `SeedData: true` ile deploy edilir — ekranın `SeedFilePath`'i `data/{ListFormCode}.json` olur ve `SeedSync*` bayrakları açılır — satırlar aynı çağrıda `seedRows` ile bu dosyaya yazılır (alan adları doğrulanır, `Guid` anahtarı sunucu üretir); migrate ekranı kurduktan sonra satırları ekler (`lowcode.instructions.md` §0.10.1). Widget sorgularındaki her dil anahtarı tanımlı olmalı ya da wizard'ın `Language.Texts` alanında EN + TR verilmeli, yoksa deploy adlarıyla reddeder (`ValidateWidgetLanguageKeysAsync`). `uploadUrl`'süz `dxImageUpload` alanı base64 sakladığı için kolonu sınırlı boyluysa (katalogdaki karakter sınırı) deploy reddedilir; tablo kolonuna bağlı `dxImageViewer` alanı da reddedilir — görsel kolonunun editörü her zaman `dxImageUpload`'dır (`ValidateImageColumnLengths`). `MenuOrder` yok sayılır: yeni ekran kardeşlerinin sonuna, güncelleme mevcut yerine yazılır — lookup kaynağı ekran önce deploy edildiği için onu kullanan ekranın üstünde kalır. |
+| `deploy_wizard` | Wizard'ı Wizard ekranıyla aynı yoldan (`IListFormWizardAppService.Create`) deploy eder. Girdi seed dosyası biçimi (`{"Wizard": …}`) ya da düz cevaplardır; ikisi de `WizardSeedFileDto.FromSeedJson`'dan geçer. Dosyaya kullanıcının etkin talebi `DevRequest` olarak yazılır (sunucu doldurur). Wizard ekranı gibi yalnızca seed dosyalarını yazar; ekran DB Migrate ile kurulur ve çıkıştaki `isPending` o zamana kadar `true` kalır (model migrate'i beklemez; `verify_wizard` bekleyen dosyada `install` kontrolünde durur). `replaceFileName` doluysa güncellemedir (dosyalar yeniden yazılır, önceki kayıtları migrate kaldırır). İstek demo veri taşıyorsa (prompt'taki satırlar, ekran görüntüsü) wizard `SeedData: true` ile deploy edilir — ekranın `SeedFilePath`'i `data/{ListFormCode}.json` olur ve `SeedSync*` bayrakları açılır — satırlar aynı çağrıda `seedRows` ile bu dosyaya yazılır (alan adları doğrulanır, `Guid` anahtarı sunucu üretir); migrate ekranı kurduktan sonra satırları ekler (`lowcode.instructions.md` §0.10.1). Widget sorgularındaki her dil anahtarı tanımlı olmalı ya da wizard'ın `Language.Texts` alanında EN + TR verilmeli, yoksa deploy adlarıyla reddeder (`ValidateWidgetLanguageKeysAsync`). `uploadUrl`'süz `dxImageUpload` alanı base64 sakladığı için kolonu sınırlı boyluysa (katalogdaki karakter sınırı) deploy reddedilir; tablo kolonuna bağlı `dxImageViewer` alanı da reddedilir — görsel kolonunun editörü her zaman `dxImageUpload`'dır (`ValidateImageColumnLengths`). `MenuOrder` yok sayılır: yeni ekran kardeşlerinin sonuna, güncelleme mevcut yerine yazılır — lookup kaynağı ekran önce deploy edildiği için onu kullanan ekranın üstünde kalır. |
| `delete_wizard` | Wizard Manager'daki silmeyle aynı: `InsertedRecords` + ekranın veri aynası, bağımlı wizard varsa reddedilir. `dropTables: true` ekranın tablosunu (yalnızca tasarımcı/`create_table` ile kurulmuş ve başka yerde kullanılmayan) CRUD endpoint'leri, `sql/object` ve `crud` dosyalarıyla düşürür; model bunu kullanıcı onayı olmadan göndermez (`WizardTableCleaner`, `lowcode.instructions.md` §4.5). |
| `verify_wizard` | Deploy edilmiş ekranı veri yazmadan doğrular: menü kaydı ve URL'si, menünün istediği yetki tanımı (`AbpPermissions`), List yolunda ekran sorgusu (`GetSelectAsync`, tek satır, çağıranın yetkisiyle), Custom yolunda bileşen (etkin, rota = menü URL'si) ve seed kapanışı (`ExportAnalysis` uyarıları; engellemez). İsteğe bağlıdır, migrate sonrasında kullanılır; `App.DevRequests` döngüsünün adımı değildir — döngü `Testing`'de biter, kullanıcı elle test edip `Staging`'e alır (`lowcode.instructions.md` §0.11). |
| `start_dev_request` | Geliştirme talebini Id ya da tam başlıkla üstlenir: yalnızca `Ready to Start` durumundakini `In Progress` durumuna alır, diğerlerini reddeder; talebin metnini döndürür. Açıklamaya yapıştırılmış base64 görseller (`data:image/png|jpeg|gif|webp`) metinden ayıklanır (`McpDevRequestImages`), yerlerinde `[image-N]` kalır ve her biri ayrı MCP resim içeriği (`ImageContentBlock`) olarak döner — model görseli resim olarak görür, görsel hiçbir yere yüklenmez. `.Write` + `App.DevRequests.Update` ister. |
diff --git a/api/modules/Sozsoft.Mcp/Sozsoft.Mcp.Application/McpDevRequestTimesheetRecorder.cs b/api/modules/Sozsoft.Mcp/Sozsoft.Mcp.Application/McpDevRequestTimesheetRecorder.cs
index f1a9e032..77ebeb33 100644
--- a/api/modules/Sozsoft.Mcp/Sozsoft.Mcp.Application/McpDevRequestTimesheetRecorder.cs
+++ b/api/modules/Sozsoft.Mcp/Sozsoft.Mcp.Application/McpDevRequestTimesheetRecorder.cs
@@ -30,6 +30,9 @@ public interface IMcpDevRequestTimesheetRecorder
/// Talebi kullanicinin etkin talebi yapar ve olcumu baslatir.
Task BeginAsync(Guid devRequestId);
+ /// Kullanicinin etkin talebi; talep acilmadiysa ya da suresi dolduysa bos.
+ Task GetActiveRequestIdAsync();
+
///
/// Etkin talebe bir satir yazar; etkin talep yoksa (islem bir talep dongusunun parcasi
/// degilse) hicbir sey yapmaz.
@@ -61,6 +64,8 @@ public class McpDevRequestTimesheetRecorder(
public Task BeginAsync(Guid devRequestId) => StampAsync(devRequestId, clock.Now);
+ public async Task GetActiveRequestIdAsync() => (await activityCache.GetAsync(ActivityKey()))?.RequestId;
+
public async Task RecordAsync(string descriptionKey, params object[] args)
{
var activity = await activityCache.GetAsync(ActivityKey());
diff --git a/api/modules/Sozsoft.Mcp/Sozsoft.Mcp.Application/McpDevelopAppService.cs b/api/modules/Sozsoft.Mcp/Sozsoft.Mcp.Application/McpDevelopAppService.cs
index bf66953b..a0945800 100644
--- a/api/modules/Sozsoft.Mcp/Sozsoft.Mcp.Application/McpDevelopAppService.cs
+++ b/api/modules/Sozsoft.Mcp/Sozsoft.Mcp.Application/McpDevelopAppService.cs
@@ -178,6 +178,10 @@ public class McpDevelopAppService(
// Satirlar deploy'dan once dogrulanir; gecersiz girdi yarim bir deploy birakmaz.
var seedRows = ParseSeedRows(input.SeedRows, wizard);
+ // Wizard dosyasi onu ureten talebi tasir; Wizard Manager talebi gosterir ve talebin
+ // butun wizard'larini birlikte export eder. Bag modelin girdisinden degil etkin talepten gelir.
+ wizard.DevRequestId = await timesheetRecorder.GetActiveRequestIdAsync();
+
await wizardAppService.Create(wizard);
var files = await wizardAppService.GetFiles();
diff --git a/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/IListFormWizardAppService.cs b/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/IListFormWizardAppService.cs
index 289178db..2ed76b64 100644
--- a/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/IListFormWizardAppService.cs
+++ b/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/IListFormWizardAppService.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Content;
@@ -26,6 +27,12 @@ public interface IListFormWizardAppService
///
Task ExportAnalysis(string fileName);
+ /// Bir gelistirme talebinin urettigi butun wizard'lari ortak kapanisla tek zip olarak dondurur.
+ Task ExportDevRequest(Guid devRequestId);
+
+ /// Talep export'unun onizlemesi; ile ayni sozlesme.
+ Task ExportDevRequestAnalysis(Guid devRequestId);
+
///
/// Export zip'ini staging klasorune acar ve her dosya icin hedefteki karsiligiyla
/// karsilastirma sonucunu dondurur. Bu adim hicbir hedef dosyaya dokunmaz.
diff --git a/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/ListFormWizardDto.cs b/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/ListFormWizardDto.cs
index f132c4d5..945dd083 100644
--- a/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/ListFormWizardDto.cs
+++ b/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/ListFormWizardDto.cs
@@ -39,6 +39,13 @@ public class ListFormWizardDto
public string WizardName { get; set; }
+ ///
+ /// Deploy'u yapan gelistirme talebi. Yalnizca sunucu ici girdidir: MCP etkin talebi buraya
+ /// yazar, HTTP istegi dolduramaz; dosyaya olarak yazilir.
+ ///
+ [JsonIgnore]
+ public Guid? DevRequestId { get; set; }
+
///
/// Wizard'in ilk deploy edildigi an. Dosya adi tarih tasimadigi icin seeder dosyalari bu
/// damgaya gore siralar; birbirine bagli wizard'lar (once Customers, sonra Tasks) uretildikleri
diff --git a/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/WizardExportDtos.cs b/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/WizardExportDtos.cs
index 6aeae15d..06a10b00 100644
--- a/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/WizardExportDtos.cs
+++ b/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/WizardExportDtos.cs
@@ -21,6 +21,9 @@ public class WizardExportAnalysisDto
/// Kaynak wizard seed dosyasinin adi.
public string FileName { get; set; }
+ /// Arsive giren wizard dosyalari; talep export'unda talebin butun wizard'lari.
+ public List WizardFiles { get; set; } = [];
+
/// Indirilecek arsivin adi.
public string ArchiveName { get; set; }
diff --git a/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/WizardSeedFileDto.cs b/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/WizardSeedFileDto.cs
index 6c6ca929..f8ce149c 100644
--- a/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/WizardSeedFileDto.cs
+++ b/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/WizardSeedFileDto.cs
@@ -46,6 +46,13 @@ public class WizardSeedFileDto
///
public WizardPendingDto Pending { get; set; }
+ ///
+ /// Wizard'i MCP uzerinden son deploy eden gelistirme talebi (App.DevRequests). Wizard
+ /// Manager'dan elle yapilan kayit bagi degistirmez; hic talep yoksa bolum dosyada yer almaz.
+ /// Baslik deploy anindaki hâlidir; talep bu ortamda yoksa (import edilmis dosya) liste onu gosterir.
+ ///
+ public WizardDevRequestDto DevRequest { get; set; }
+
///
/// Dosyaya yazmadan once ortama ozgu alanlari temizler. Kayit kimlikleri ve audit damgalari
/// veritabanina aittir; dosyada tasinirlarsa her ortamda anlamsiz fark uretirler. EditType ise
@@ -219,8 +226,14 @@ public class WizardSeedFileDto
// Bekleyen kurulum yoksa bolum dosyada hic yer almaz; kurulu bir wizard'in dosyasi
// migrate sonrasinda deploy oncesiyle birebir ayni kalir.
- if (Pending == null && node is JsonObject root)
- root.Remove(nameof(Pending));
+ if (node is JsonObject root)
+ {
+ if (Pending == null)
+ root.Remove(nameof(Pending));
+
+ if (DevRequest == null)
+ root.Remove(nameof(DevRequest));
+ }
if (node?[nameof(Wizard)] is JsonObject wizardNode)
{
@@ -438,6 +451,13 @@ public class WizardPendingDto
public List ListFormCodes { get; set; } = [];
}
+/// Wizard'i ureten gelistirme talebinin dosyadaki izi.
+public class WizardDevRequestDto
+{
+ public Guid Id { get; set; }
+ public string Title { get; set; }
+}
+
/// Kaydi kullanan (silinmesine engel olan) taraf.
public class WizardRecordRefDto
{
@@ -549,4 +569,13 @@ public class WizardFileInfoDto
/// yolunda component bagimliliklari. Yalnizca kapsamda wizard dosyasi olanlar listelenir.
///
public List Dependencies { get; set; } = [];
+
+ /// Wizard'i ureten gelistirme talebi; elle eklenen wizard'da bostur.
+ public Guid? DevRequestId { get; set; }
+
+ /// Talebin guncel basligi; talep bu ortamda yoksa dosyadaki baslik.
+ public string DevRequestTitle { get; set; }
+
+ /// Talebin kayit sayfasi; talep bu ortamda yoksa bostur ve liste baglanti vermez.
+ public string DevRequestUrl { get; set; }
}
diff --git a/api/src/Sozsoft.Platform.Application/ListForms/ListFormWizardAppService.cs b/api/src/Sozsoft.Platform.Application/ListForms/ListFormWizardAppService.cs
index 1cefe7f9..9a8af58c 100644
--- a/api/src/Sozsoft.Platform.Application/ListForms/ListFormWizardAppService.cs
+++ b/api/src/Sozsoft.Platform.Application/ListForms/ListFormWizardAppService.cs
@@ -49,6 +49,7 @@ public class ListFormWizardAppService(
IRepository repoPermGroup,
IRepository