@qingflow-tech/qingflow-app-builder-mcp 1.0.6 → 1.0.7

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.
@@ -115,6 +115,13 @@ class PublicViewButtonType(str, Enum):
115
115
  class PublicViewButtonConfigType(str, Enum):
116
116
  top = "TOP"
117
117
  detail = "DETAIL"
118
+ list = "LIST"
119
+
120
+
121
+ class PublicButtonPlacement(str, Enum):
122
+ header = "header"
123
+ detail = "detail"
124
+ list = "list"
118
125
 
119
126
 
120
127
  class PublicChartType(str, Enum):
@@ -739,6 +746,8 @@ class FieldPatch(StrictModel):
739
746
  default=None,
740
747
  validation_alias=AliasChoices("custom_button_text", "customButtonText", "custom_btn_text", "customBtnText"),
741
748
  )
749
+ as_data_title: bool | None = Field(default=None, validation_alias=AliasChoices("as_data_title", "asDataTitle"))
750
+ as_data_cover: bool | None = Field(default=None, validation_alias=AliasChoices("as_data_cover", "asDataCover"))
742
751
  subfields: list["FieldPatch"] = Field(default_factory=list)
743
752
 
744
753
  @model_validator(mode="after")
@@ -819,6 +828,8 @@ class FieldMutation(StrictModel):
819
828
  default=None,
820
829
  validation_alias=AliasChoices("custom_button_text", "customButtonText", "custom_btn_text", "customBtnText"),
821
830
  )
831
+ as_data_title: bool | None = Field(default=None, validation_alias=AliasChoices("as_data_title", "asDataTitle"))
832
+ as_data_cover: bool | None = Field(default=None, validation_alias=AliasChoices("as_data_cover", "asDataCover"))
822
833
  subfields: list[FieldPatch] | None = None
823
834
  subfield_updates: list["FieldUpdatePatch"] | None = Field(
824
835
  default=None,
@@ -1013,6 +1024,27 @@ class FlowTransitionPatch(StrictModel):
1013
1024
  target: str = Field(alias="to")
1014
1025
 
1015
1026
 
1027
+ class ViewQueryConditionsPatch(StrictModel):
1028
+ enabled: bool = Field(default=True, validation_alias=AliasChoices("enabled", "queryConditionStatus", "status"))
1029
+ exact: bool = Field(default=False, validation_alias=AliasChoices("exact", "queryConditionExact"))
1030
+ hide_before_query: bool = Field(default=False, validation_alias=AliasChoices("hide_before_query", "hideBeforeQuery", "hideBeforeQueryCondition"))
1031
+ rows: list[list[str | int]] = Field(default_factory=list, validation_alias=AliasChoices("rows", "fields", "queryCondition"))
1032
+
1033
+
1034
+ class ViewAssociatedResourcesPatch(StrictModel):
1035
+ visible: bool = Field(default=True, validation_alias=AliasChoices("visible", "enabled", "asosChartVisible"))
1036
+ limit_type: str | None = Field(default=None, validation_alias=AliasChoices("limit_type", "limitType"))
1037
+ associated_item_ids: list[Any] = Field(
1038
+ default_factory=list,
1039
+ validation_alias=AliasChoices(
1040
+ "associated_item_ids",
1041
+ "associatedItemIds",
1042
+ "asosChartIdList",
1043
+ "items",
1044
+ ),
1045
+ )
1046
+
1047
+
1016
1048
  class ViewUpsertPatch(StrictModel):
1017
1049
  name: str
1018
1050
  view_key: str | None = Field(default=None, validation_alias=AliasChoices("view_key", "viewKey"))
@@ -1025,6 +1057,17 @@ class ViewUpsertPatch(StrictModel):
1025
1057
  title_field: str | None = Field(default=None, validation_alias=AliasChoices("title_field", "titleField"))
1026
1058
  buttons: list["ViewButtonBindingPatch"] | None = None
1027
1059
  visibility: VisibilityPatch | None = None
1060
+ query_conditions: ViewQueryConditionsPatch | None = Field(default=None, validation_alias=AliasChoices("query_conditions", "queryConditions", "query_condition", "queryCondition"))
1061
+ associated_resources: ViewAssociatedResourcesPatch | None = Field(
1062
+ default=None,
1063
+ validation_alias=AliasChoices(
1064
+ "associated_resources",
1065
+ "associatedResources",
1066
+ "associated_reports",
1067
+ "associatedReports",
1068
+ "asosChartConfig",
1069
+ ),
1070
+ )
1028
1071
 
1029
1072
  @model_validator(mode="before")
1030
1073
  @classmethod
@@ -1042,6 +1085,20 @@ class ViewUpsertPatch(StrictModel):
1042
1085
  payload["filters"] = payload.pop("filter_rules")
1043
1086
  if "filterRules" in payload and "filters" not in payload:
1044
1087
  payload["filters"] = payload.pop("filterRules")
1088
+ if "queryConditions" in payload and "query_conditions" not in payload:
1089
+ payload["query_conditions"] = payload.pop("queryConditions")
1090
+ if "query_condition" in payload and "query_conditions" not in payload:
1091
+ payload["query_conditions"] = payload.pop("query_condition")
1092
+ if "queryCondition" in payload and "query_conditions" not in payload:
1093
+ payload["query_conditions"] = payload.pop("queryCondition")
1094
+ if "associatedResources" in payload and "associated_resources" not in payload:
1095
+ payload["associated_resources"] = payload.pop("associatedResources")
1096
+ if "associated_reports" in payload and "associated_resources" not in payload:
1097
+ payload["associated_resources"] = payload.pop("associated_reports")
1098
+ if "associatedReports" in payload and "associated_resources" not in payload:
1099
+ payload["associated_resources"] = payload.pop("associatedReports")
1100
+ if "asosChartConfig" in payload and "associated_resources" not in payload:
1101
+ payload["associated_resources"] = payload.pop("asosChartConfig")
1045
1102
  raw_type = payload.get("type")
1046
1103
  if isinstance(raw_type, str):
1047
1104
  normalized = raw_type.strip().lower()
@@ -1128,13 +1185,29 @@ class CustomButtonMatchRulePatch(StrictModel):
1128
1185
  return payload
1129
1186
 
1130
1187
 
1188
+ class CustomButtonFieldMappingPatch(StrictModel):
1189
+ source_field: Any = Field(validation_alias=AliasChoices("source_field", "sourceField", "source"))
1190
+ target_field: Any = Field(validation_alias=AliasChoices("target_field", "targetField", "target"))
1191
+
1192
+
1131
1193
  class CustomButtonAddDataConfigPatch(StrictModel):
1132
- related_app_key: str | None = Field(default=None, validation_alias=AliasChoices("related_app_key", "relatedAppKey"))
1194
+ related_app_key: str | None = Field(
1195
+ default=None,
1196
+ validation_alias=AliasChoices("related_app_key", "relatedAppKey", "target_app_key", "targetAppKey"),
1197
+ )
1133
1198
  related_app_name: str | None = Field(default=None, validation_alias=AliasChoices("related_app_name", "relatedAppName"))
1134
1199
  que_relation: list[CustomButtonMatchRulePatch] = Field(
1135
1200
  default_factory=list,
1136
1201
  validation_alias=AliasChoices("que_relation", "queRelation"),
1137
1202
  )
1203
+ field_mappings: list[CustomButtonFieldMappingPatch] = Field(
1204
+ default_factory=list,
1205
+ validation_alias=AliasChoices("field_mappings", "fieldMappings", "mappings"),
1206
+ )
1207
+ default_values: dict[str, Any] = Field(
1208
+ default_factory=dict,
1209
+ validation_alias=AliasChoices("default_values", "defaultValues", "defaults"),
1210
+ )
1138
1211
 
1139
1212
 
1140
1213
  class CustomButtonExternalQRobotConfigPatch(StrictModel):
@@ -1241,6 +1314,184 @@ class CustomButtonPatch(StrictModel):
1241
1314
  return self
1242
1315
 
1243
1316
 
1317
+ class CustomButtonUpsertPatch(CustomButtonPatch):
1318
+ button_id: int | None = Field(default=None, validation_alias=AliasChoices("button_id", "buttonId", "id"))
1319
+ client_key: str | None = Field(default=None, validation_alias=AliasChoices("client_key", "clientKey"))
1320
+
1321
+
1322
+ class CustomButtonRemovePatch(StrictModel):
1323
+ button_id: int | None = Field(default=None, validation_alias=AliasChoices("button_id", "buttonId", "id"))
1324
+ button_text: str | None = Field(default=None, validation_alias=AliasChoices("button_text", "buttonText", "name"))
1325
+
1326
+ @model_validator(mode="after")
1327
+ def validate_selector(self) -> "CustomButtonRemovePatch":
1328
+ if self.button_id is None and not str(self.button_text or "").strip():
1329
+ raise ValueError("remove_buttons[] requires button_id or button_text")
1330
+ return self
1331
+
1332
+
1333
+ class CustomButtonViewButtonBindingPatch(StrictModel):
1334
+ button_ref: Any = Field(validation_alias=AliasChoices("button_ref", "buttonRef", "button_id", "buttonId", "id"))
1335
+ placement: PublicButtonPlacement = Field(default=PublicButtonPlacement.detail, validation_alias=AliasChoices("placement", "position"))
1336
+ primary: bool = Field(default=False, validation_alias=AliasChoices("primary", "being_main", "beingMain"))
1337
+ button_limit: list[list[ViewFilterRulePatch]] = Field(
1338
+ default_factory=list,
1339
+ validation_alias=AliasChoices("button_limit", "buttonLimit", "visible_when", "visibleWhen"),
1340
+ )
1341
+ button_formula: str | None = Field(default=None, validation_alias=AliasChoices("button_formula", "buttonFormula"))
1342
+ button_formula_type: int = Field(default=1, validation_alias=AliasChoices("button_formula_type", "buttonFormulaType"))
1343
+ print_tpls: list[Any] = Field(default_factory=list, validation_alias=AliasChoices("print_tpls", "printTpls"))
1344
+
1345
+ @model_validator(mode="before")
1346
+ @classmethod
1347
+ def normalize_aliases(cls, value: Any) -> Any:
1348
+ if not isinstance(value, dict):
1349
+ return value
1350
+ payload = dict(value)
1351
+ raw_placement = payload.get("placement", payload.get("position", payload.get("config_type", payload.get("configType"))))
1352
+ if isinstance(raw_placement, str):
1353
+ normalized = raw_placement.strip().lower()
1354
+ if normalized in {"top", "header"}:
1355
+ payload["placement"] = PublicButtonPlacement.header.value
1356
+ elif normalized in {"detail", "data_detail"}:
1357
+ payload["placement"] = PublicButtonPlacement.detail.value
1358
+ elif normalized in {"list", "row", "row_action"}:
1359
+ payload["placement"] = PublicButtonPlacement.list.value
1360
+ raw_limits = payload.get("button_limit", payload.get("buttonLimit", payload.get("visible_when", payload.get("visibleWhen"))))
1361
+ if isinstance(raw_limits, list) and raw_limits and all(isinstance(item, dict) for item in raw_limits):
1362
+ payload["button_limit"] = [raw_limits]
1363
+ return payload
1364
+
1365
+
1366
+ class CustomButtonViewConfigPatch(StrictModel):
1367
+ view_key: str = Field(validation_alias=AliasChoices("view_key", "viewKey", "viewgraphKey", "viewGraphKey"))
1368
+ mode: str = Field(default="merge", validation_alias=AliasChoices("mode", "apply_mode", "applyMode"))
1369
+ buttons: list[CustomButtonViewButtonBindingPatch] = Field(default_factory=list)
1370
+
1371
+ @model_validator(mode="after")
1372
+ def validate_mode(self) -> "CustomButtonViewConfigPatch":
1373
+ normalized = str(self.mode or "").strip().lower()
1374
+ if normalized not in {"merge", "replace"}:
1375
+ raise ValueError("view_configs[].mode must be merge or replace")
1376
+ self.mode = normalized
1377
+ if normalized == "merge" and "buttons" not in getattr(self, "model_fields_set", set()):
1378
+ raise ValueError("view_configs[] in merge mode requires buttons; pass buttons: [] or mode=replace to clear existing bindings")
1379
+ return self
1380
+
1381
+
1382
+ class CustomButtonsApplyRequest(StrictModel):
1383
+ app_key: str
1384
+ upsert_buttons: list[CustomButtonUpsertPatch] = Field(default_factory=list)
1385
+ remove_buttons: list[CustomButtonRemovePatch] = Field(default_factory=list)
1386
+ view_configs: list[CustomButtonViewConfigPatch] = Field(default_factory=list)
1387
+
1388
+ @model_validator(mode="before")
1389
+ @classmethod
1390
+ def normalize_aliases(cls, value: Any) -> Any:
1391
+ if not isinstance(value, dict):
1392
+ return value
1393
+ payload = dict(value)
1394
+ if "buttons" in payload and "upsert_buttons" not in payload:
1395
+ payload["upsert_buttons"] = payload.pop("buttons")
1396
+ if "upsertButtons" in payload and "upsert_buttons" not in payload:
1397
+ payload["upsert_buttons"] = payload.pop("upsertButtons")
1398
+ if "removeButtons" in payload and "remove_buttons" not in payload:
1399
+ payload["remove_buttons"] = payload.pop("removeButtons")
1400
+ if "viewConfigs" in payload and "view_configs" not in payload:
1401
+ payload["view_configs"] = payload.pop("viewConfigs")
1402
+ return payload
1403
+
1404
+ @model_validator(mode="after")
1405
+ def validate_shape(self) -> "CustomButtonsApplyRequest":
1406
+ if not self.upsert_buttons and not self.remove_buttons and not self.view_configs:
1407
+ raise ValueError("custom button apply requires at least one upsert, remove, or view config operation")
1408
+ return self
1409
+
1410
+
1411
+ class AssociatedResourceUpsertPatch(StrictModel):
1412
+ client_key: str | None = Field(default=None, validation_alias=AliasChoices("client_key", "clientKey"))
1413
+ associated_item_id: int | None = Field(
1414
+ default=None,
1415
+ validation_alias=AliasChoices("associated_item_id", "associatedItemId", "asosChartId", "id"),
1416
+ )
1417
+ graph_type: str = Field(validation_alias=AliasChoices("graph_type", "graphType"))
1418
+ target_app_key: str = Field(validation_alias=AliasChoices("target_app_key", "targetAppKey", "app_key", "appKey"))
1419
+ chart_key: str | None = Field(default=None, validation_alias=AliasChoices("chart_key", "chartKey"))
1420
+ view_key: str | None = Field(default=None, validation_alias=AliasChoices("view_key", "viewKey", "viewgraphKey", "viewGraphKey"))
1421
+ report_source: str | None = Field(default=None, validation_alias=AliasChoices("report_source", "reportSource"))
1422
+ source_type: str | None = Field(default=None, validation_alias=AliasChoices("source_type", "sourceType"))
1423
+ match_rules: list[CustomButtonMatchRulePatch] = Field(default_factory=list, validation_alias=AliasChoices("match_rules", "matchRules"))
1424
+
1425
+ @model_validator(mode="before")
1426
+ @classmethod
1427
+ def normalize_aliases(cls, value: Any) -> Any:
1428
+ if not isinstance(value, dict):
1429
+ return value
1430
+ payload = dict(value)
1431
+ if "chart_id" in payload and "chart_key" not in payload and "chartKey" not in payload:
1432
+ payload["chart_key"] = str(payload.pop("chart_id"))
1433
+ raw_graph_type = str(payload.get("graph_type", payload.get("graphType", "")) or "").strip().lower()
1434
+ raw_source_type = payload.get("source_type", payload.get("sourceType"))
1435
+ has_report_source = "report_source" in payload or "reportSource" in payload
1436
+ if isinstance(raw_source_type, str):
1437
+ normalized_source = raw_source_type.strip().upper()
1438
+ if normalized_source == "BI_QINGFLOW" and not has_report_source:
1439
+ payload["report_source"] = "app"
1440
+ payload.pop("source_type", None)
1441
+ payload.pop("sourceType", None)
1442
+ elif normalized_source == "BI_DATASET" and not has_report_source:
1443
+ payload["report_source"] = "dataset"
1444
+ payload.pop("source_type", None)
1445
+ payload.pop("sourceType", None)
1446
+ elif normalized_source == "QINGFLOW" and raw_graph_type in {"view", "viewgraph"}:
1447
+ payload.pop("source_type", None)
1448
+ payload.pop("sourceType", None)
1449
+ return payload
1450
+
1451
+
1452
+ class AssociatedResourceViewConfigPatch(StrictModel):
1453
+ view_key: str = Field(validation_alias=AliasChoices("view_key", "viewKey", "viewgraphKey", "viewGraphKey"))
1454
+ visible: bool = Field(default=True, validation_alias=AliasChoices("visible", "enabled", "asosChartVisible"))
1455
+ limit_type: str | None = Field(default=None, validation_alias=AliasChoices("limit_type", "limitType"))
1456
+ associated_item_ids: list[Any] = Field(
1457
+ default_factory=list,
1458
+ validation_alias=AliasChoices("associated_item_ids", "associatedItemIds", "asosChartIdList"),
1459
+ )
1460
+ associated_item_refs: list[str] = Field(default_factory=list, validation_alias=AliasChoices("associated_item_refs", "associatedItemRefs", "refs"))
1461
+
1462
+
1463
+ class AssociatedResourcesApplyRequest(StrictModel):
1464
+ app_key: str
1465
+ upsert_resources: list[AssociatedResourceUpsertPatch] = Field(default_factory=list)
1466
+ remove_associated_item_ids: list[int] = Field(default_factory=list)
1467
+ reorder_associated_item_ids: list[int] = Field(default_factory=list)
1468
+ view_configs: list[AssociatedResourceViewConfigPatch] = Field(default_factory=list)
1469
+
1470
+ @model_validator(mode="before")
1471
+ @classmethod
1472
+ def normalize_aliases(cls, value: Any) -> Any:
1473
+ if not isinstance(value, dict):
1474
+ return value
1475
+ payload = dict(value)
1476
+ if "upsertResources" in payload and "upsert_resources" not in payload:
1477
+ payload["upsert_resources"] = payload.pop("upsertResources")
1478
+ if "resources" in payload and "upsert_resources" not in payload:
1479
+ payload["upsert_resources"] = payload.pop("resources")
1480
+ if "removeAssociatedItemIds" in payload and "remove_associated_item_ids" not in payload:
1481
+ payload["remove_associated_item_ids"] = payload.pop("removeAssociatedItemIds")
1482
+ if "reorderAssociatedItemIds" in payload and "reorder_associated_item_ids" not in payload:
1483
+ payload["reorder_associated_item_ids"] = payload.pop("reorderAssociatedItemIds")
1484
+ if "viewConfigs" in payload and "view_configs" not in payload:
1485
+ payload["view_configs"] = payload.pop("viewConfigs")
1486
+ return payload
1487
+
1488
+ @model_validator(mode="after")
1489
+ def validate_shape(self) -> "AssociatedResourcesApplyRequest":
1490
+ if not self.upsert_resources and not self.remove_associated_item_ids and not self.reorder_associated_item_ids and not self.view_configs:
1491
+ raise ValueError("associated resources apply requires at least one resource or view config operation")
1492
+ return self
1493
+
1494
+
1244
1495
  class ViewButtonBindingPatch(StrictModel):
1245
1496
  button_type: PublicViewButtonType = Field(validation_alias=AliasChoices("button_type", "buttonType"))
1246
1497
  config_type: PublicViewButtonConfigType = Field(validation_alias=AliasChoices("config_type", "configType"))
@@ -1278,10 +1529,12 @@ class ViewButtonBindingPatch(StrictModel):
1278
1529
  raw_config_type = payload.get("config_type", payload.get("configType"))
1279
1530
  if isinstance(raw_config_type, str):
1280
1531
  normalized_config = raw_config_type.strip().lower()
1281
- if normalized_config == "top":
1532
+ if normalized_config in {"top", "header"}:
1282
1533
  payload["config_type"] = "TOP"
1283
1534
  elif normalized_config == "detail":
1284
1535
  payload["config_type"] = "DETAIL"
1536
+ elif normalized_config in {"list", "row", "row_action"}:
1537
+ payload["config_type"] = "LIST"
1285
1538
  raw_limits = payload.get("button_limit", payload.get("buttonLimit"))
1286
1539
  if isinstance(raw_limits, list) and raw_limits and all(isinstance(item, dict) for item in raw_limits):
1287
1540
  payload["button_limit"] = [raw_limits]
@@ -1597,15 +1850,25 @@ class AppGetResponse(StrictModel):
1597
1850
  field_count: int = 0
1598
1851
  layout_section_count: int = 0
1599
1852
  view_count: int = 0
1853
+ chart_count: int = 0
1854
+ associated_resource_count: int = 0
1855
+ custom_button_count: int = 0
1600
1856
  workflow_enabled: bool = False
1857
+ counts: dict[str, int] = Field(default_factory=dict)
1858
+ views: list[dict[str, Any]] = Field(default_factory=list)
1859
+ charts: list[dict[str, Any]] = Field(default_factory=list)
1860
+ associated_resources: list[dict[str, Any]] = Field(default_factory=list)
1861
+ custom_buttons: list[dict[str, Any]] = Field(default_factory=list)
1601
1862
  verification_hints: list[str] = Field(default_factory=list)
1602
1863
  editability: dict[str, bool | None] = Field(default_factory=dict)
1864
+ form_settings: dict[str, Any] = Field(default_factory=dict)
1603
1865
 
1604
1866
 
1605
1867
  class AppGetFieldsResponse(StrictModel):
1606
1868
  app_key: str
1607
1869
  fields: list[dict[str, Any]] = Field(default_factory=list)
1608
1870
  field_count: int = 0
1871
+ form_settings: dict[str, Any] = Field(default_factory=dict)
1609
1872
 
1610
1873
 
1611
1874
  class AppGetLayoutResponse(StrictModel):
@@ -1681,6 +1944,7 @@ class ViewGetResponse(StrictModel):
1681
1944
  config: dict[str, Any] = Field(default_factory=dict)
1682
1945
  questions: list[dict[str, Any]] = Field(default_factory=list)
1683
1946
  associations: list[dict[str, Any]] = Field(default_factory=list)
1947
+ associated_resources_config: dict[str, Any] = Field(default_factory=dict)
1684
1948
 
1685
1949
 
1686
1950
  class ChartGetResponse(StrictModel):
@@ -1879,7 +2143,10 @@ def _normalize_public_department_scope_mode(value: Any) -> str | None:
1879
2143
 
1880
2144
 
1881
2145
  CustomButtonMatchRulePatch.model_rebuild()
2146
+ CustomButtonFieldMappingPatch.model_rebuild()
1882
2147
  CustomButtonAddDataConfigPatch.model_rebuild()
2148
+ CustomButtonViewButtonBindingPatch.model_rebuild()
2149
+ CustomButtonViewConfigPatch.model_rebuild()
1883
2150
  CodeBlockAliasPathPatch.model_rebuild()
1884
2151
  ViewButtonBindingPatch.model_rebuild()
1885
2152
  ViewUpsertPatch.model_rebuild()