@appaflytech/zeyrek-ai-mcp 0.0.43 → 0.0.45
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 +86 -2
- package/dist/knowledge/componentCatalog.js +63 -26
- package/dist/knowledge/componentEvents.js +6 -0
- package/dist/knowledge/connectDataBind.js +43 -6
- package/dist/knowledge/connectDataDefinition.js +74 -3
- package/dist/knowledge/connectDataRules.js +14 -0
- package/dist/knowledge/mobileComponentCatalog.js +66 -7
- package/dist/knowledge/mobileStore.js +61 -2
- package/dist/knowledge/platform/mobile.js +1 -1
- package/dist/knowledge/platform/mobileRules.js +2 -1
- package/dist/knowledge/platform/mobileTabs.js +31 -2
- package/dist/knowledge/platform/web.js +1 -1
- package/dist/knowledge/rules.js +195 -4
- package/dist/knowledge/textHooks.js +434 -0
- package/dist/platform/capture/capture.js +1 -1
- package/dist/platform/capture/readiness.js +4 -0
- package/dist/platform/errors.js +22 -2
- package/dist/prompts/mobilePublish.js +21 -0
- package/dist/resources/examples/flow-biometric-confirm.json +199 -0
- package/dist/resources/examples/microfunction-node-dependencies.json +19 -0
- package/dist/resources/guides/access.md +3 -3
- package/dist/resources/guides/component.md +20 -4
- package/dist/resources/guides/deployment.md +98 -0
- package/dist/resources/guides/entity.md +1 -1
- package/dist/resources/guides/expressions.md +5 -1
- package/dist/resources/guides/external-component.md +6 -4
- package/dist/resources/guides/merge.md +81 -4
- package/dist/resources/guides/microfunction.md +104 -9
- package/dist/resources/guides/microservice.md +34 -5
- package/dist/resources/guides/mobile-connect-data.md +70 -0
- package/dist/resources/guides/mobile-flow.md +64 -0
- package/dist/resources/guides/mobile-publish.md +161 -16
- package/dist/resources/guides/mobile-steps.md +17 -0
- package/dist/resources/guides/mobile.md +41 -23
- package/dist/resources/guides/page.md +11 -5
- package/dist/resources/guides/translation.md +95 -0
- package/dist/resources/knowledge.js +3 -1
- package/dist/resources/prompts/mobile-publish-prepare.md +89 -0
- package/dist/resources/schema-fingerprint.json +4 -4
- package/dist/resources/schemas/ApplyMicrofunctionArchiveChangesCommand.json +76 -0
- package/dist/resources/schemas/ConnectDataDescribeDto.json +44 -0
- package/dist/resources/schemas/ConnectDataResultDto.json +10 -0
- package/dist/resources/schemas/CreateMicrofunctionCommand.json +8 -0
- package/dist/resources/schemas/InvokeMicrofunctionCommand.json +0 -4
- package/dist/resources/schemas/MobileStorePreflightScope.json +13 -0
- package/dist/resources/schemas/StartMobileBuildCommand.json +35 -1
- package/dist/resources/schemas/UpdateMicrofunctionCommand.json +8 -0
- package/dist/resources/schemas/UpsertMobileStoreSettingsCommand.json +75 -0
- package/dist/server.js +2 -0
- package/dist/tools/common.js +6 -0
- package/dist/tools/components.js +19 -6
- package/dist/tools/connectData.js +9 -4
- package/dist/tools/deployments.js +1 -1
- package/dist/tools/designSchemaPatch.js +16 -4
- package/dist/tools/environments.js +3 -3
- package/dist/tools/files.js +1 -1
- package/dist/tools/flows.js +29 -3
- package/dist/tools/layouts.js +32 -12
- package/dist/tools/merges.js +8 -8
- package/dist/tools/microfunctions.js +53 -3
- package/dist/tools/mobileStore.js +83 -21
- package/dist/tools/pages.js +59 -24
- package/dist/tools/platformInfo.js +4 -2
- package/dist/tools/textHookGuard.js +116 -0
- package/package.json +2 -2
|
@@ -291,7 +291,7 @@ function unsortableReason(kind) {
|
|
|
291
291
|
* Girdi + kabiliyet + bağlanabilir prop kaydından tanım. Block bulgusu varsa tanım yine döner
|
|
292
292
|
* (dryRun'da görülsün) ama çağıran yazmaz.
|
|
293
293
|
*/
|
|
294
|
-
export function buildDefinition(input, describe, connectable, connectablePaths = [], itemProps = []) {
|
|
294
|
+
export function buildDefinition(input, describe, connectable, connectablePaths = [], itemProps = [], platform = 'web') {
|
|
295
295
|
const findings = [];
|
|
296
296
|
const block = (ruleId, message) => { findings.push({ ruleId, severity: 'block', message }); };
|
|
297
297
|
const warn = (ruleId, message) => { findings.push({ ruleId, severity: 'warn', message }); };
|
|
@@ -401,9 +401,18 @@ export function buildDefinition(input, describe, connectable, connectablePaths =
|
|
|
401
401
|
block('CD-002', `'${slug}' aranamaz: arama yalnız korumasız, içerir (icontains) işleci olan metin alanında çalışır — platform bu alanı aramada YOK SAYAR (geçerli hiç alan kalmazsa 422 ConnectDataFilterNotAllowed). Aranabilir bir metin alanı seçin.`);
|
|
402
402
|
}
|
|
403
403
|
}
|
|
404
|
-
const
|
|
404
|
+
const givenLookup = input.lookup !== undefined
|
|
405
405
|
? input.lookup
|
|
406
406
|
: connectable?.lookup && input.source.kind === 'entity' ? { fields: [], mode: 'modal' } : null;
|
|
407
|
+
const isMobile = platform === 'mobile';
|
|
408
|
+
// Telefon satırının varsayılan başlığı: lookup label alanını gösteriyorsa (ya da alanlar türetiliyorsa) o, yoksa ilk alan
|
|
409
|
+
// (screen-builder `defaultMobileRow` aynası).
|
|
410
|
+
const lookupSlugs = (givenLookup?.fields ?? []).map(item => item.slug).filter(slug => slug?.trim());
|
|
411
|
+
const rowTitle = roles.label && (lookupSlugs.length === 0 || lookupSlugs.includes(roles.label)) ? roles.label : lookupSlugs[0];
|
|
412
|
+
const rootLookup = givenLookup && isMobile
|
|
413
|
+
? { ...givenLookup, mobileMode: givenLookup.mobileMode ?? 'sheet', ...(givenLookup.mobileRow || !rowTitle ? {} : { mobileRow: { title: rowTitle } }) }
|
|
414
|
+
: givenLookup;
|
|
415
|
+
const mobile = input.mobile !== undefined ? input.mobile : isMobile && (isListComponent || rootLookup) ? { infiniteScroll: true } : undefined;
|
|
407
416
|
const definition = {
|
|
408
417
|
version: 1,
|
|
409
418
|
source: { kind: input.source.kind, id: input.source.id, ...(input.source.slug ?? describe.source?.slug ? { slug: input.source.slug ?? describe.source?.slug } : {}) },
|
|
@@ -423,11 +432,27 @@ export function buildDefinition(input, describe, connectable, connectablePaths =
|
|
|
423
432
|
defaults: input.edit?.defaults ?? {},
|
|
424
433
|
writeMode: input.edit?.writeMode ?? 'atomic'
|
|
425
434
|
},
|
|
426
|
-
refresh: { afterWrite: input.refresh?.afterWrite ?? 'reload', poll: input.refresh?.poll ?? null }
|
|
435
|
+
refresh: { afterWrite: input.refresh?.afterWrite ?? 'reload', poll: input.refresh?.poll ?? null },
|
|
436
|
+
...(mobile ? { mobile } : {}),
|
|
437
|
+
...(input.mobileCard ? { mobileCard: input.mobileCard } : {})
|
|
427
438
|
},
|
|
428
439
|
...(input.params && Object.keys(input.params).length > 0 ? { params: input.params } : {}),
|
|
429
|
-
...(rootLookup ? { lookup: rootLookup } : {})
|
|
440
|
+
...(rootLookup ? { lookup: rootLookup } : {}),
|
|
441
|
+
...(input.grouping ? { grouping: input.grouping } : {})
|
|
430
442
|
};
|
|
443
|
+
const groups = (connectable?.wizardSteps ?? []).includes('grouping');
|
|
444
|
+
if (groups && !input.grouping) {
|
|
445
|
+
block('CD-019', `Bu bileşen satırları bölümlere ayırır: gruplama alanı seçin — grouping: { by: '<alan>', sectionOrder: 'asc' | 'desc' | 'asis', dateBucket?: 'day' | 'week' | 'month' } verin. Sunucu sırayı gruplama alanıyla başlatır; date alanında gün/hafta/ay kovası satıra __section olarak yazılır, datetime alanında cihaz yerel günden kovalar.`);
|
|
446
|
+
}
|
|
447
|
+
if (groups && input.grouping?.dateBucket && !describe.fields.find(item => item.slug === input.grouping?.by)?.dateBuckets?.length) {
|
|
448
|
+
block('CD-019', `grouping.dateBucket '${input.grouping.dateBucket}': '${input.grouping.by}' tarih alanı değil (describe dateBuckets yok) — platform 422 grouping.dateBucket döner. Tarih/tarih-saat alanı seçin ya da dateBucket'ı kaldırın.`);
|
|
449
|
+
}
|
|
450
|
+
if (groups && input.grouping && input.grouping.sectionOrder !== 'asis' && describe.fields.find(item => item.slug === input.grouping?.by)?.sortable === false) {
|
|
451
|
+
block('CD-019', `grouping.by '${input.grouping.by}' bu kaynakta sıralanamaz (describe sortable yok): sunucu gruplu listeyi gruplama alanıyla sıralar — platform kaydı 422 connect-data-grouping-not-sortable döner. Sıralanabilir bir alan seçin ya da sectionOrder: 'asis' verin.`);
|
|
452
|
+
}
|
|
453
|
+
if (!groups && input.grouping) {
|
|
454
|
+
block('CD-020', `grouping yalnız satırları bölümleyen bileşende (component_get.connectData.props.<prop>.wizardSteps 'grouping' — mobilde grouped-list) yazılır; bu bileşen gruplamayı okumaz. grouping'i kaldırın.`);
|
|
455
|
+
}
|
|
431
456
|
const declaredParameters = (describe.source?.parameters ?? []).map(parameter => parameter.name);
|
|
432
457
|
for (const name of Object.keys(input.params ?? {}).filter(item => !declaredParameters.some(declared => declared.toLowerCase() === item.toLowerCase()))) {
|
|
433
458
|
block('CD-013', `params.${name}: '${describe.source?.slug ?? describe.source?.id}' böyle bir parametre almaz. Alınanlar: ${declaredParameters.join(' · ') || '(yok)'} (describe source.parameters; sayfalama, sıralama, dinamik filtre ve dil parametreleri motorundur).`);
|
|
@@ -559,6 +584,9 @@ export function inputFromExisting(input, existing) {
|
|
|
559
584
|
pageSize: input.pageSize ?? existing.page?.limit,
|
|
560
585
|
params: input.params ?? (existing.params && Object.keys(existing.params).length > 0 ? { ...existing.params } : undefined),
|
|
561
586
|
lookup: input.lookup !== undefined ? input.lookup : existing.lookup ?? null,
|
|
587
|
+
mobile: input.mobile !== undefined ? input.mobile : existing.behavior?.mobile ?? undefined,
|
|
588
|
+
mobileCard: input.mobileCard !== undefined ? input.mobileCard : existing.behavior?.mobileCard ?? undefined,
|
|
589
|
+
grouping: input.grouping !== undefined ? input.grouping : existing.grouping ?? undefined,
|
|
562
590
|
language: input.language ?? existing.language ?? undefined,
|
|
563
591
|
filterable: input.filterable ?? [...(existing.behavior?.filterable ?? [])],
|
|
564
592
|
searchable: input.searchable ?? [...(existing.behavior?.searchable ?? [])],
|
|
@@ -644,10 +672,12 @@ export function renameDefinitionPaths(definition, renames) {
|
|
|
644
672
|
...(edit.defaults ? { defaults: Object.fromEntries(Object.entries(edit.defaults).map(([path, value]) => [rename(path), value])) } : {})
|
|
645
673
|
}
|
|
646
674
|
}
|
|
647
|
-
: {})
|
|
675
|
+
: {}),
|
|
676
|
+
...(definition.behavior.mobileCard ? { mobileCard: renameMobileParts(definition.behavior.mobileCard, rename) } : {})
|
|
648
677
|
}
|
|
649
678
|
}
|
|
650
679
|
: {}),
|
|
680
|
+
...(definition.grouping ? { grouping: { ...definition.grouping, by: rename(definition.grouping.by) } } : {}),
|
|
651
681
|
...(definition.lookup
|
|
652
682
|
? {
|
|
653
683
|
lookup: {
|
|
@@ -662,7 +692,8 @@ export function renameDefinitionPaths(definition, renames) {
|
|
|
662
692
|
}
|
|
663
693
|
}
|
|
664
694
|
: {}),
|
|
665
|
-
...(definition.lookup.sort ? { sort: definition.lookup.sort.map(item => ({ ...item, field: rename(item.field) })) } : {})
|
|
695
|
+
...(definition.lookup.sort ? { sort: definition.lookup.sort.map(item => ({ ...item, field: rename(item.field) })) } : {}),
|
|
696
|
+
...(definition.lookup.mobileRow ? { mobileRow: renameMobileParts(definition.lookup.mobileRow, rename) } : {})
|
|
666
697
|
}
|
|
667
698
|
}
|
|
668
699
|
: {})
|
|
@@ -706,6 +737,10 @@ export function capabilityUnderRecordedNames(describe) {
|
|
|
706
737
|
return Object.keys(recorded).length === 0 ? describe : { ...describe, fields: describe.fields.map(field => ({ ...field, slug: renamePath(field.slug, recorded) })) };
|
|
707
738
|
}
|
|
708
739
|
/** Bind girdisindeki yolları (alanlar, roller, expand, filtre, sıralama, filterable/searchable, edit) yeniden adlandırır. */
|
|
740
|
+
/** Telefon satırı/kartı parçalarının (`title`, `subtitle`, `trailing`, `fields`) yollarını çevirir. */
|
|
741
|
+
function renameMobileParts(parts, rename) {
|
|
742
|
+
return Object.fromEntries(Object.entries(parts).map(([part, value]) => [part, typeof value === 'string' ? rename(value) : Array.isArray(value) ? value.map(item => rename(String(item))) : value]));
|
|
743
|
+
}
|
|
709
744
|
export function renameBindInput(input, renames) {
|
|
710
745
|
if (Object.keys(renames).length === 0)
|
|
711
746
|
return input;
|
|
@@ -724,6 +759,8 @@ export function renameBindInput(input, renames) {
|
|
|
724
759
|
...(input.sort ? { sort: input.sort.map(item => ({ ...item, field: rename(item.field) })) } : {}),
|
|
725
760
|
...(input.filterable ? { filterable: input.filterable.map(rename) } : {}),
|
|
726
761
|
...(input.searchable ? { searchable: input.searchable.map(rename) } : {}),
|
|
762
|
+
...(input.mobileCard ? { mobileCard: renameMobileParts(input.mobileCard, rename) } : {}),
|
|
763
|
+
...(input.grouping ? { grouping: { ...input.grouping, by: rename(input.grouping.by) } } : {}),
|
|
727
764
|
...(input.edit
|
|
728
765
|
? {
|
|
729
766
|
edit: {
|
|
@@ -27,6 +27,35 @@ const filterSchema = z.lazy(() => z.object({
|
|
|
27
27
|
}).strict());
|
|
28
28
|
const sortSchema = z.object({ field: z.string(), ascending: z.boolean(), rawSql: z.null().optional() }).strict();
|
|
29
29
|
const pageSchema = z.object({ mode: z.enum(['offset', 'cursor', 'client']), limit: z.number().int() }).strict();
|
|
30
|
+
/** Telefonda lookup yüzeyi; yoksa `sheet` (backend `ConnectDataDefinitionValidator.LookupMobileModes`). */
|
|
31
|
+
export const CONNECT_DATA_LOOKUP_MOBILE_MODES = ['sheet', 'fullscreen'];
|
|
32
|
+
const mobileRowSchema = z.object({ title: z.string(), subtitle: z.string().nullable().optional(), trailing: z.string().nullable().optional() }).strict();
|
|
33
|
+
/** Backend `ConnectDataMobileBehaviorModel`: telefon "Telefonda" kutusunun anahtarları; sunucu okumaz. */
|
|
34
|
+
export const mobileBehaviorSchema = z.object({
|
|
35
|
+
search: z.boolean().nullable().optional(),
|
|
36
|
+
infiniteScroll: z.boolean().nullable().optional(),
|
|
37
|
+
pullToRefresh: z.boolean().nullable().optional(),
|
|
38
|
+
recentSelections: z.boolean().nullable().optional(),
|
|
39
|
+
filterChips: z.boolean().nullable().optional(),
|
|
40
|
+
swipeDelete: z.boolean().nullable().optional()
|
|
41
|
+
}).strict();
|
|
42
|
+
/** Backend `ConnectDataMobileCardModel`: datatable kart görünümü telefonda (seçili yollar). */
|
|
43
|
+
export const mobileCardSchema = z.object({ title: z.string(), fields: z.array(z.string()).nullable().optional(), trailing: z.string().nullable().optional() }).strict();
|
|
44
|
+
/** Backend `ConnectDataRules.GroupingDateBuckets` / `GroupingSectionOrders` (kök ADR 0019). */
|
|
45
|
+
export const CONNECT_DATA_GROUPING_DATE_BUCKETS = ['day', 'week', 'month'];
|
|
46
|
+
export const CONNECT_DATA_GROUPING_SECTION_ORDERS = ['asc', 'desc', 'asis'];
|
|
47
|
+
/**
|
|
48
|
+
* Backend `ConnectDataGroupingModel`: gruplu listenin bölümlemesi. Sunucu sırayı `by` ile başlatır (`asis` hariç),
|
|
49
|
+
* `dateBucket` varsa `date` alanında satıra `__section` yazar (`datetime` cihazda kovalanır). Değerler metin olarak alınır, kural `connectDataShapeIssues`'ta.
|
|
50
|
+
*/
|
|
51
|
+
export const groupingSchema = z.object({
|
|
52
|
+
by: z.string(),
|
|
53
|
+
dateBucket: z.string().nullable().optional(),
|
|
54
|
+
sectionOrder: z.string().nullable().optional(),
|
|
55
|
+
otherSectionTitle: z.string().nullable().optional(),
|
|
56
|
+
stickyHeaders: z.boolean().nullable().optional(),
|
|
57
|
+
showCounts: z.boolean().nullable().optional()
|
|
58
|
+
}).strict();
|
|
30
59
|
const behaviorSchema = z.object({
|
|
31
60
|
filterable: z.array(z.string()).nullable().optional(),
|
|
32
61
|
searchable: z.array(z.string()).nullable().optional(),
|
|
@@ -40,14 +69,18 @@ const behaviorSchema = z.object({
|
|
|
40
69
|
defaults: z.record(z.unknown()).nullable().optional(),
|
|
41
70
|
writeMode: z.enum(['atomic', 'partial']).optional()
|
|
42
71
|
}).strict().nullable().optional(),
|
|
43
|
-
refresh: z.object({ afterWrite: z.string().nullable().optional(), poll: z.number().nullable().optional() }).strict().nullable().optional()
|
|
72
|
+
refresh: z.object({ afterWrite: z.string().nullable().optional(), poll: z.number().nullable().optional() }).strict().nullable().optional(),
|
|
73
|
+
mobile: mobileBehaviorSchema.nullable().optional(),
|
|
74
|
+
mobileCard: mobileCardSchema.nullable().optional()
|
|
44
75
|
}).strict();
|
|
45
76
|
export const lookupSchema = z.lazy(() => z.object({
|
|
46
77
|
fields: z.array(fieldSchema).nullable().optional(),
|
|
47
78
|
behavior: behaviorSchema.nullable().optional(),
|
|
48
79
|
sort: z.array(sortSchema).nullable().optional(),
|
|
49
80
|
page: pageSchema.nullable().optional(),
|
|
50
|
-
mode: z.string().nullable().optional()
|
|
81
|
+
mode: z.string().nullable().optional(),
|
|
82
|
+
mobileMode: z.string().nullable().optional(),
|
|
83
|
+
mobileRow: mobileRowSchema.nullable().optional()
|
|
51
84
|
}).strict());
|
|
52
85
|
const fieldSchema = z.lazy(() => z.object({
|
|
53
86
|
id: z.string().uuid().nullable().optional(),
|
|
@@ -67,7 +100,8 @@ export const connectDataDefinitionSchema = z.object({
|
|
|
67
100
|
behavior: behaviorSchema.nullable().optional(),
|
|
68
101
|
params: z.record(z.unknown()).nullable().optional(),
|
|
69
102
|
expressions: z.record(z.string()).nullable().optional(),
|
|
70
|
-
lookup: lookupSchema.nullable().optional()
|
|
103
|
+
lookup: lookupSchema.nullable().optional(),
|
|
104
|
+
grouping: groupingSchema.nullable().optional()
|
|
71
105
|
}).strict();
|
|
72
106
|
/** Tanımın seçtiği yollar: `ad`, `sube`, `sube.ad`; expand iki seviyeye kadar. */
|
|
73
107
|
export function selectedPaths(definition) {
|
|
@@ -203,6 +237,31 @@ export function connectDataShapeIssues(ref, path = 'ref') {
|
|
|
203
237
|
shape('connect-data-enum-invalid', `${path}.behavior.edit.saveMode`, "saveMode yalnız 'row', 'cell' ya da 'batch'.");
|
|
204
238
|
if (behavior?.refresh?.afterWrite && !['reload', 'merge'].includes(behavior.refresh.afterWrite))
|
|
205
239
|
shape('connect-data-enum-invalid', `${path}.behavior.refresh.afterWrite`, "afterWrite yalnız 'reload' ya da 'merge'.");
|
|
240
|
+
const mobileCard = behavior?.mobileCard;
|
|
241
|
+
if (mobileCard) {
|
|
242
|
+
const cardParts = [['title', mobileCard.title ?? ''], ...(mobileCard.fields ?? []).map((field) => ['fields', field]), ...(mobileCard.trailing != null ? [['trailing', mobileCard.trailing]] : [])];
|
|
243
|
+
const reported = new Set();
|
|
244
|
+
for (const [part, field] of cardParts.filter(([, field]) => !paths.includes(field))) {
|
|
245
|
+
if (reported.has(part))
|
|
246
|
+
continue;
|
|
247
|
+
reported.add(part);
|
|
248
|
+
subset('connect-data-mobile-field-not-selected', `${path}.behavior.mobileCard.${part}`, `Telefon kartında (${part}) '${field}' seçili değil. Seçili: ${paths.join(' · ')}`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
const grouping = definition.grouping;
|
|
252
|
+
if (grouping) {
|
|
253
|
+
if (kind && kind !== 'entity')
|
|
254
|
+
issues.push({ code: 'CD-013', rule: 'connect-data-source-feature-unsupported', path: `${path}.grouping`, message: `${kind} kaynağında gruplama yok: sunucu sırası ve gün/hafta/ay kovası yalnız entity kaynağında.` });
|
|
255
|
+
if (!grouping.by.trim() || !paths.includes(grouping.by))
|
|
256
|
+
subset('connect-data-grouping-not-selected', `${path}.grouping.by`, `Gruplama alanı '${grouping.by}' seçili değil. Seçili: ${paths.join(' · ')}`);
|
|
257
|
+
if (grouping.dateBucket && !CONNECT_DATA_GROUPING_DATE_BUCKETS.includes(grouping.dateBucket))
|
|
258
|
+
shape('connect-data-enum-invalid', `${path}.grouping.dateBucket`, "grouping.dateBucket yalnız 'day', 'week' ya da 'month' (alan date/datetime olmalı).");
|
|
259
|
+
if (grouping.sectionOrder && !CONNECT_DATA_GROUPING_SECTION_ORDERS.includes(grouping.sectionOrder))
|
|
260
|
+
shape('connect-data-enum-invalid', `${path}.grouping.sectionOrder`, "grouping.sectionOrder yalnız 'asc', 'desc' ya da 'asis'.");
|
|
261
|
+
if (grouping.sectionOrder !== 'asis' && definition.page?.mode === 'cursor' && (definition.sort ?? []).length > 0) {
|
|
262
|
+
issues.push({ code: 'CD-013', rule: 'connect-data-source-feature-unsupported', path: `${path}.sort`, message: 'Gruplama + cursor sayfalamada sıra gruplama alanı ve anahtardır: sort verilemez — sort\'u kaldırın ya da offset sayfalayın.' });
|
|
263
|
+
}
|
|
264
|
+
}
|
|
206
265
|
for (const [role, fieldPath] of Object.entries(definition.mapping?.roles ?? {})) {
|
|
207
266
|
if (fieldPath?.trim() && !paths.includes(fieldPath))
|
|
208
267
|
subset('connect-data-role-not-selected', `${path}.mapping.roles.${role}`, `'${role}' rolü seçili olmayan '${fieldPath}' alanına eşlenmiş.`);
|
|
@@ -216,8 +275,20 @@ export function connectDataShapeIssues(ref, path = 'ref') {
|
|
|
216
275
|
issues.push({ code: 'CD-011', rule: 'connect-data-lookup-nested', path: lookupPath, message: `'${owner}' lookup'ı içinde başka lookup olamaz.` });
|
|
217
276
|
if (lookup.mode && !['drawer', 'modal'].includes(lookup.mode))
|
|
218
277
|
shape('connect-data-enum-invalid', `${lookupPath}.mode`, "lookup.mode yalnız 'drawer' ya da 'modal'.");
|
|
278
|
+
if (lookup.mobileMode && !CONNECT_DATA_LOOKUP_MOBILE_MODES.includes(lookup.mobileMode))
|
|
279
|
+
shape('connect-data-enum-invalid', `${lookupPath}.mobileMode`, "lookup.mobileMode yalnız 'sheet' (alt sayfa, varsayılan) ya da 'fullscreen' (tam ekran).");
|
|
219
280
|
if (lookup.page && (lookup.page.limit < 1 || lookup.page.limit > CONNECT_DATA_PAGE_LIMIT_MAX))
|
|
220
281
|
shape('connect-data-page-limit', `${lookupPath}.page.limit`, `lookup.page.limit 1…${CONNECT_DATA_PAGE_LIMIT_MAX} arasında olmalı.`);
|
|
282
|
+
if (lookup.mobileRow) {
|
|
283
|
+
const lookupPaths = selectedPaths({ ...definition, fields: lookup.fields ?? [] });
|
|
284
|
+
const rowParts = [['title', lookup.mobileRow.title ?? ''], ['subtitle', lookup.mobileRow.subtitle], ['trailing', lookup.mobileRow.trailing]];
|
|
285
|
+
for (const [part, field] of rowParts) {
|
|
286
|
+
const isBlankTitle = part === 'title' && !field?.trim();
|
|
287
|
+
const isOutside = typeof field === 'string' && lookupPaths.length > 0 && !lookupPaths.includes(field);
|
|
288
|
+
if (isBlankTitle || isOutside)
|
|
289
|
+
subset('connect-data-mobile-field-not-selected', `${lookupPath}.mobileRow.${part}`, `Telefon satırında (${part}) '${field ?? ''}' '${owner}' lookup'ının alanı değil${isBlankTitle ? ' (başlık zorunlu)' : ''}. Lookup alanları: ${lookupPaths.join(' · ') || '(türetilir)'}`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
221
292
|
}
|
|
222
293
|
return issues;
|
|
223
294
|
}
|
|
@@ -124,5 +124,19 @@ export const connectDataRuleCatalog = [
|
|
|
124
124
|
rule: "Dosya alanı (describe type 'file') edit.editable'a konamaz: bağlı bileşen dosyayı satır içinde yazmaz. edit açıkken editable verilmezse gateway'in önerdiği yazılabilir alanlar da dosya alanını dışarıda bırakır.",
|
|
125
125
|
enforcedBy: 'connect_data_bind — buildDefinition (dryRun dahil, istek gitmeden)',
|
|
126
126
|
source: "38/M-4; ConnectDataService.ValidateSourcesAsync ConnectDataRules.EditableFile 'connect-data-editable-file' (422, kayıtta)"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: 'CD-019',
|
|
130
|
+
severity: 'block',
|
|
131
|
+
rule: "Satırları bölümleyen bileşen (connectData.props.<prop>.wizardSteps 'grouping' — mobilde grouped-list) tanımda grouping ister: by seçili ve (asis dışında) sıralanabilir bir alan, sectionOrder asc · desc · asis; dateBucket (day · week · month) yalnız date/datetime alanda (describe dateBuckets).",
|
|
132
|
+
enforcedBy: 'connect_data_bind — buildDefinition (istek gitmeden); şekil ve alt küme connectDataShapeIssues (connect-data-grouping-not-selected, connect-data-enum-invalid)',
|
|
133
|
+
source: "kök ADR 0019 (plan mobil-tasarimci-kabuk-ekranlari K8, b-32); ConnectDataDefinitionValidator connect-data-grouping-not-selected, ConnectDataService 422 grouping.dateBucket ve ValidateSourcesAsync connect-data-grouping-bucket-not-date ve connect-data-grouping-not-sortable"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
id: 'CD-020',
|
|
137
|
+
severity: 'block',
|
|
138
|
+
rule: "grouping yalnız satırları bölümleyen bileşende yazılır; gruplama adımı bildirmeyen bileşen (datatable, repeater, seçim bileşenleri…) onu okumaz.",
|
|
139
|
+
enforcedBy: 'connect_data_bind — buildDefinition (connectable.wizardSteps)',
|
|
140
|
+
source: 'kök ADR 0019; Studio Veri bağla sihirbazı gruplama adımını yalnız bildiren bileşende çizer (wizard-step-registry)'
|
|
127
141
|
}
|
|
128
142
|
];
|