@appaflytech/zeyrek-ai-mcp 0.0.56 → 0.0.58
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.
- package/dist/knowledge/backendConstraints.js +12 -0
- package/dist/knowledge/storeImport.js +7 -2
- package/dist/resources/guides/deployment.md +9 -2
- package/dist/resources/guides/mobile-publish.md +6 -2
- package/dist/resources/schema-fingerprint.json +3 -3
- package/dist/resources/schemas/CreateEntityCommand.json +3 -0
- package/dist/resources/schemas/CreateWorkflowCommand.json +3 -0
- package/dist/resources/schemas/UpdateEntityCommand.json +3 -0
- package/dist/resources/schemas/UpdateWorkflowCommand.json +3 -0
- package/dist/tools/deployments.js +1 -1
- package/dist/tools/mobileStore.js +1 -1
- package/dist/tools/mobileStoreImport.js +4 -4
- package/package.json +1 -1
|
@@ -822,6 +822,18 @@ export const backendRules = [
|
|
|
822
822
|
guide: 'ngapps://guides/entity',
|
|
823
823
|
check: body => entityTransferFindings(body)
|
|
824
824
|
},
|
|
825
|
+
{
|
|
826
|
+
id: 'ENT-019',
|
|
827
|
+
module: 'entity',
|
|
828
|
+
commands: { create: 'CreateEntityCommand', update: 'UpdateEntityCommand' },
|
|
829
|
+
status: 400,
|
|
830
|
+
summary: "roles tablosunda recordTransferSkipExisting açılamaz",
|
|
831
|
+
sourceRef: 'RecordTransferValidator.ValidateAsync: requestedSkipExisting && entity.Id == Defaults.RoleEntityGuid ⇒ RecordTransferSkipExistingNotAvailableForRolesException (ADR 0072, K-4)',
|
|
832
|
+
guide: 'ngapps://guides/deployment',
|
|
833
|
+
check: body => String(body.slug ?? '').toLowerCase() === 'roles' && body.recordTransferSkipExisting === true
|
|
834
|
+
? ["recordTransferSkipExisting: Keeping existing rows isn't available for 'roles' — roller kendi taşıyıcılarıyla (Module.Role) aktarılır, satır parçasıyla değil; ayar orada uygulanamadığı için platform 400 döner. Ayarı kapalı bırakın."]
|
|
835
|
+
: []
|
|
836
|
+
},
|
|
825
837
|
{
|
|
826
838
|
id: 'MS-017',
|
|
827
839
|
module: 'microservice',
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
/** Backend `MobileStoreImportConstants.Section*` — rapor bölümleri */
|
|
7
7
|
export const STORE_IMPORT_SECTIONS = ['identity', 'texts', 'urls', 'appInfo', 'assets', 'declarations'];
|
|
8
|
+
/** Backend `MobileStoreImportConstants.IssueLockedKept` — ilk derlemenin kilitlediği, Uygula'nın yazmadığı satır */
|
|
9
|
+
export const LOCKED_KEPT_ISSUE = 'locked_kept';
|
|
8
10
|
/** Backend `MobileStoreDiffConstants.Choice*` */
|
|
9
11
|
export const STORE_DIFF_CHOICES = ['zeyrek', 'store'];
|
|
10
12
|
/** Backend `PurchaseOptions.ImportMaxBytes` */
|
|
@@ -17,8 +19,10 @@ const items = (value) => (Array.isArray(value) ? value : []).filter(isObject);
|
|
|
17
19
|
export function importReportOutline(record, section) {
|
|
18
20
|
const report = isObject(record.report) ? record.report : {};
|
|
19
21
|
const sections = items(report.sections);
|
|
22
|
+
const rowsOf = sections.flatMap(entry => items(entry.rows).map(row => ({ section: entry.key, row })));
|
|
23
|
+
const lockedKept = rowsOf.filter(({ row }) => Array.isArray(row.issues) && row.issues.includes(LOCKED_KEPT_ISSUE)).map(({ row }) => row.field);
|
|
20
24
|
const issues = sections.flatMap(entry => items(entry.rows)
|
|
21
|
-
.filter(row => Array.isArray(row.issues) && row.issues.
|
|
25
|
+
.filter(row => Array.isArray(row.issues) && row.issues.some(issue => issue !== LOCKED_KEPT_ISSUE))
|
|
22
26
|
.map(row => ({ section: entry.key, field: row.field, store: row.store, issues: row.issues, value: row.value, alternative: row.alternative })));
|
|
23
27
|
const violations = items(record.violations);
|
|
24
28
|
return {
|
|
@@ -28,7 +32,8 @@ export function importReportOutline(record, section) {
|
|
|
28
32
|
progress: record.progress,
|
|
29
33
|
summary: report.summary,
|
|
30
34
|
issues,
|
|
31
|
-
|
|
35
|
+
...(lockedKept.length > 0 ? { lockedKept: { fields: lockedKept, note: "İlk derleme bu alanları kilitledi: Uygula yazmaz, Zeyrek'teki korunur (MOB-037). Karar gerektirmez." } } : {}),
|
|
36
|
+
products: items(report.products).map((product, index) => ({ index, kind: product.kind, bucket: product.bucket, suggestedKey: product.suggestedKey, suggestedEntitlement: product.suggestedEntitlement, existingKey: product.existingKey, apple: product.apple, play: product.play, storeManaged: product.storeManaged, issues: product.issues })),
|
|
32
37
|
mapping: record.mapping,
|
|
33
38
|
...(violations.length > 0 ? { violations, next: `Taslak kaydedildi ama ${violations.length} kural ihlali var; mobile_store_import_apply bunlar düzelmeden 422 döner. Satırı düzeltip mobile_store_import_mapping'i yeniden çağırın.` } : {}),
|
|
34
39
|
...(section ? { rows: items(sections.find(entry => entry.key === section)?.rows) } : {}),
|
|
@@ -57,11 +57,17 @@ Satırlar **tablo başına** açılan kayıt taşıma ayarıyla gider. Ayar enti
|
|
|
57
57
|
satırları ana tabloyla **otomatik** gider; onlara ayrıca ayar açılmaz. Junction satırı yalnız iki
|
|
58
58
|
tarafı da taşınıyorsa gider (dosya tarafı her zaman geçer).
|
|
59
59
|
- **Kimlikler 1:1 korunur:** satır production'a aynı birincil anahtarla yazılır, identity sayacı
|
|
60
|
-
taşınan id'lerin ötesine ilerletilir. Production'da aynı id'li satır varsa üzerine yazılır.
|
|
60
|
+
taşınan id'lerin ötesine ilerletilir. Production'da aynı id'li satır varsa üzerine yazılır (ayar kapalıyken).
|
|
61
61
|
- **`'all'` = ayna (DEP-005, backend ADR 0011):** promote'ta production o tabloda development'ın
|
|
62
62
|
aynasıdır. Kaynakta olmayan satır, çevirisi ve junction satırı production'da **silinir** —
|
|
63
63
|
production'a doğrudan girilmiş satırlar dahil. Kaynak tablo boşsa hedef tablo boşalır. Platformun
|
|
64
64
|
kendi tabloları (`users`, `roles`, `permissions`) taşımaya açılabilir ama aynalanmaz.
|
|
65
|
+
- **Hedefte varsa elleme (`recordTransferSkipExisting: true`, backend ADR 0072):** hedefte aynı birincil anahtarlı
|
|
66
|
+
ya da başka bir unique anahtarı çakışan satır **güncellenmez**, yalnız eksik satır eklenir; tablo **aynalanmaz**
|
|
67
|
+
(hedefin kendi eklediği satır silinmez). Şablon güncellemesinde de geçerlidir; dal açılışı ve merge yok sayar.
|
|
68
|
+
`roles`'ta açılamaz (ENT-019). Identity anahtarlı tabloya iki taraf da satır eklerse kimlikler çakışır ve kaynağın
|
|
69
|
+
satırı gelmez — iki tarafın satır eklediği tabloda `uuid` anahtar kullanın. Studio: tablo paneli → **"Hedefte zaten olan
|
|
70
|
+
kayıtları güncelleme"**.
|
|
65
71
|
- **`'specific'` silmez:** yalnız upsert yapar. Seçili satırın FK ile gösterdiği satırlar zincirleme
|
|
66
72
|
gelir (bir satır seçmek birkaçını taşıyabilir); seçilmemiş bir satıra giden çoka-çok bağı düşer.
|
|
67
73
|
- **İlişki sırası:** `'all'` açılan tablonun ilişki hedefinde de taşıma açık olmalıdır, yoksa kayıt
|
|
@@ -122,4 +128,5 @@ yeni bir deploy.
|
|
|
122
128
|
| Çeviriler eksik, satırlar var | ana tablonun ayarı | çeviri tablosu ana tabloyla gider; ana tabloda ayar açık olmalı |
|
|
123
129
|
| Görsel production'da 404 | `page_schema_get` → prop düz URL mi, `{ type:'file', ref }` mi | prop'u `ref` ile bağlayın ya da dosyayı taşınan satırın dosya sütunundan okuyun |
|
|
124
130
|
| Satırın dosyası 404, satır var | satır taşınıyor mu (`recordTransferMode`) | dosya yalnız taşınan satırla gider |
|
|
125
|
-
| Production'da silinmiş satırlar | tablo `'all'` mı | ayna kuralı (DEP-005); production'a girilen veri bu tabloda tutulmaz |
|
|
131
|
+
| Production'da silinmiş satırlar | tablo `'all'` mı | ayna kuralı (DEP-005); production'a girilen veri bu tabloda tutulmaz — tutulsun isteniyorsa `recordTransferSkipExisting: true` |
|
|
132
|
+
| Production / abone değeri deploy ya da şablon güncellemesiyle ezildi | `entity_get` → `recordTransferSkipExisting` | `true` yapın: var olan satır güncellenmez |
|
|
@@ -329,13 +329,17 @@ ve Play iç test satın almaları `environment: test` etiketiyle, `includeTest:
|
|
|
329
329
|
## Mağazadan taşıma
|
|
330
330
|
|
|
331
331
|
Yayındaki bir uygulama (App Store / Google Play) Zeyrek'e **bir kez okunur, bir kez onaylanır**; sonra tek kaynak Zeyrek'tir
|
|
332
|
-
(kök ADR 0028).
|
|
332
|
+
(kök ADR 0028). İlk derlemeden sonra da yeniden okunabilir ve uygulanabilir (MOB-037); ilk derlemenin kilitlediği alanlar
|
|
333
|
+
(Bundle ID, paket adı, URL şeması, iOS build numarası, Android version code) ve sürüm Zeyrek'teki değerde kalır, farklı
|
|
334
|
+
Bundle ID / paket adı 409 verir. Aynı Bundle ID / paket adıyla **yeniden eşlenebilir**: yeni okuma açılır, `replace.<satır>` (tek görsellik yuva) ve `replace.asset.screenshot.<dil>.<cihaz>` (ekran görüntüsü seti)
|
|
335
|
+
dolu yuvaları mağazadakiyle değiştirir, raporda `existingKey` dolu ürün yeni ürün açmadan güncellenir.
|
|
333
336
|
|
|
334
337
|
1. `mobile_store_import_start { applicationId, bundleId, packageName }` → bağlantı satırı ve okuma işi.
|
|
335
338
|
2. `mobile_store_import_report` → `state: ready` olunca kovalar: **auto** (Zeyrek'e gelir) · **upload** (siz yüklersiniz:
|
|
336
339
|
ikon, 6.5" ekran görüntüsü) · **kept** (mağazada kalır: beyan içerikleri, ülke fiyatı, promosyon, tüketilen ürün).
|
|
337
340
|
3. `mobile_store_import_mapping` → `scheme` (eski uygulamanın URL şeması, zorunlu), iki mağaza farkı
|
|
338
|
-
(`choice.<satır>`), ürün anahtarı/hak (`product.<i>.key|entitlement`), beyan onayı.
|
|
341
|
+
(`choice.<satır>`), ürün anahtarı/hak (`product.<i>.key|entitlement`; `existingKey` dolu üründe yok sayılır), beyan onayı.
|
|
342
|
+
Mağaza kimliği seçilmez (MOB-038).
|
|
339
343
|
4. `mobile_store_import_apply` → tek işlem; mağazaya hiçbir şey gitmez. Örnek: `store-import-mapping`.
|
|
340
344
|
|
|
341
345
|
**Aboneler — üç kaynak:** eski liste (`mobile_purchase_import`, önce `dryRun` — MOB-039) · mağaza bildirimi (katalogdaki
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"hash": "
|
|
3
|
-
"generatedAt": "2026-11-
|
|
2
|
+
"hash": "34361b013283a252757338ed07d8cdcd70294df1c334d35723a9b194c62d1c4b",
|
|
3
|
+
"generatedAt": "2026-11-03T11:41:34.837Z",
|
|
4
4
|
"types": 377,
|
|
5
5
|
"files": 196,
|
|
6
6
|
"note": "Şemaları üreten backend kaynaklarının parmak izi. Elle düzenlemeyin: 'npm run generate-schemas' yazar, 'npm run schema:check' denetler.",
|
|
@@ -9,4 +9,4 @@
|
|
|
9
9
|
"System.Text.Json.Nodes.JsonNode",
|
|
10
10
|
"System.Text.Json.Nodes.JsonNodeOptions"
|
|
11
11
|
]
|
|
12
|
-
}
|
|
12
|
+
}
|
|
@@ -27,7 +27,7 @@ export function registerDeploymentTools(server, platform) {
|
|
|
27
27
|
const config = platform.config;
|
|
28
28
|
server.registerTool('deployment_start', {
|
|
29
29
|
title: 'Deployment başlat',
|
|
30
|
-
description: 'Projeyi kaynak environment\'tan hedef environment\'a deploy eder. Asenkron bir saga\'dır: sonuç bu yanıtta bitmez, deployment_status ile izleyin. Environment id\'lerini project_get çıktısından alın. BPM: süreç tanımları ve iş takvimleri taşınır — hedefte farklı aktif model yeni sürüm olarak yayınlanır (production\'da gelişte aktif), hedefin uyarlaması korunur; uyarlama, örnek, görev ve defter taşınmaz; kaynakta olmayan tanım silinir, açık örneği varsa emekliye ayrılır. KAYNAK YALNIZ DEVELOPMENT\'TIR: dal ya da production kaynak verilirse 400 (CantDeployFromBranchException) — dalı önce development\'a merge edin. ÖN DENETİM: deploy başlamadan production verisi denetlenir; veriyi bozacak ya da silecek her değişiklik 400 (DeploymentDataRiskException) ile listelenir ve deploy BAŞLAMAZ — biçim \'tablo.alan: tür (satır)\', türler not-null | unique | field-removed | table-removed | localization-move. YALNIZ TANIM TAŞINIR: tablo satırları ancak tabloda recordTransferMode (\'all\' | \'specific\' + transferRowIds) açıksa gider, çeviri ve junction satırları ana tabloyla birlikte. Kayıt taşıması \'all\' olan tabloda production development\'ın AYNASIDIR (kaynakta olmayan satır ve çevirisi silinir). DOSYA yalnız id referansıyla gider (file tipli prop { type:\'file\', ref:<fileId> } ya da taşınan satırın dosya sütunu); sayfaya düz yazılan /d/ serve URL\'si /p/\'ye çevrilir ama dosya kopyalanmaz, production\'da 404 döner — platform_guide(\'deployment\'). Microfunction\'ın yalnız YAYINLANMIŞ kodu taşınır ve hedefte yayınlanır; hiç yayınlanmamış olan hedefte taslak kalır. Zamanlanmış işin duraklatma durumu taşınır. YAYINLANMAMIŞ TASLAK TAŞINMAZ: kaynakta taslağı olan süreçler yanıtta unpublishedDrafts ({ slug, name, draftVersionNumber, activeVersionNumber }) ve note ile listelenir; hedefte aktif sürüm kalır. Taşımak için taslağı kaynakta yayınlayın (requireGreenScenarios açıksa önce senaryoları taslak üzerinde koşun), sonra yeniden deploy edin. DELTA (varsayılan): yalnız içerik özeti production\'dakinden farklı tanımlar taşınır, kaynakta olmayan tanım silinir; entity, rol, erişim politikası, bileşen, dosya, süreç tanımı, organizasyon yapısı ve tablo satırları her deploy\'da tam taşınır; klasör silme taşınmaz. Kaynağın ya da production\'ın özeti güvenilir değilse (son tamamlanmış özet denetimi güncel biçimde bir fill ya da farksız bir check değilse) deploy kendiliğinden tam koşar; fullMode:true her tanımı taşır. Hangi kipte koştuğu ve modül başına sayılar deployment_status yanıtında (mode, counters).',
|
|
30
|
+
description: 'Projeyi kaynak environment\'tan hedef environment\'a deploy eder. Asenkron bir saga\'dır: sonuç bu yanıtta bitmez, deployment_status ile izleyin. Environment id\'lerini project_get çıktısından alın. BPM: süreç tanımları ve iş takvimleri taşınır — hedefte farklı aktif model yeni sürüm olarak yayınlanır (production\'da gelişte aktif), hedefin uyarlaması korunur; uyarlama, örnek, görev ve defter taşınmaz; kaynakta olmayan tanım silinir, açık örneği varsa emekliye ayrılır. KAYNAK YALNIZ DEVELOPMENT\'TIR: dal ya da production kaynak verilirse 400 (CantDeployFromBranchException) — dalı önce development\'a merge edin. ÖN DENETİM: deploy başlamadan production verisi denetlenir; veriyi bozacak ya da silecek her değişiklik 400 (DeploymentDataRiskException) ile listelenir ve deploy BAŞLAMAZ — biçim \'tablo.alan: tür (satır)\', türler not-null | unique | field-removed | table-removed | localization-move. YALNIZ TANIM TAŞINIR: tablo satırları ancak tabloda recordTransferMode (\'all\' | \'specific\' + transferRowIds) açıksa gider, çeviri ve junction satırları ana tabloyla birlikte. Kayıt taşıması \'all\' olan tabloda production development\'ın AYNASIDIR (kaynakta olmayan satır ve çevirisi silinir) — tabloda recordTransferSkipExisting açıksa ayna yoktur, production\'da var olan satır güncellenmez, yalnız eksik satır eklenir. DOSYA yalnız id referansıyla gider (file tipli prop { type:\'file\', ref:<fileId> } ya da taşınan satırın dosya sütunu); sayfaya düz yazılan /d/ serve URL\'si /p/\'ye çevrilir ama dosya kopyalanmaz, production\'da 404 döner — platform_guide(\'deployment\'). Microfunction\'ın yalnız YAYINLANMIŞ kodu taşınır ve hedefte yayınlanır; hiç yayınlanmamış olan hedefte taslak kalır. Zamanlanmış işin duraklatma durumu taşınır. YAYINLANMAMIŞ TASLAK TAŞINMAZ: kaynakta taslağı olan süreçler yanıtta unpublishedDrafts ({ slug, name, draftVersionNumber, activeVersionNumber }) ve note ile listelenir; hedefte aktif sürüm kalır. Taşımak için taslağı kaynakta yayınlayın (requireGreenScenarios açıksa önce senaryoları taslak üzerinde koşun), sonra yeniden deploy edin. DELTA (varsayılan): yalnız içerik özeti production\'dakinden farklı tanımlar taşınır, kaynakta olmayan tanım silinir; entity, rol, erişim politikası, bileşen, dosya, süreç tanımı, organizasyon yapısı ve tablo satırları her deploy\'da tam taşınır; klasör silme taşınmaz. Kaynağın ya da production\'ın özeti güvenilir değilse (son tamamlanmış özet denetimi güncel biçimde bir fill ya da farksız bir check değilse) deploy kendiliğinden tam koşar; fullMode:true her tanımı taşır. Hangi kipte koştuğu ve modül başına sayılar deployment_status yanıtında (mode, counters).',
|
|
31
31
|
inputSchema: {
|
|
32
32
|
projectId: guid,
|
|
33
33
|
sourceEnvironmentId: guid,
|
|
@@ -590,7 +590,7 @@ export function registerMobileStoreTools(server, platform, storeArt = {}) {
|
|
|
590
590
|
}, handle(config, async ({ buildId: id }) => buildSummary(unwrap(await platform.org('POST', `/mobile-builds/${id}/cancel`)), new Date().toISOString())));
|
|
591
591
|
server.registerTool('mobile_asset_create', {
|
|
592
592
|
title: 'Mağaza görseli yükle',
|
|
593
|
-
description: `Mağaza görselini yükler (POST mobile-store/{appId}/assets, multipart). Kaynak path (gateway'in okuyabildiği yerel dosya) ya da base64 content'tir — dosya ajanın bağlamına girmez. Yuvalar: derleme görselleri icon (1024×1024 PNG, alfasız), adaptiveForeground / adaptiveBackground / adaptiveMonochrome (
|
|
593
|
+
description: `Mağaza görselini yükler (POST mobile-store/{appId}/assets, multipart). Kaynak path (gateway'in okuyabildiği yerel dosya) ya da base64 content'tir — dosya ajanın bağlamına girmez. Yuvalar: derleme görselleri icon (1024×1024 PNG, alfasız), adaptiveForeground / adaptiveBackground / adaptiveMonochrome (kare, ≥ 512×512 PNG), splash (≥ 1242×2436 PNG) — dilsizdir, locale verilmez; mağaza görselleri featureGraphic (1024×500, alfasız), promo, screenshot (deviceClass zorunlu, locale önerilir: 'screenshot/tr/iphone69'); reviewAttachment (dilsiz, PNG/JPEG) App Review'a ek görseldir — yalnız app-store-review gönderimine girer. Tuzak: screenshot ve promo dışındaki türler TEKLİDİR — yükleme yuvadaki önceki görselin YERİNE geçer ve eskisi silinir. Yuva başına en çok 10 ekran görüntüsü, dosya ≤ 10 MB, PNG ya da JPEG (derleme görseli yalnız PNG). Ölçü, biçim ve alfa backend'de denetlenir; 422 hangi ölçünün beklendiğini söyler. EKRAN GÖRÜNTÜSÜ uygulamanın kendi sayfasından üretilir: önce page_screenshot { environment: 'production', applicationSlug: <uygulama id'si — production'ın kendi slug'ına çözülür, APP-002>, pageSlug, device, format: 'jpeg', quality: 92, language, colorScheme: 'light', outPath }, sonra bu araç { path: <outPath>, kind: 'screenshot', deviceClass, locale }. Cihaz sınıfı → device: ${captureTable}. JPEG şarttır: iPhone ve iPad ekran görüntüsünde alfa kanalı reddedilir. Giriş/splash ekranını çekmeyin (App Review 2.3.3: uygulama kullanımda gösterilir). Sıra: mobile_asset_update; silme: mobile_asset_delete; liste: mobile_store_get { detail: ['assets'] }.`,
|
|
594
594
|
inputSchema: {
|
|
595
595
|
applicationId,
|
|
596
596
|
path: z.string().min(1).optional().describe("Gateway sürecinin okuyabildiği yerel PNG/JPEG yolu (page_screenshot outPath'i); content ile birlikte verilmez"),
|
|
@@ -18,7 +18,7 @@ export function registerMobileStoreImportTools(server, platform) {
|
|
|
18
18
|
const config = platform.config;
|
|
19
19
|
server.registerTool('mobile_store_import_start', {
|
|
20
20
|
title: 'Mağazadan içe aktarmayı başlat',
|
|
21
|
-
description: "Yayındaki uygulamanın App Store ve Google Play kaydını OKUMAYA başlar (POST mobile-store/{appId}/imports; ADR 0028). Önce bağlantı eşzamanlı doğrulanır (connection { ios: found | not_found | no_access, android: … }, upload anahtarı uyarısı), sonra arka plan işi iki mağazayı okur ve üç kovalı rapor yazar (Gelir · Sen yüklersin · Mağazada kalır). Okuma mağazaya HİÇBİR ŞEY yazmaz, Zeyrek'te de hiçbir şey değişmez — değişiklik yalnız mobile_store_import_apply ile olur.
|
|
21
|
+
description: "Yayındaki uygulamanın App Store ve Google Play kaydını OKUMAYA başlar (POST mobile-store/{appId}/imports; ADR 0028). Önce bağlantı eşzamanlı doğrulanır (connection { ios: found | not_found | no_access, android: … }, upload anahtarı uyarısı), sonra arka plan işi iki mağazayı okur ve üç kovalı rapor yazar (Gelir · Sen yüklersin · Mağazada kalır). Okuma mağazaya HİÇBİR ŞEY yazmaz, Zeyrek'te de hiçbir şey değişmez — değişiklik yalnız mobile_store_import_apply ile olur. İlk derlemeden sonra da çalışır: yeniden okuma (yeniden eşleme) ve Uygula her zaman açıktır; ilk derlemenin kilitlediği alanlar (Bundle ID, paket adı, URL şeması, iOS build numarası, Android version code) ve sürüm Zeyrek'teki değerde kalır. Kilitli kimlikten farklı bundleId / packageName verilirse 409 MobileStoreImportLockedException (MOB-037). Yeni okuma açık eski kaydı vazgeçilmiş sayar. Sonra mobile_store_import_report ile durumu okuyun (state queued → reading → ready).",
|
|
22
22
|
inputSchema: {
|
|
23
23
|
applicationId,
|
|
24
24
|
bundleId: z.string().min(1).optional().describe("App Store'daki Bundle ID ('com.anatoli.app'); yalnız Android ise verilmez"),
|
|
@@ -34,7 +34,7 @@ export function registerMobileStoreImportTools(server, platform) {
|
|
|
34
34
|
}
|
|
35
35
|
catch (error) {
|
|
36
36
|
if (error instanceof PlatformApiError && error.status === 409) {
|
|
37
|
-
throw new PlatformApiError(`${error.message} — MOB-037:
|
|
37
|
+
throw new PlatformApiError(`${error.message} — MOB-037: verilen Bundle ID / paket adı uygulamanın kilitlediğinden farklı; yeniden eşleme için kilitli Bundle ID / paket adını verin (mobile_store_get ile okunur).`, 409, error.code);
|
|
38
38
|
}
|
|
39
39
|
throw error;
|
|
40
40
|
}
|
|
@@ -54,7 +54,7 @@ export function registerMobileStoreImportTools(server, platform) {
|
|
|
54
54
|
}));
|
|
55
55
|
server.registerTool('mobile_store_import_mapping', {
|
|
56
56
|
title: 'İçe aktarma seçimlerini kaydet',
|
|
57
|
-
description: "Raporun Zeyrek'e nasıl yazılacağını kaydeder (PUT mobile-store/{appId}/imports/{importId}/mapping; seçimler birleşmez, verilen sözlük kaydı değiştirir — önce mobile_store_import_report ile okuyun). Anahtarlar: scheme (ZORUNLU — URL şeması mağazadan okunamaz, eski uygulamanınki girilir; MOB-041/P-31) · choice.<satır> = apple | play | custom ve custom.<satır> (iki mağazada farklı metin, K6) · skip.<satır> / skip.language.<dil> = true · replace.<satır> = true (ikon, adaptive ön plan ya da öne çıkan görsel yuvası doluysa üzerine yazar; verilmezse mevcut görsel korunur) · target.language.<mağaza>.<dil> = <Zeyrek dili> (eşlenemeyen dilin metnini o dile yazar; eşlenmiş satırı ezmez) · product.<i>.{key, entitlement, period, trial, price, skip} (i = rapordaki ürün sırası; anahtar ve hak ^[a-z][a-z0-9_]{1,63}$) · declaration.<anahtar> = true. Taslak kural ihlaliyle de saklanır: ihlaller yanıtın violations listesinde [{ row, field, code }] döner (choice_required, period_required, price_required, key_taken…) ve mobile_store_import_apply onlar düzelmeden 422 verir. İçe aktarılan ürünün MAĞAZA KİMLİĞİ seçilmez — mağazadan gelir ve kilitlidir (MOB-038).",
|
|
57
|
+
description: "Raporun Zeyrek'e nasıl yazılacağını kaydeder (PUT mobile-store/{appId}/imports/{importId}/mapping; seçimler birleşmez, verilen sözlük kaydı değiştirir — önce mobile_store_import_report ile okuyun). Anahtarlar: scheme (ZORUNLU — URL şeması mağazadan okunamaz, eski uygulamanınki girilir; MOB-041/P-31) · choice.<satır> = apple | play | custom ve custom.<satır> (iki mağazada farklı metin, K6) · skip.<satır> / skip.language.<dil> = true · replace.<satır> = true (ikon, adaptive ön plan ya da öne çıkan görsel yuvası doluysa üzerine yazar; verilmezse mevcut görsel korunur) · replace.asset.screenshot.<dil>.<cihaz> = true (o yuvadaki ekran görüntüsü setini siler, mağazadakileri yazar; verilmezse mevcutlar korunur ve yuva başına 10 sınırı mevcutları da sayar — taşan satır asset_invalid) · target.language.<mağaza>.<dil> = <Zeyrek dili> (eşlenemeyen dilin metnini o dile yazar; eşlenmiş satırı ezmez) · product.<i>.{key, entitlement, period, trial, price, skip} (i = rapordaki ürün sırası; anahtar ve hak ^[a-z][a-z0-9_]{1,63}$) · declaration.<anahtar> = true. Taslak kural ihlaliyle de saklanır: ihlaller yanıtın violations listesinde [{ row, field, code }] döner (choice_required, period_required, price_required, key_taken…) ve mobile_store_import_apply onlar düzelmeden 422 verir. İçe aktarılan ürünün MAĞAZA KİMLİĞİ seçilmez — mağazadan gelir ve kilitlidir (MOB-038). Raporda existingKey dolu ürün Zeyrek'te aynı mağaza kimliğiyle duran üründür: Uygula yeni ürün açmaz, onu günceller (fiyat, süre, deneme, metin, mağaza modeli); anahtar ve hak Zeyrek'tekidir, product.<i>.key / entitlement yok sayılır; tür farklıysa kind ihlali.",
|
|
58
58
|
inputSchema: {
|
|
59
59
|
applicationId,
|
|
60
60
|
importId,
|
|
@@ -69,7 +69,7 @@ export function registerMobileStoreImportTools(server, platform) {
|
|
|
69
69
|
}));
|
|
70
70
|
server.registerTool('mobile_store_import_apply', {
|
|
71
71
|
title: 'İçe aktarmayı uygula',
|
|
72
|
-
description: "Onaylanan raporu TEK İŞLEMDE Zeyrek'e yazar (POST mobile-store/{appId}/imports/{importId}/apply): mağaza ayarı, beyanlar (kaynak import), görseller, ürün kataloğu (saklanan mağaza kimlikleriyle, değişiklik beklemez) ve kimlik kilidi; mağaza tabanı farka kaydedilir. Mağazaya HİÇBİR ŞEY gönderilmez. Uygulanmış kayıt yeniden uygulanmaz (409). Sonra: mobile_product_list (içe aktarılan ürünler), yayından önce mobile_store_diff ve ön kontrol P-24…P-31.",
|
|
72
|
+
description: "Onaylanan raporu TEK İŞLEMDE Zeyrek'e yazar (POST mobile-store/{appId}/imports/{importId}/apply): mağaza ayarı, beyanlar (kaynak import), görseller, ürün kataloğu (saklanan mağaza kimlikleriyle, değişiklik beklemez) ve kimlik kilidi; mağaza tabanı farka kaydedilir. Mağazaya HİÇBİR ŞEY gönderilmez. Uygulanmış kayıt yeniden uygulanmaz (409); yeniden eşleme için (ilk derlemeden sonra da) mobile_store_import_start ile yeni okuma açılır. İlk derlemenin kilitlediği alanlar ve sürüm yazılmaz, Zeyrek'teki değer kalır. Sonra: mobile_product_list (içe aktarılan ürünler), yayından önce mobile_store_diff ve ön kontrol P-24…P-31.",
|
|
73
73
|
inputSchema: { applicationId, importId },
|
|
74
74
|
annotations: writes
|
|
75
75
|
}, handle(config, async ({ applicationId: appId, importId: id }) => importReportOutline(unwrap(await platform.org('POST', `/mobile-store/${appId}/imports/${id}/apply`)))));
|
package/package.json
CHANGED