@shundoo-ai/dsh-cosmic 1.0.21 → 1.0.22
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/package.json +1 -1
- package/skills/cosmic-build/LOCAL-PATCHES.md +43 -14
- package/skills/cosmic-build/SKILL.md +24 -9
- package/skills/cosmic-build/examples/java-rules/CosmicReportAggregation.java +26 -17
- package/skills/cosmic-build/examples/java-rules/CosmicReportFilters.java +96 -2
- package/skills/cosmic-build/knowledge/cosmic/arch/security/security_standard.md +4 -4
- package/skills/cosmic-build/knowledge/cosmic/platform/allimport.md +2 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/core/dynamic-object-collection.md +6 -4
- package/skills/cosmic-build/knowledge/cosmic/platform/core/model.md +9 -9
- package/skills/cosmic-build/knowledge/cosmic/platform/core/view.md +5 -5
- package/skills/cosmic-build/knowledge/cosmic/platform/form-plugin.md +8 -4
- package/skills/cosmic-build/knowledge/cosmic/platform/list-plugin.md +5 -3
- package/skills/cosmic-build/knowledge/cosmic/platform/print-plugin-guide.md +1 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/report-plugin.md +269 -57
- package/skills/cosmic-build/knowledge/cosmic/platform/reportlistdata-plugin.md +130 -23
- package/skills/cosmic-build/knowledge/cosmic/platform/reporttreedata-plugin.md +48 -28
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/_index.md +12 -3
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/common/attachment-name-process.md +17 -13
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/common/dynamic-update-field.md +4 -4
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/filter-grid/filter-grid-set-value.md +1 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/filter-basedatafield.md +2 -3
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/filter-container-init.md +0 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/filter-popup.md +0 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/filter-value-parse.md +5 -6
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/list-show-form.md +1 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/query-field-dynamic.md +0 -7
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/business-data/delete-service.md +24 -29
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/ksql/db-batch.md +4 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/ksql/db-direct-access.md +4 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/qfilter/entity-object-access.md +8 -3
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/qfilter/qfilter-compose.md +6 -5
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/after-bind-data-set-visible.md +5 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/click-return-data.md +2 -2
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/closed-call-back-set-value.md +2 -2
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/register-listener.md +1 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/set-filter-tab-org.md +3 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/dispatch-service/microservice-dev.md +18 -11
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/dist-lock/dist-lock-basic.md +3 -6
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/mq/mq-subscribe.md +5 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/thread-pool/async-operation.md +10 -6
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/thread-pool/big-task-async.md +4 -2
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/thread-pool/schedule-task.md +9 -7
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/operation/operation-interactive.md +33 -34
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/operation/operation-plugin-events.md +30 -22
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-async-query.md +133 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-batch-query.md +26 -22
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-chart.md +112 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-dataset-assembly.md +200 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-head-filter.md +177 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-hyperlink-drill.md +216 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-list-data-query.md +12 -12
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-merge-column.md +44 -6
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-print-data.md +163 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-row-data-toolbar.md +188 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-subtotal-total.md +139 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-tree-data-query.md +108 -12
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-tree-list.md +181 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/system-service/report-plugin-interface.md +3 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-basedata-cascade-confirm.md +14 -11
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-list-before-item-validate.md +1 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-list-build-filter.md +1 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-list-multi-level-filter.md +11 -11
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-list-refresh-node.md +22 -15
- package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-algo.md +2 -2
- package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-entity-model.md +3 -4
- package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-exception.md +9 -5
- package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-orm-access.md +4 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-request-context.md +7 -3
- package/skills/cosmic-build/knowledge/cosmic/platform/standards.md +28 -3
- package/skills/cosmic-build/references/compile-guide.md +36 -1
- package/skills/cosmic-build/references/dcs-code-rules.md +180 -0
- package/skills/cosmic-build/references/delivery.md +16 -2
- package/skills/cosmic-build/references/execution-contract.md +15 -3
- package/skills/cosmic-build/references/java-plugin-delivery.md +21 -11
- package/skills/cosmic-build/references/plugin-handoff-input.md +82 -24
- package/skills/cosmic-build/references/plugin-runtime-routing.md +23 -6
- package/skills/cosmic-build/references/report-filter-contract.md +53 -15
- package/skills/cosmic-build/references/sdk-inspection.md +4 -1
- package/skills/cosmic-build/references/type-registry.json +26 -17
- package/skills/cosmic-build/schemas/data-model-authoring.schema.json +1 -1
- package/skills/cosmic-build/scripts/_http_client.py +3 -0
- package/skills/cosmic-build/scripts/compile_plugin_source.py +251 -42
- package/skills/cosmic-build/scripts/configure_list.py +112 -0
- package/skills/cosmic-build/scripts/dcs-rule-catalog.json +799 -0
- package/skills/cosmic-build/scripts/dcs_code_gate.py +1976 -0
- package/skills/cosmic-build/scripts/execution_binding.py +25 -0
- package/skills/cosmic-build/scripts/platform_api_contract.py +352 -7
- package/skills/cosmic-build/scripts/plugin_source_gate.py +9 -1
- package/skills/cosmic-build/scripts/plugin_target_sdk.py +12 -8
- package/skills/cosmic-build/scripts/prepare_plugin_handoff.py +488 -88
- package/skills/cosmic-build/scripts/query_plugin_handoff.py +207 -20
- package/skills/cosmic-build/scripts/register_plugins.py +27 -10
- package/skills/cosmic-build/scripts/render_output_cards.py +57 -20
- package/skills/cosmic-build/scripts/resolve_output_path.py +60 -26
- package/skills/cosmic-build/scripts/run_java_tests.py +162 -0
- package/skills/cosmic-build/scripts/sync_generated_locale_assets.py +28 -0
- package/skills/cosmic-build/scripts/test/fixtures/ReportSdkCheck.java +1 -22
- package/skills/cosmic-build/scripts/test/fixtures/list_column_property_declarations.json +887 -0
- package/skills/cosmic-build/scripts/test/fixtures/operation-entry-field-prepare.java +78 -0
- package/skills/cosmic-build/scripts/test/test_add_field_required_contract.py +12 -0
- package/skills/cosmic-build/scripts/test/test_batch5_drift_governance.py +23 -2
- package/skills/cosmic-build/scripts/test/test_compile_plugin_source.py +287 -4
- package/skills/cosmic-build/scripts/test/test_configure_list_delivery.py +132 -0
- package/skills/cosmic-build/scripts/test/test_cosmic_sdk_examples.py +58 -1
- package/skills/cosmic-build/scripts/test/test_data_model_contract.py +19 -0
- package/skills/cosmic-build/scripts/test/test_dcs_code_gate.py +901 -0
- package/skills/cosmic-build/scripts/test/test_delivery_stage_boundary.py +1 -1
- package/skills/cosmic-build/scripts/test/test_direct_cli_architecture.py +2 -0
- package/skills/cosmic-build/scripts/test/test_http_client.py +6 -0
- package/skills/cosmic-build/scripts/test/test_java_toolchain_feedback.py +206 -0
- package/skills/cosmic-build/scripts/test/test_kd_api.py +21 -0
- package/skills/cosmic-build/scripts/test/test_list_configuration_closure.py +184 -0
- package/skills/cosmic-build/scripts/test/test_mcp_cli.py +139 -2
- package/skills/cosmic-build/scripts/test/test_menu_creation_closure.py +16 -0
- package/skills/cosmic-build/scripts/test/test_modeling_input_recovery.py +55 -1
- package/skills/cosmic-build/scripts/test/test_open_world_cli_catalog.py +1 -1
- package/skills/cosmic-build/scripts/test/test_operation_field_preparation.py +84 -0
- package/skills/cosmic-build/scripts/test/test_platform_api_contract.py +322 -1
- package/skills/cosmic-build/scripts/test/test_plugin_handoff.py +951 -4
- package/skills/cosmic-build/scripts/test/test_plugin_source_gate.py +30 -2
- package/skills/cosmic-build/scripts/test/test_plugin_target_sdk.py +21 -0
- package/skills/cosmic-build/scripts/test/test_property_reroute.py +165 -0
- package/skills/cosmic-build/scripts/test/test_property_schema_first.py +35 -0
- package/skills/cosmic-build/scripts/test/test_query_plugin_handoff.py +221 -0
- package/skills/cosmic-build/scripts/test/test_register_plugins.py +76 -4
- package/skills/cosmic-build/scripts/test/test_render_output_cards.py +75 -3
- package/skills/cosmic-build/scripts/test/test_report_business_contract.py +27 -5
- package/skills/cosmic-build/scripts/test/test_report_doc_contract_sync.py +103 -11
- package/skills/cosmic-build/scripts/test/test_report_plugin_source_gate.py +46 -16
- package/skills/cosmic-build/scripts/test/test_report_properties.py +74 -15
- package/skills/cosmic-build/scripts/test/test_report_query_data_source.py +3 -1
- package/skills/cosmic-build/scripts/test/test_report_sdk_optimization.py +1 -2
- package/skills/cosmic-build/scripts/test/test_test_environment.py +76 -1
- package/skills/cosmic-build/scripts/test_environment.py +67 -1
- package/skills/cosmic-build/skills/cosmic-coding-impl/SKILL.md +52 -10
- package/skills/cosmic-build/skills/cosmic-meta-api/apis/ai_meta.md +16 -3
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/report-write-contracts.json +59 -26
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/rule-domain.json +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/report-write.schema.json +75 -18
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/pdm/scripts/pdm_auto.py +39 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/pdm/scripts/pdm_client.py +97 -10
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/verify/SKILL.md +10 -12
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_apps.py +3 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_formactions.py +38 -29
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_listui.py +400 -233
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_metaops.py +87 -45
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_properties.py +42 -15
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_rules.py +135 -5
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/config.py +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/execution_errors.py +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/formatters.py +17 -11
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/property_reroute.py +15 -5
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/report_ops.py +1429 -238
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/validators.py +56 -28
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/cosmic_api.py +380 -134
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/field_decorator.py +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/meta_export.py +12 -11
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/meta_verifier.py +42 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_add_field_placement_closure.py +8 -8
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_build_configuration_readback.py +94 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_build_receipt_resume.py +47 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_metadata_unchanged_fail_closed.py +87 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_dym_evidence.py +23 -23
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_entity_integrity.py +279 -4
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_field_guard.py +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_plugin_contract.py +509 -32
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_readback_derivation.py +178 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_recreate_plan.py +125 -10
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_serve_contract.py +208 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_typed_filters.py +259 -50
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_rule_inventory_perf.py +29 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_rule_write_closure.py +20 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_batch_post_build_recovery.py +18 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_batch_verification_evidence.py +35 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_identity_guard.py +25 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_time_range_rule.py +98 -0
- package/skills/cosmic-build/skills/cosmic-meta-knowledge/domain-model/report-model.md +20 -9
- package/skills/cosmic-build/skills/cosmic-meta-knowledge/generation/report-modeling-guide.md +55 -25
- package/skills/cosmic-build/skills/cosmic-meta-knowledge/property-guides/report-column-properties.md +15 -39
- package/skills/cosmic-build/skills/cosmic-meta-modeling/SKILL.md +19 -17
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/SKILL.md +82 -38
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/examples/golden-example-report-batch.md +64 -19
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/examples/golden-example-report-plugin.md +32 -20
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/examples/golden-example-report-tree.md +78 -31
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/report-artifact-schema.json +2 -1
- package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-companion-fields.md +3 -0
- package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-list-configuration.md +2 -0
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/data_model_contract.py +3 -1
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/data_model_emit.py +27 -4
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/report_validator.py +99 -44
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/test_report_examples.py +31 -4
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/test_report_validator.py +129 -29
- package/skills/cosmic-build/skills/cosmic-meta-modifier/SKILL.md +6 -2
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/operation/validation.md +2 -0
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/property/SKILL.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/report-op/SKILL.md +104 -25
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/SKILL.md +9 -0
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/verify/usage-guide.md +2 -2
- package/skills/cosmic-build/skills/cosmic-meta-modifier/references/list-filter-modification.md +39 -12
- package/skills/cosmic-build/skills/mcp-server/SKILL.md +39 -24
- package/skills/cosmic-build/skills/mcp-server/scripts/mcp_cli.py +20 -6
- package/skills/cosmic-dev-best-practices/SKILL.md +1 -1
- package/skills/cosmic-dev-best-practices/references/README.md +2 -2
- package/skills/cosmic-dev-best-practices/references/basedata-dev-convention.md +2 -2
- package/skills/cosmic-dev-best-practices/references/bill-dev-convention.md +4 -4
- package/skills/cosmic-dev-best-practices/references/design-document-convention.md +2 -2
- package/skills/cosmic-dev-best-practices/references/design-examples/basedata-design-example.md +4 -4
- package/skills/cosmic-dev-best-practices/references/design-examples/bill-design-example.md +13 -13
- package/skills/cosmic-dev-best-practices/references/elements/CustomerField.md +1 -1
- package/skills/cosmic-dev-best-practices/references/elements/README.md +1 -1
- package/skills/cosmic-dev-best-practices/references/elements/SupplierField.md +1 -1
- package/skills/cosmic-dev-best-practices/references/elements/common-field-property-conventions.md +109 -13
- package/skills/cosmic-dev-best-practices/references/layout-control-convention.md +1 -1
- package/skills/erp-analysis/references/delivery-contract.md +2 -1
- package/skills/erp-analysis/templates/AGENTS.template.md +3 -1
- package/skills/cosmic-build/assets/platform-report-filters/TypedReportFilterFields.java +0 -169
- package/skills/cosmic-build/assets/platform-report-filters/platform.patch +0 -98
- package/skills/cosmic-build/scripts/apply_report_filter_extension.py +0 -39
|
@@ -78,6 +78,18 @@ class TestReportValidator(unittest.TestCase):
|
|
|
78
78
|
self.assertTrue(result["valid"], result["errors"])
|
|
79
79
|
self.assertEqual([], result["warnings"])
|
|
80
80
|
|
|
81
|
+
def test_default_sorts_need_a_java_fetch_plugin(self):
|
|
82
|
+
artifact = self._make_valid_artifact()
|
|
83
|
+
artifact["reportPlugins"] = []
|
|
84
|
+
artifact["queryDataSource"] = {"dataSourceNumber": "kdtest_ds"}
|
|
85
|
+
result = validate_report_artifact(artifact)
|
|
86
|
+
self.assertFalse(result["valid"])
|
|
87
|
+
self.assertIn("R-report-contract", _rules(result))
|
|
88
|
+
self.assertTrue(any("REPORT_DEFAULT_SORT_PLUGIN_REQUIRED" in row["message"]
|
|
89
|
+
for row in result["errors"]))
|
|
90
|
+
artifact.pop("reportSorts")
|
|
91
|
+
self.assertTrue(validate_report_artifact(artifact)["valid"])
|
|
92
|
+
|
|
81
93
|
def test_invalid_entity_type(self):
|
|
82
94
|
artifact = self._make_valid_artifact()
|
|
83
95
|
artifact["entities"][0]["type"] = "BillEntity"
|
|
@@ -204,6 +216,7 @@ class TestReportValidator(unittest.TestCase):
|
|
|
204
216
|
# ── R-fetch-source ──────────────────────────────────────────────────────
|
|
205
217
|
def test_missing_plugin_warns_about_empty_report(self):
|
|
206
218
|
artifact = self._make_valid_artifact()
|
|
219
|
+
artifact.pop("reportSorts")
|
|
207
220
|
artifact["reportPlugins"] = []
|
|
208
221
|
result = validate_report_artifact(artifact)
|
|
209
222
|
self.assertTrue(result["valid"], result["errors"])
|
|
@@ -214,6 +227,7 @@ class TestReportValidator(unittest.TestCase):
|
|
|
214
227
|
artifact = self._make_valid_artifact()
|
|
215
228
|
artifact["reportPlugins"] = []
|
|
216
229
|
artifact["queryDataSource"] = {"dataSourceNumber": "test818"}
|
|
230
|
+
artifact.pop("reportSorts")
|
|
217
231
|
result = validate_report_artifact(artifact)
|
|
218
232
|
self.assertTrue(result["valid"], result["errors"])
|
|
219
233
|
self.assertNotIn("R-fetch-source", _rules(result, "warnings"))
|
|
@@ -279,12 +293,15 @@ class TestReportValidator(unittest.TestCase):
|
|
|
279
293
|
artifact["reportColumns"].append(column)
|
|
280
294
|
return artifact
|
|
281
295
|
|
|
282
|
-
def
|
|
296
|
+
def test_registered_plugin_and_hidden_bigint_do_not_prove_precision_reference(self):
|
|
283
297
|
artifact = self._with_binding_target({"kind": "amount", "currencyField": "currency_id"})
|
|
298
|
+
before = copy.deepcopy(artifact)
|
|
284
299
|
result = validate_report_artifact(artifact)
|
|
285
|
-
self.
|
|
300
|
+
self.assertFalse(result["valid"])
|
|
301
|
+
self.assertIn("R-presentation-binding-target", _rules(result))
|
|
302
|
+
self.assertTrue(any("REPORT_PRECISION_REFERENCE_UNVERIFIED" in row["message"] for row in result["errors"]))
|
|
286
303
|
self.assertNotIn("R-presentation-fetch", _rules(result))
|
|
287
|
-
self.assertEqual(
|
|
304
|
+
self.assertEqual(before, artifact)
|
|
288
305
|
|
|
289
306
|
def test_presentation_without_a_plugin_is_an_error(self):
|
|
290
307
|
"""Only the data-fetch plugin can bind presentation, so it has nowhere to land."""
|
|
@@ -310,7 +327,8 @@ class TestReportValidator(unittest.TestCase):
|
|
|
310
327
|
result = validate_report_artifact(artifact)
|
|
311
328
|
self.assertFalse(result["valid"])
|
|
312
329
|
self.assertIn("R-presentation-binding", _rules(result))
|
|
313
|
-
|
|
330
|
+
issue = next(row for row in result["errors"] if row["rule"] == "R-presentation-binding")
|
|
331
|
+
self.assertIn("not the fieldKey of any declared", issue["message"])
|
|
314
332
|
|
|
315
333
|
def test_a_measure_unit_binding_to_no_declared_column_is_an_error(self):
|
|
316
334
|
artifact = self._with_presentation({"kind": "qty", "measureUnitField": "unit_id"})
|
|
@@ -325,25 +343,23 @@ class TestReportValidator(unittest.TestCase):
|
|
|
325
343
|
result = validate_report_artifact(artifact)
|
|
326
344
|
self.assertFalse(result["valid"])
|
|
327
345
|
self.assertIn("R-presentation-binding", _rules(result))
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
self.
|
|
344
|
-
|
|
345
|
-
if i["rule"] == "R-presentation-binding-target"][0]
|
|
346
|
-
self.assertIn("bigint", warning["message"])
|
|
346
|
+
issue = next(row for row in result["errors"] if row["rule"] == "R-presentation-binding")
|
|
347
|
+
self.assertIn("fieldKey == dateIndex", issue["message"])
|
|
348
|
+
|
|
349
|
+
def test_visible_and_other_scalar_targets_are_also_refused(self):
|
|
350
|
+
for kind, key in (("amount", "currencyField"), ("price", "currencyField"), ("qty", "measureUnitField")):
|
|
351
|
+
for field_type in ("bigint", "text", "decimal"):
|
|
352
|
+
for hide in (True, False):
|
|
353
|
+
with self.subTest(kind=kind, fieldType=field_type, hide=hide):
|
|
354
|
+
artifact = self._with_binding_target(
|
|
355
|
+
{"kind": kind, key: "currency_id", "scale": 2}, fieldType=field_type, hide=hide)
|
|
356
|
+
result = validate_report_artifact(artifact)
|
|
357
|
+
self.assertFalse(result["valid"])
|
|
358
|
+
self.assertIn("R-presentation-binding-target", _rules(result))
|
|
359
|
+
|
|
360
|
+
def test_explicit_decimal_scale_still_passes_without_implying_dynamic_precision(self):
|
|
361
|
+
artifact = self._with_presentation({"kind": "decimal", "scale": 3})
|
|
362
|
+
self.assertTrue(validate_report_artifact(artifact)["valid"])
|
|
347
363
|
|
|
348
364
|
def test_a_binding_key_irrelevant_to_the_kind_is_a_contract_violation(self):
|
|
349
365
|
"""Not a missing binding: an amount column has no unit to bind, so the key is the error.
|
|
@@ -355,7 +371,8 @@ class TestReportValidator(unittest.TestCase):
|
|
|
355
371
|
"kind": "amount", "currencyField": "currency_id", "measureUnitField": "unit_id"})
|
|
356
372
|
result = validate_report_artifact(artifact)
|
|
357
373
|
self.assertFalse(result["valid"])
|
|
358
|
-
self.
|
|
374
|
+
self.assertIn("R-report-contract", _rules(result))
|
|
375
|
+
self.assertNotIn("R-presentation-binding", _rules(result))
|
|
359
376
|
self.assertIn("measureUnitField", result["errors"][0]["message"])
|
|
360
377
|
|
|
361
378
|
def test_basedata_presentation_binds_no_column(self):
|
|
@@ -383,6 +400,7 @@ class TestReportValidator(unittest.TestCase):
|
|
|
383
400
|
def test_a_binding_target_inside_a_group_counts(self):
|
|
384
401
|
"""A hidden id column may live inside the group it serves."""
|
|
385
402
|
artifact = self._make_valid_artifact()
|
|
403
|
+
artifact["reportSorts"] = [{"fieldKey": "amount2", "direction": "asc"}]
|
|
386
404
|
artifact["reportColumns"] = [{
|
|
387
405
|
"kind": "group", "fieldKey": "grp_money", "caption": "Money", "children": [
|
|
388
406
|
{"kind": "column", "fieldKey": "amount2", "dateIndex": "amount2",
|
|
@@ -393,8 +411,9 @@ class TestReportValidator(unittest.TestCase):
|
|
|
393
411
|
],
|
|
394
412
|
}]
|
|
395
413
|
result = validate_report_artifact(artifact)
|
|
396
|
-
self.
|
|
397
|
-
self.
|
|
414
|
+
self.assertFalse(result["valid"])
|
|
415
|
+
self.assertIn("R-presentation-binding-target", _rules(result))
|
|
416
|
+
self.assertNotIn("R-presentation-binding", _rules(result))
|
|
398
417
|
|
|
399
418
|
# ── R-filter-unpersisted ────────────────────────────────────────────────
|
|
400
419
|
def test_must_input_true_warns(self):
|
|
@@ -423,6 +442,39 @@ class TestReportValidator(unittest.TestCase):
|
|
|
423
442
|
result = validate_report_artifact(artifact)
|
|
424
443
|
self.assertIn("R-filter-unpersisted", _rules(result, "warnings"))
|
|
425
444
|
|
|
445
|
+
# ── typed filter editors ─────────────────────────────────────────────────────────
|
|
446
|
+
def _with_filter(self, **filt):
|
|
447
|
+
artifact = self._make_valid_artifact()
|
|
448
|
+
artifact["reportFilters"] = [{"fieldPath": "flt_supplier", "displayName": "Supplier", **filt}]
|
|
449
|
+
return validate_report_artifact(artifact)
|
|
450
|
+
|
|
451
|
+
def test_a_multi_select_editor_compared_with_in_is_silent(self):
|
|
452
|
+
result = self._with_filter(compare="in", fieldType="MulBasedataField",
|
|
453
|
+
basedataNumber="bd_supplier")
|
|
454
|
+
self.assertTrue(result["valid"], result["errors"])
|
|
455
|
+
self.assertEqual([], result["warnings"])
|
|
456
|
+
|
|
457
|
+
def test_in_on_a_single_select_editor_warns(self):
|
|
458
|
+
result = self._with_filter(compare="in", fieldType="basedata", basedataNumber="bd_supplier")
|
|
459
|
+
self.assertTrue(result["valid"], result["errors"])
|
|
460
|
+
self.assertIn("R-filter-type-compare", _rules(result, "warnings"))
|
|
461
|
+
|
|
462
|
+
def test_equals_on_a_multi_select_editor_warns(self):
|
|
463
|
+
result = self._with_filter(compare="=", fieldType="MulComboField",
|
|
464
|
+
comboItems=[{"value": "A", "caption": "A"}])
|
|
465
|
+
self.assertIn("R-filter-type-compare", _rules(result, "warnings"))
|
|
466
|
+
|
|
467
|
+
def test_a_typed_editor_missing_its_parameter_is_a_contract_error(self):
|
|
468
|
+
result = self._with_filter(compare="in", fieldType="MulBasedataField")
|
|
469
|
+
self.assertFalse(result["valid"])
|
|
470
|
+
self.assertIn("R-report-contract", _rules(result))
|
|
471
|
+
|
|
472
|
+
def test_the_retired_source_binding_is_a_contract_error(self):
|
|
473
|
+
result = self._with_filter(compare="in", source={"formNumber": "pm_purorderbill",
|
|
474
|
+
"fieldKey": "supplier"})
|
|
475
|
+
self.assertFalse(result["valid"])
|
|
476
|
+
self.assertIn("R-report-contract", _rules(result))
|
|
477
|
+
|
|
426
478
|
# ── R-plugin-class ──────────────────────────────────────────────────────
|
|
427
479
|
def test_valid_class_name(self):
|
|
428
480
|
result = validate_report_artifact(self._make_valid_artifact())
|
|
@@ -435,6 +487,39 @@ class TestReportValidator(unittest.TestCase):
|
|
|
435
487
|
self.assertFalse(result["valid"])
|
|
436
488
|
self.assertIn("R-plugin-class", _rules(result))
|
|
437
489
|
|
|
490
|
+
def test_an_underscore_in_the_simple_class_name_is_rejected(self):
|
|
491
|
+
"""The plugin handoff resolves a registered class as [A-Za-z][A-Za-z0-9]*.
|
|
492
|
+
|
|
493
|
+
Accepting an underscore here let an artifact register its class and then fail Java
|
|
494
|
+
delivery with PLUGIN_CLASS_NOT_QUALIFIED.
|
|
495
|
+
"""
|
|
496
|
+
artifact = self._make_valid_artifact()
|
|
497
|
+
artifact["reportPlugins"][0]["className"] = "kd.kdtest.report.Test_ReportPlugin"
|
|
498
|
+
result = validate_report_artifact(artifact)
|
|
499
|
+
self.assertFalse(result["valid"])
|
|
500
|
+
self.assertIn("R-plugin-class", _rules(result))
|
|
501
|
+
|
|
502
|
+
# ── R-plugin-slot ────────────────────────────────────────────────────────────────────
|
|
503
|
+
def test_two_report_plugins_warn_that_the_data_slot_takes_one(self):
|
|
504
|
+
"""The left-tree example used to register its tree class as a second data plugin."""
|
|
505
|
+
artifact = self._make_valid_artifact()
|
|
506
|
+
artifact.pop("reportSorts")
|
|
507
|
+
artifact["reportPlugins"].append(
|
|
508
|
+
{"type": "Java", "className": "kd.kdtest.report.TestTreePlugin"})
|
|
509
|
+
result = validate_report_artifact(artifact)
|
|
510
|
+
self.assertTrue(result["valid"], result["errors"])
|
|
511
|
+
warning = [i for i in result["warnings"] if i["rule"] == "R-plugin-slot"][0]
|
|
512
|
+
self.assertIn("ReportTreeAp.ReportPlugin", warning["message"])
|
|
513
|
+
self.assertIn("setReportProperties --target tree", warning["message"])
|
|
514
|
+
self.assertNotIn("bos_grouprpttpl", warning["message"])
|
|
515
|
+
|
|
516
|
+
def test_the_left_tree_plugin_class_name_is_checked_too(self):
|
|
517
|
+
artifact = self._make_valid_artifact()
|
|
518
|
+
artifact["reportProperties"] = {"tree": {"ReportPlugin": "TreePlugin"}}
|
|
519
|
+
result = validate_report_artifact(artifact)
|
|
520
|
+
self.assertFalse(result["valid"])
|
|
521
|
+
self.assertIn("R-plugin-class", _rules(result))
|
|
522
|
+
|
|
438
523
|
# ── reportProperties ────────────────────────────────────────────────────
|
|
439
524
|
# The section is checked before createPage because the platform cannot report the mistake:
|
|
440
525
|
# it applies a property map by reflection and silently ignores a key it does not recognise,
|
|
@@ -507,11 +592,26 @@ class TestReportValidator(unittest.TestCase):
|
|
|
507
592
|
self.assertEqual(sorted(_rules(result)),
|
|
508
593
|
["R-property-column", "R-property-target"])
|
|
509
594
|
|
|
510
|
-
def
|
|
595
|
+
def test_tree_properties_are_refused_because_no_template_carries_a_left_tree(self):
|
|
596
|
+
"""ReportTreeAp comes from a report tree control a user adds, never from a template."""
|
|
511
597
|
result = validate_report_artifact(
|
|
512
598
|
self._with_properties({"tree": {"LeafNodeQuery": False}}))
|
|
513
|
-
self.
|
|
514
|
-
self.assertIn("R-property-tree", _rules(result
|
|
599
|
+
self.assertFalse(result["valid"])
|
|
600
|
+
self.assertIn("R-property-tree", _rules(result))
|
|
601
|
+
message = [i for i in result["errors"] if i["rule"] == "R-property-tree"][0]["message"]
|
|
602
|
+
self.assertIn("setReportProperties --target tree", message)
|
|
603
|
+
|
|
604
|
+
def test_tree_properties_are_refused_on_every_public_template(self):
|
|
605
|
+
# bos_grouprpttpl is the grouped report (group panel + group list), not a left tree.
|
|
606
|
+
for template in ("bos_rpttpl", "bos_rptqingtpl", "bos_grouprpttpl",
|
|
607
|
+
"bos_commfilterrpttpl"):
|
|
608
|
+
with self.subTest(template=template):
|
|
609
|
+
artifact = self._with_properties(
|
|
610
|
+
{"tree": {"ReportPlugin": "kd.kdtest.report.TestTreePlugin"}})
|
|
611
|
+
artifact["templateNumber"] = template
|
|
612
|
+
result = validate_report_artifact(artifact)
|
|
613
|
+
self.assertFalse(result["valid"])
|
|
614
|
+
self.assertIn("R-property-tree", _rules(result))
|
|
515
615
|
|
|
516
616
|
def test_an_absent_section_raises_nothing(self):
|
|
517
617
|
artifact = self._make_valid_artifact()
|
|
@@ -22,11 +22,13 @@ description: app-build 内部执行技能,用确定性 CLI 修改已有苍穹
|
|
|
22
22
|
|
|
23
23
|
单字段参数与批量项表达相同的受支持初始状态:
|
|
24
24
|
|
|
25
|
+
用户未指定类型时,由 AI 根据业务含义及已有相关字段、引用契约选择准确类型,并显式传入 `--field-type` 或 `fieldType`。文本仅用于自由文本语义,不能作为缺省类型;只有无法确定且影响存储或业务行为的歧义才询问。
|
|
26
|
+
|
|
25
27
|
| 含义 | 单字段参数 | `--fields` 数组项 |
|
|
26
28
|
|---|---|---|
|
|
27
29
|
| 显示名称 | `--field-name` | `name` |
|
|
28
30
|
| 英文业务标识 | `--biz-word` | `bizWord` |
|
|
29
|
-
|
|
|
31
|
+
| 类型(显式选择) | `--field-type` | `fieldType` |
|
|
30
32
|
| 必填 | `--required` | `required: true` |
|
|
31
33
|
| 已有目标面板 | `--panel` | `panel` |
|
|
32
34
|
| 紧邻已有字段 | `--before` 或 `--after` | `before` 或 `after` |
|
|
@@ -62,6 +64,8 @@ description: app-build 内部执行技能,用确定性 CLI 修改已有苍穹
|
|
|
62
64
|
|
|
63
65
|
## 单字段语法与放置语义
|
|
64
66
|
|
|
67
|
+
记录发生时刻且包含日期和时间(如上次质检时间)使用 `DateTimeField`;仅记录日期使用 `DateField`。字段名称不隐含其他属性。
|
|
68
|
+
|
|
65
69
|
创建字段使用已知 `FieldDataType`;只有类型或伴随参数不明确时才查询下方字段目录:
|
|
66
70
|
|
|
67
71
|
```text
|
|
@@ -108,7 +112,7 @@ MetaOps 或再次确认。
|
|
|
108
112
|
| 新增/删除字段 | `addField` / `removeField`;创建通过 `--fields` 支持逐项初始状态与放置 |
|
|
109
113
|
| 报表列 | `modules/report-op/SKILL.md` → `addReportColumns` |
|
|
110
114
|
| 选择字段候选值及默认值 | `references/selection-option-modification.md` → `configureSelectionFields` |
|
|
111
|
-
|
|
|
115
|
+
| 列表列/汇总/零值显示/格式/搜索/常用过滤/scheme filters/排序 | `references/list-filter-modification.md` → `configureList` |
|
|
112
116
|
| 删除准确过滤/搜索字段 | `removeFilterColumn` |
|
|
113
117
|
| 新增分录实体 | `addEntryEntity`,见末节 |
|
|
114
118
|
| 新增标题字段面板 | UI `addFieldPanel`;新字段随后使用 `addField --fields --panel` |
|
|
@@ -80,7 +80,7 @@ archive、表单 Schema 或本地目录。
|
|
|
80
80
|
| 页签上显示的“页签操作” | `ensureTabPageOperations --input '{"tab":"<页签>","items":[{"title":"<显示名称>","operationCode":"<操作编码>","operationType":"<需要新建时的操作类型>","operationName":"<操作名称>"}]}'`;页签项编码 `itemCode` 可省略,命令保留其他页签操作,它不是按钮 |
|
|
81
81
|
| 附件面板行为 | 只读一次 `attachment-panel-properties.md`,再用一次 `setProperties` |
|
|
82
82
|
| 实体权限控制元数据 | `setPermissionControl`,按所需控制查看输入契约;该能力不等同于角色授权或权限项新建 |
|
|
83
|
-
| 其他陌生且已发布的属性 | 只调用一次 `describePropertyInput --propertyNames
|
|
83
|
+
| 其他陌生且已发布的属性 | 只调用一次 `describePropertyInput --formNumber <formNumber> --elementKey <elementKey> --propertyNames <名称>`,再执行其返回路由;仅有名称时用 `--element <准确名称>` 替代 `--elementKey`,歧义须按返回候选消解 |
|
|
84
84
|
|
|
85
85
|
设计器多选字段普通值放 `set`;`MustInputCondition`、`Features`、`CtlTips`、`Style`
|
|
86
86
|
四类弹窗值放 `complex`(也接受中文名)。`Style` 的标量键编译为简单属性,`border`、
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
| 需求 | 命令 | 写入语义 |
|
|
9
9
|
|---|---|---|
|
|
10
10
|
| 新增、删除或修改过滤条件 | `setReportFilters` | 全量替换 |
|
|
11
|
-
| 修改默认排序 | `setReportSorts
|
|
11
|
+
| 修改默认排序 | `setReportSorts`(已阻断) | 需求保留到 Java 查询契约;不写元数据 |
|
|
12
12
|
| 新增或更新一个报表插件 | `registerReportPlugin` | 按 `className` 幂等更新 |
|
|
13
13
|
| 新增或更新一个查询扩展插件 | `registerReportPluginExt` | 按 `className` 幂等更新,允许多个 |
|
|
14
14
|
| 绑定或解绑查询数据源 | `setReportQueryDataSource` | 替换单个属性;`--clear` 解绑 |
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
| 修改行背景色 | `setReportRowBackColor` | 全量替换规则列表 |
|
|
18
18
|
| 修改过滤配置 | `setReportFilterFieldConfig` | 全量替换 |
|
|
19
19
|
| 修改初始字段 | `setReportDefaultHiddenFields` | 全量替换 |
|
|
20
|
-
|
|
|
20
|
+
| 删除一个叶子列,含分组内的叶子列 | `removeReportColumn` | 单项删除;需要后端补丁,不自动降级 |
|
|
21
|
+
| 删除分组、重排或改已有列的类型 | `planReportRecreate`,再 `deleteForm` + `run` | 单独授权重建;**不可逆,见下节** |
|
|
21
22
|
|
|
22
23
|
## 报表属性:一条命令,六个宿主
|
|
23
24
|
|
|
@@ -33,7 +34,11 @@
|
|
|
33
34
|
| `tree` | `ReportTreeAp` | `LeafNodeQuery`、`ReportPlugin` |
|
|
34
35
|
| `column` | `EntryFieldAp` 或 `EntryFieldGroupAp` | `Summary`、`Width`、`Freeze`、`TextAlign`、`Merge`、`GroupCollapsible` |
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
`column` 需要 `--element`。`tree` 按类型定位宿主:只有用户给报表新增了「报表树」控件才存在——没有任何公共
|
|
38
|
+
模板预置 `ReportTreeAp`(`bos_grouprpttpl` 是分组报表,不是左树)——命令按元素类型 `ReportTreeAp` 查找该
|
|
39
|
+
控件,不论用户给它起了什么 key。没有该控件时写入会以 `REPORT_PROPERTY_ELEMENT_MISMATCH` 被拒绝;有多个时
|
|
40
|
+
用 `--element` 指定其一。其余目标都由表单编码定位宿主。两个列宿主接受的
|
|
41
|
+
属性集不同——分组没有
|
|
37
42
|
`Summary`、`Width` 和 `Mask`,叶子列没有 `Merge`、`GroupCollapsible`、`GroupDefaultCollapse` 和
|
|
38
43
|
`Hide`——所以命令会先解析元素类型,再拒绝属于另一方的键。
|
|
39
44
|
|
|
@@ -47,11 +52,14 @@
|
|
|
47
52
|
`ReportSumMeta` 在属性读取上解析不到,但确实会落盘。写入值与原值相同的键记在
|
|
48
53
|
`indistinguishableFromCurrentValue`:目标状态成立,只是这次读取无法证明是哪一次调用造成的。
|
|
49
54
|
|
|
50
|
-
**`ShowFilterFields` 有一个真实存在的坑。** `setReportFilters`
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
**`ShowFilterFields` 有一个真实存在的坑。** 在未安装类型化报表过滤补丁的平台上(其 `setReportFilters`
|
|
56
|
+
结果在 `filterEditors` 下报告 `platformReceipt` 为 false),`setReportFilters` 会把同一个属性写成逗号
|
|
57
|
+
拼接串,在真实报表上实测为 `flt_biztime,flt_supplier,flt_billstatus`,而运行时按 JSON 数组解析。于是在
|
|
58
|
+
那里写过的报表都带着一个运行时读不了的值,用户更新已选条件时会抛 `KDException`。
|
|
53
59
|
`setReportProperties --target filterPanel --input '{"ShowFilterFields": [...]}'` 写的是 JSON 数组
|
|
54
|
-
|
|
60
|
+
形态,正是修复手段;在这类平台上每次调用 `setReportFilters` 之后都要重新执行一次。已安装补丁的平台
|
|
61
|
+
自己写数组,但会按过滤的 `mustInput` / `visible` 重置 `FilterMustInput` 和初始字段,所以这两项的
|
|
62
|
+
`setReportProperties` / `setReportDefaultHiddenFields` 要在 `setReportFilters` 之后执行,而不是之前。
|
|
55
63
|
|
|
56
64
|
## 加列是增量的,改列属性不需要重建
|
|
57
65
|
|
|
@@ -71,12 +79,12 @@ Field 而不是再建一个,所以重复调用幂等。写入前的 key 分类
|
|
|
71
79
|
- `REPORT_ENTITY_FIELDS_DUPLICATED`:这张报表的实体已经有重名字段,所有报表写命令全部拒绝;追加
|
|
72
80
|
也修不了这个状态,请用 `planReportRecreate` 规划重建。
|
|
73
81
|
|
|
74
|
-
`addReportColumns`
|
|
75
|
-
|
|
82
|
+
`addReportColumns` 不能删除或修改已有列。删除一个叶子列使用 `removeReportColumn`,标题修改走属性通道。
|
|
83
|
+
重排列或修改 `fieldType` / `dateIndex` 仍需要单独授权重建,并在删除之前先做规划。
|
|
76
84
|
|
|
77
85
|
已有列的**展现**不在这个集合里。宽度、汇总方式、冻结、对齐、掩码以及分组折叠开关都是列控件的属性,
|
|
78
86
|
所以 `setReportProperties --target column --element <key>` 用一次带独立回读的原子写入就能改掉它们。
|
|
79
|
-
|
|
87
|
+
只有追加、单叶子删除及属性通道无法表达的结构变化,才动用重建:
|
|
80
88
|
|
|
81
89
|
```bash
|
|
82
90
|
{python} "{cosmic_api}" planReportRecreate \
|
|
@@ -98,15 +106,47 @@ artifact 的列差异,绑定到这张报表的每一条菜单,以及有序
|
|
|
98
106
|
`width` 读不到,所以差异只比较 key 和标题 —— 其余部分以目标 artifact 为准。
|
|
99
107
|
|
|
100
108
|
**失败不等于没改**:报表分区写入抛错时,表单可能已经被改动(实测一次失败的 `setReportFilters`
|
|
101
|
-
已经把过滤面板从 5 个控件替换成了 2 个)。所以 `setReportFilters` /
|
|
109
|
+
已经把过滤面板从 5 个控件替换成了 2 个)。所以 `setReportFilters` /
|
|
102
110
|
`registerReportPlugin` 的失败信息里会明确提示「表单可能已被修改」,重试前必须先重新读回。
|
|
103
111
|
|
|
112
|
+
明确应用/表单作用域后,报表 POST 保存被拒或传输失败会使旧本地需求基线失效,并返回
|
|
113
|
+
`platformMutationPossible`。只有已有成功写回执、随后回读失败或不匹配时,才返回
|
|
114
|
+
`platformMutationApplied`。CLI 与 scoped serve 均保留此区别;输入/身份预检拒绝及 dry-run
|
|
115
|
+
不会使基线失效。携带完整的当前 artifact,通过只读刷新对账;失败或本地修复本身不授权重放写入。
|
|
116
|
+
|
|
104
117
|
每条写命令都必须传入已验证的 `--app-root` 和精确 `--formNumber`。`--formId` 只作为可选的身份
|
|
105
118
|
佐证;不一致时失败关闭。输入 Schema 和样例位于:
|
|
106
119
|
|
|
107
120
|
- `{ROOT_DIR}/skills/cosmic-meta-api/contracts/schema/report-write.schema.json`
|
|
108
121
|
- `{ROOT_DIR}/skills/cosmic-meta-api/contracts/cli/report-write-contracts.json`
|
|
109
122
|
|
|
123
|
+
## 跨后端版本安全删除单个叶子列
|
|
124
|
+
|
|
125
|
+
使用精确列 key;命令自行解析应用内报表、验证唯一叶子、提交一次删除,并独立回读其余列树。
|
|
126
|
+
不支持单项删除分组列。
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
{python} "{cosmic_api}" removeReportColumn \
|
|
130
|
+
--app-root "{appRoot}" --formNumber "{formNumber}" --fieldKey "{columnKey}"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
实现使用现有 `setComplexProperty` 的 `ReportColumns.remove` 分支,不是新增 HTTP 端点。
|
|
134
|
+
客户端可能早于该后端分支发布。明确不支持的回执(含被 `META_SAVE_FAIL` 包装的内层失败)返回
|
|
135
|
+
`REPORT_COLUMN_DELETE_API_UNAVAILABLE`:停止,保留原本地基线,说明需要等待后端升级。
|
|
136
|
+
禁止静默隐藏、重建、改删游离字段或重放请求。`--dryRun` 只在本地构建载荷,不证明服务端支持。
|
|
137
|
+
目标不存在、权限错误、保存失败和瞬时错误均不能视为能力尚未发布。
|
|
138
|
+
|
|
139
|
+
成功回执必须标明请求的 key 与删除动作;回读证明目标消失,其余列的父级、属性和顺序保持。
|
|
140
|
+
能观察到的目标默认排序必须清除;读不到的排序/插件分区仍未核验。
|
|
141
|
+
精简 Schema 无法证明字段 ID 引用图,因此即使后端执行孤立字段清理,`entityFieldCleanup`
|
|
142
|
+
仍明确标为未核验。元数据删除不等于运行验收,也不证明既有 Java 已更新。
|
|
143
|
+
|
|
144
|
+
已知币别/单位展示依赖会在写前以 `REPORT_COLUMN_IN_USE` 拒绝。
|
|
145
|
+
完整基线匹配时撤回目标列、对应排序和列属性,保留其余展示、过滤和插件需求。
|
|
146
|
+
缺基线、漂移、回读失败、删空列树或留下空分组时契约保持不完整。
|
|
147
|
+
Java 交付前按当前契约核对 `getColumns()` 与 `query()`,避免旧插件重新创建已删列,
|
|
148
|
+
或继续使用已撤回的绑定。
|
|
149
|
+
|
|
110
150
|
## 报表列不是表单字段
|
|
111
151
|
|
|
112
152
|
「报表帮我加下创建人邮箱」要的是一个列,所以走 `addReportColumns`。改成加字段并不能「先完成一半」:
|
|
@@ -145,12 +185,20 @@ artifact 的列差异,绑定到这张报表的每一条菜单,以及有序
|
|
|
145
185
|
|
|
146
186
|
## 直接路径
|
|
147
187
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
188
|
+
过滤编辑控件类型与查询比较符是两项能力。每个过滤的控件用 `fieldType` 加该类型的参数声明,例如
|
|
189
|
+
F7 选择用 `basedataNumber`、下拉框用 `comboItems`;输入 Schema 列出了全部 25 种控件及各自需要的参数。
|
|
190
|
+
平台通过类型化报表过滤 API 创建这些控件;该 API 以平台补丁发布,而本技能随客户端发布,所以同一个
|
|
191
|
+
请求会遇到三种平台:
|
|
192
|
+
|
|
193
|
+
| 平台 | `setReportFilters` 的行为 | `typedFilterSupport` |
|
|
194
|
+
|---|---|---|
|
|
195
|
+
| 已安装补丁 | 创建每个请求的控件,并返回逐个过滤的回执 | `available` |
|
|
196
|
+
| 较早的补丁,缺少某个类型 | 保存前拒绝;CLI 去掉这些过滤的控件部分重新发送 | `partial` 或 `unavailable` |
|
|
197
|
+
| 未安装补丁 | 忽略 `fieldType`:`between` 建 `DateRangeField`,其余建 `TextField` | 回读看到旧控件后为 `unavailable` |
|
|
198
|
+
|
|
199
|
+
降级的过滤不是写入失败,结果在 `filterEditors` 下点名它。告诉用户哪些条件仍是普通控件、平台补丁
|
|
200
|
+
安装后即可切换,然后重新发送同一份完整过滤数组 —— 不需要重建。不要用只读类型属性、隐藏列或 Java
|
|
201
|
+
查询逻辑代替控件。`getReportSchema` 在 schema 文本带有类名时返回每个过滤实际渲染的 `fieldType`;
|
|
154
202
|
缺少类型证据表示未知,不能推断为 `TextField`。
|
|
155
203
|
|
|
156
204
|
|
|
@@ -158,7 +206,22 @@ F7 多选 `MulBaseDataField` 和下拉框 `ComboListField` 需要平台接口扩
|
|
|
158
206
|
读回报表投影并比较请求值。
|
|
159
207
|
|
|
160
208
|
对已有报表执行 `setReportFilters` 时,只调用一次 `getReportSchema`,在内存中只修改过滤条件数组,
|
|
161
|
-
|
|
209
|
+
再把完整目标数组发出去。类型化过滤要重新写明 `fieldType` 及其参数:读取结果给出每个过滤实际渲染的
|
|
210
|
+
`fieldType` 和基础资料过滤的 `referenceNumber`,但不含下拉选项。在已安装补丁的平台上,不带
|
|
211
|
+
`fieldType` 发送的过滤会保留它现有的控件,所以无法重述选项的过滤就不要写 `fieldType`;要把控件改回
|
|
212
|
+
文本框,则声明 `TextField`。禁止读取完整表单元数据或搜索源码。
|
|
213
|
+
|
|
214
|
+
`setReportSorts` 以 `REPORT_SORTS_API_UNSAFE` 被阻断,包括 dry-run。它的 API 污染了默认显示列
|
|
215
|
+
配置 `InitField`,该属性不是排序;缺少 `isvisible` 会使表格设置抛出 `NullPointerException`。
|
|
216
|
+
禁止补 `isvisible: true`、绕过到其他元数据通道或重建报表。已有污染条目需要单独进行 API 侧修复;
|
|
217
|
+
本次技能更新不会修复它们。
|
|
218
|
+
|
|
219
|
+
修改排序时,通过下方只读刷新,将完整 artifact 的 `reportSorts` 与叶子列及一个已启用的 Java
|
|
220
|
+
取数插件对账,再通过 Java 交付修改该插件。消费 `reportContract.defaultSorts` 和 `defaultSortPolicy`,
|
|
221
|
+
保留规则顺序及 `fieldKey` 到 `dateIndex` 的映射。优先处理 `ReportQueryParam.getSortInfo()` 的
|
|
222
|
+
交互排序;没有交互排序时才应用默认值,在最终 DataSet 组装之后、分页/导出之前执行。
|
|
223
|
+
保留权限过滤,校验 key 后使用 SDK 排序 API。无插件意味着能力边界,不授权丢弃排序或擅自添加插件。
|
|
224
|
+
元数据回读不能证明该行为;默认排序与交互排序需要分别验收。
|
|
162
225
|
|
|
163
226
|
`addReportColumns` 只发要新增的那些列,不要发完整列树。命令自己解析报表、追加,并回读确认每个
|
|
164
227
|
已有列的可观察属性、父级和顺序不变,以及每个新节点结构正确且位于同级已有节点之后。
|
|
@@ -194,9 +257,9 @@ canonical 投影),返回的过滤条件只携带结构 —— key、显示
|
|
|
194
257
|
「不存在」:组装完整过滤条件数组时,需求仍然要求的每一项都要重新声明一遍。排序和插件在该档位下
|
|
195
258
|
会出现在 `unverifiableSections` 里,所以某个分区读回为空并不能证明它确实为空。
|
|
196
259
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
260
|
+
要补充插件证据,加上 `--with-dym-evidence --app-root "{appRoot}"`:它会先同步平台自身的设计态
|
|
261
|
+
导出,并证明 `reportPlugins`,档位升为 `formLayout+dym`。`reportSorts` 保持未核验,导出的默认显示列
|
|
262
|
+
配置不构成排序证据。不加该开关时,命令绝不会采信一份不是刚刚同步下来的导出。
|
|
200
263
|
|
|
201
264
|
CLI 在写入前拒绝未解析的关系:
|
|
202
265
|
|
|
@@ -216,6 +279,22 @@ CLI 在写入前拒绝未解析的关系:
|
|
|
216
279
|
`ReportQueryParam.getFilter().getFilterItem(...)` 读取并作用到该列。过滤条件是可完整替换的,
|
|
217
280
|
所以已经带着冲突 key 的报表,只要用不冲突的 key 重新发一遍完整过滤列表即可修好。
|
|
218
281
|
|
|
282
|
+
## 保持 Java 契约与当前需求一致
|
|
283
|
+
|
|
284
|
+
直接 CLI 的列、过滤和插件写入通过验证后,在身份与写前观察结果匹配时合并到完整本地需求基线。
|
|
285
|
+
`addReportColumns` 保留被跳过的已有列的原展示定义;过滤全量替换会从新契约移除已撤回的过滤条件。
|
|
286
|
+
测试用的新列不授权新增业务关联,新过滤控件本身也不授权查询逻辑。
|
|
287
|
+
|
|
288
|
+
后续 Java 准备使用 `reportAuthoringState.artifactPath`,不把历史运行结果改写成当前证据。
|
|
289
|
+
缺基线、漂移、回读失败或本地保存失败时保留 `incomplete`/`failed`,不能伪造成功契约。
|
|
290
|
+
未合并的属性写入成功后会使旧基线失效;serve 显式传入 `appRoot` 与 `formNumber` 时也会失效,
|
|
291
|
+
但不会从局部回执补造完整需求。
|
|
292
|
+
|
|
293
|
+
携带完整的当前 artifact,通过 `prepare_plugin_handoff.py --refresh-report-state` 只读对账,
|
|
294
|
+
详见[交接输入](../../../../references/plugin-handoff-input.md)。该入口只核对身份及可观察的列/过滤条件,不写平台。
|
|
295
|
+
写回执之后的回读或本地保存失败不代表平台未变更;先修复本地证据并核对未知状态再决定重试,
|
|
296
|
+
不得为了修复本地文件重放已成功的平台修改。设计证据不证明查询行为或 Java 已加载。
|
|
297
|
+
|
|
219
298
|
## 完成
|
|
220
299
|
|
|
221
300
|
成功响应已经携带窄范围独立读回验证。除非用户要求额外检查,不要再手工读回一次 Schema。
|
|
@@ -225,10 +304,10 @@ CLI 在写入前拒绝未解析的关系:
|
|
|
225
304
|
列的 key,以及「报表实体」「复杂属性」「投影」「读回档位」「设计态导出」这些词。该说的是「报表现在
|
|
226
305
|
可以按文本过滤」,而不是这个过滤条件拿到了哪个 key。
|
|
227
306
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
`menuBindings`
|
|
231
|
-
|
|
307
|
+
加列保留现有列;以后的删除属于单独的破坏性请求,不是自动回滚。
|
|
308
|
+
已安装补丁的后端支持单叶子删除并保留报表身份与菜单绑定;未支持时说明后端发版边界并停止。
|
|
309
|
+
只有单独授权重建时,才把 `lostOnRecreate` 与 `menuBindings` 翻译成用户真正会失去的菜单绑定、
|
|
310
|
+
设计器调整和旧表单权限,让用户决定。禁止把删除一个列扩展为删除整张报表。
|
|
232
311
|
|
|
233
312
|
删除插件、分批与导出行为等未支持需求属于能力缺口:明确说明缺口,或把它路由到承载 `queryBatchBy()`
|
|
234
313
|
和 `export()` 的插件。不要用通用元数据写入模拟。异步查询、分页、行高、列宽模式、直接导出 Excel 以及
|
|
@@ -81,6 +81,15 @@
|
|
|
81
81
|
仅第一项显示某字段时,使用 `not-equals @first` 配合 `behavior hide`;其他项还要清空该字段时,
|
|
82
82
|
用同一条件再执行一次 `ensureConditionalClearFields`。
|
|
83
83
|
|
|
84
|
+
“单据编号不为空时复制到工单编号”直接调用一次 `ensureConditionalCopyFieldValue`:
|
|
85
|
+
单据编号同时作为 `--condition-field` 和 `--source`,传 `--operator not-empty`,
|
|
86
|
+
工单编号作为 `--target`,不传 `--value`。复用已选应用环境,由命令解析字段并回读规则;
|
|
87
|
+
语义命令失败后不要尝试用原始 `addRule` JSON 反复试错。
|
|
88
|
+
|
|
89
|
+
业务规则给时间范围赋固定值时,FormulaAction 可写为 `<TimeRangeField字段key> = '09:00-18:00'`。
|
|
90
|
+
CLI 根据实时元数据解析开始、结束字段,转换成秒数并回读规则。更新时需提供完整的目标动作分支,
|
|
91
|
+
以保留其中其他动作。设计态回读不能证明运行时触发成功,仍需在表单验证;跨午夜范围在平台语义确认前会被拒绝。
|
|
92
|
+
|
|
84
93
|
`ensureFieldCalculation` 证明公式和两个来源字段的变化触发器。平台运行态已验证:标准数值乘法中
|
|
85
94
|
任一来源为空或为零时,目标金额回到空值呈现,不残留旧金额;不得为此再追加清空规则。用户要求
|
|
86
95
|
不同于该标准行为时,只有已有发布命令能准确表达才继续,否则单独报告。
|
|
@@ -169,7 +169,7 @@ py "SCRIPTS/meta_verifier.py" modify --formId 5PKQY --ops "[{\"op\":\"add\",\"ta
|
|
|
169
169
|
字段 'cc_new_field' 存在于表单结构中
|
|
170
170
|
|
|
171
171
|
[WARN] #2 property_equals: cc_amount
|
|
172
|
-
[已知缺陷] modifyMeta modify mustInput
|
|
172
|
+
[已知缺陷] modifyMeta modify mustInput 可能被静默忽略,建议独立验证创建后使用带回读的 setProperties API | 原始: cc_amount.MustInput = False,预期 True
|
|
173
173
|
实际值: False
|
|
174
174
|
|
|
175
175
|
------------------------------------------------------------
|
|
@@ -338,7 +338,7 @@ WARN 表示命中了已知缺陷库,是苍穹 API 的限制,不是你的操
|
|
|
338
338
|
| 场景 | 建议操作 |
|
|
339
339
|
|------|---------|
|
|
340
340
|
| `modifyMeta` 无法设置 `MulBasedataField.tableName` | 改用 `setProperties` API |
|
|
341
|
-
| `modifyMeta modify mustInput` 被静默忽略 |
|
|
341
|
+
| `modifyMeta modify mustInput` 被静默忽略 | 独立验证结构创建后,改用带回读的 `setProperties`,显式保留必录要求 |
|
|
342
342
|
|
|
343
343
|
切换 API 执行后,用 `props` 子命令再次验证。
|
|
344
344
|
|