hap-cli 0.8.30__tar.gz → 0.9.0__tar.gz
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.
- {hap_cli-0.8.30 → hap_cli-0.9.0}/PKG-INFO +31 -21
- {hap_cli-0.8.30/hap_cli → hap_cli-0.9.0}/README.md +30 -20
- hap_cli-0.9.0/app_live_tests/fixtures/__init__.py +1 -0
- hap_cli-0.9.0/app_live_tests/fixtures/feedback_scenario.py +256 -0
- hap_cli-0.9.0/app_live_tests/smoke.py +4618 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0/hap_cli}/README.md +30 -20
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/README_CN.md +34 -20
- hap_cli-0.9.0/hap_cli/__init__.py +68 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/__main__.py +1 -1
- hap_cli-0.8.30/hap_cli/hap_cli.py → hap_cli-0.9.0/hap_cli/_entry.py +80 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/app_cmd.py +188 -14
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/attachment_cmd.py +20 -3
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/auth_cmd.py +6 -6
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/calendar_cmd.py +55 -7
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/chart_cmd.py +55 -14
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/chat_cmd.py +11 -15
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/chatbot_cmd.py +20 -7
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/config_cmd.py +5 -6
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/contact_cmd.py +103 -7
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/department_cmd.py +2 -2
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/group_cmd.py +43 -2
- hap_cli-0.9.0/hap_cli/commands/guide_cmd.py +57 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/instance_cmd.py +315 -35
- hap_cli-0.9.0/hap_cli/commands/node_cmd.py +1494 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/optionset_cmd.py +2 -1
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/page_cmd.py +123 -27
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/post_cmd.py +41 -13
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/record_cmd.py +246 -18
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/role_cmd.py +3 -2
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/v3_registry.py +140 -8
- hap_cli-0.9.0/hap_cli/commands/workflow_cmd.py +788 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/worksheet_cmd.py +674 -54
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/context.py +8 -2
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/action_spec_adapter.py +102 -9
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app.py +490 -34
- hap_cli-0.9.0/hap_cli/core/app_creator/_hapmeta/control_type_codes.py +11 -0
- hap_cli-0.9.0/hap_cli/core/app_creator/_hapmeta/worksheet_templates.py +66 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/charts.py +4 -6
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/config.py +6 -4
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/fields.py +3 -9
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/hap.py +2 -2
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/steps.py +12 -43
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/store.py +5 -7
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/workflow_dsl.py +3 -13
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/attachment.py +80 -11
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/auth.py +21 -3
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/calendar_mod.py +163 -7
- hap_cli-0.9.0/hap_cli/core/chart.py +679 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/chat.py +134 -1
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/chatbot.py +80 -8
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/cli_access.py +35 -12
- hap_cli-0.9.0/hap_cli/core/condition_dsl.py +946 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/contact.py +77 -0
- {hap_cli-0.8.30/hap_cli/core/app_creator/_hapmeta → hap_cli-0.9.0/hap_cli/core}/control_type_codes.py +15 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/department.py +14 -2
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/editspec/field.schema.json +52 -4
- hap_cli-0.9.0/hap_cli/core/editor/fieldlower.py +226 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/jsonschema_mini.py +38 -4
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/ops.py +149 -3
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/reader.py +33 -3
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/field_normalizer.py +133 -20
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/field_spec_adapter.py +48 -12
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/filter_translator.py +107 -3
- hap_cli-0.9.0/hap_cli/core/filter_v3.py +218 -0
- hap_cli-0.9.0/hap_cli/core/flow_node.py +2558 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/global_meta.py +15 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/group.py +35 -4
- hap_cli-0.9.0/hap_cli/core/guide.py +350 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/instance.py +799 -98
- hap_cli-0.9.0/hap_cli/core/layout_check.py +355 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/logger.py +36 -1
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/optionset.py +11 -4
- hap_cli-0.9.0/hap_cli/core/page.py +713 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/post.py +38 -7
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/record.py +830 -33
- hap_cli-0.9.0/hap_cli/core/record_defaults.py +1041 -0
- hap_cli-0.9.0/hap_cli/core/record_form_checks.py +286 -0
- hap_cli-0.9.0/hap_cli/core/record_lookups.py +199 -0
- hap_cli-0.9.0/hap_cli/core/record_rules.py +1483 -0
- hap_cli-0.9.0/hap_cli/core/relation_scope.py +569 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/role.py +50 -6
- hap_cli-0.9.0/hap_cli/core/rule_spec_adapter.py +116 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/session.py +133 -6
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/update.py +12 -6
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/upload.py +111 -8
- hap_cli-0.9.0/hap_cli/core/v3/dispatcher.py +926 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/view_spec_adapter.py +316 -23
- hap_cli-0.9.0/hap_cli/core/workflow.py +1292 -0
- hap_cli-0.9.0/hap_cli/core/workflow_node_dsl.py +5055 -0
- hap_cli-0.9.0/hap_cli/core/worksheet.py +3406 -0
- hap_cli-0.9.0/hap_cli/core/worksheet_form.py +71 -0
- hap_cli-0.9.0/hap_cli/core/worksheet_reference.py +283 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/worksheet_templates.py +152 -16
- hap_cli-0.9.0/hap_cli/guide/en/approval.md +354 -0
- hap_cli-0.9.0/hap_cli/guide/en/chart.md +308 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/guide/en/messages.md +9 -3
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/guide/en/overview.md +17 -11
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/guide/en/post.md +14 -2
- hap_cli-0.9.0/hap_cli/guide/en/record.md +1144 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/guide/en/setup.md +10 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/guide/en/skills.md +13 -5
- hap_cli-0.9.0/hap_cli/guide/en/workflow.md +1161 -0
- hap_cli-0.9.0/hap_cli/guide/en/worksheet.md +661 -0
- hap_cli-0.9.0/hap_cli/guide/index.json +103 -0
- hap_cli-0.9.0/hap_cli/guide/zh-Hans/approval.md +314 -0
- hap_cli-0.9.0/hap_cli/guide/zh-Hans/chart.md +262 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/guide/zh-Hans/messages.md +9 -3
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/guide/zh-Hans/overview.md +14 -10
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/guide/zh-Hans/post.md +14 -2
- hap_cli-0.9.0/hap_cli/guide/zh-Hans/record.md +1017 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/guide/zh-Hans/setup.md +10 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/guide/zh-Hans/skills.md +13 -5
- hap_cli-0.9.0/hap_cli/guide/zh-Hans/workflow.md +1037 -0
- hap_cli-0.9.0/hap_cli/guide/zh-Hans/worksheet.md +583 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/i18n.py +18 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/locale/messages.json +2566 -276
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/conftest.py +22 -1
- hap_cli-0.9.0/hap_cli/tests/test_action_mdpublic_parity.py +289 -0
- hap_cli-0.9.0/hap_cli/tests/test_advanced_setting_guard.py +514 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_app_export_usage.py +1 -1
- hap_cli-0.9.0/hap_cli/tests/test_app_light_color.py +42 -0
- hap_cli-0.9.0/hap_cli/tests/test_app_section_name.py +97 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_approval_submit_fill_cli.py +1 -1
- hap_cli-0.9.0/hap_cli/tests/test_approval_wire.py +259 -0
- hap_cli-0.9.0/hap_cli/tests/test_atomic_write.py +202 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_attachment_share.py +1 -1
- hap_cli-0.9.0/hap_cli/tests/test_batch_add_atomic.py +381 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_bug_036430.py +1 -1
- hap_cli-0.9.0/hap_cli/tests/test_calendar_date_range.py +51 -0
- hap_cli-0.9.0/hap_cli/tests/test_calendar_discussion_cli.py +89 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_chart.py +73 -10
- hap_cli-0.9.0/hap_cli/tests/test_chart_filter_merge.py +200 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_chat_attachment_send.py +11 -5
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_chat_recall_cli.py +14 -12
- hap_cli-0.9.0/hap_cli/tests/test_chat_send_socket.py +122 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_cli_access.py +2 -2
- hap_cli-0.9.0/hap_cli/tests/test_coded_responses.py +152 -0
- hap_cli-0.9.0/hap_cli/tests/test_condition_dsl.py +451 -0
- hap_cli-0.9.0/hap_cli/tests/test_condition_dsl_entries.py +239 -0
- hap_cli-0.9.0/hap_cli/tests/test_condition_dsl_readback.py +131 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_config_cmd.py +1 -1
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_core.py +859 -77
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_destructive_confirm_cli.py +6 -1
- hap_cli-0.9.0/hap_cli/tests/test_dsl_existing_node_refs.py +372 -0
- hap_cli-0.9.0/hap_cli/tests/test_dsl_multi_record_guard.py +444 -0
- hap_cli-0.9.0/hap_cli/tests/test_engine_core_parity.py +121 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_arg_consistency.py +236 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_bidirectional.py +155 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_discussion_mentions.py +227 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_entry_module.py +122 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_field_record_ref.py +380 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_http_error_body.py +85 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_json_anywhere.py +123 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_json_file_arg.py +65 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_layout_check.py +206 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_node_get_detail.py +188 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_node_summary.py +226 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_post_cursor.py +119 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_publish_reasons.py +193 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_replicate_workflow.py +587 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_save_fields_shape.py +167 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_subgroups.py +73 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_subtable_read.py +281 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_worksheet_references.py +262 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_worksheet_visibility.py +133 -0
- hap_cli-0.9.0/hap_cli/tests/test_fb_worksheet_workflows.py +159 -0
- hap_cli-0.9.0/hap_cli/tests/test_fields_mdpublic_parity.py +287 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_full_e2e.py +2 -2
- hap_cli-0.9.0/hap_cli/tests/test_g1_chart_parity.py +200 -0
- hap_cli-0.9.0/hap_cli/tests/test_g1_record_parity.py +206 -0
- hap_cli-0.9.0/hap_cli/tests/test_g1_upload_parity.py +163 -0
- hap_cli-0.9.0/hap_cli/tests/test_g1_worksheet_parity.py +237 -0
- hap_cli-0.9.0/hap_cli/tests/test_g2_coverage_parity.py +484 -0
- hap_cli-0.9.0/hap_cli/tests/test_g3_workflow_parity.py +348 -0
- hap_cli-0.9.0/hap_cli/tests/test_g4_approval_parity.py +403 -0
- hap_cli-0.9.0/hap_cli/tests/test_g5_low_frequency_parity.py +500 -0
- hap_cli-0.9.0/hap_cli/tests/test_g6_advanced_fields.py +460 -0
- hap_cli-0.9.0/hap_cli/tests/test_g6_fields_roundtrip.py +102 -0
- hap_cli-0.9.0/hap_cli/tests/test_g7_misc_gaps.py +342 -0
- hap_cli-0.9.0/hap_cli/tests/test_g7b_permanent_delete.py +348 -0
- hap_cli-0.9.0/hap_cli/tests/test_g8_filter_operator.py +305 -0
- hap_cli-0.9.0/hap_cli/tests/test_g8b_pivot_operators.py +106 -0
- hap_cli-0.9.0/hap_cli/tests/test_g8c_empty_filter_and_help_truth.py +329 -0
- hap_cli-0.9.0/hap_cli/tests/test_g9_appid_resolve.py +166 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_global_meta.py +1 -1
- hap_cli-0.9.0/hap_cli/tests/test_guide.py +364 -0
- hap_cli-0.9.0/hap_cli/tests/test_guide_sections.py +322 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_i18n.py +8 -8
- hap_cli-0.9.0/hap_cli/tests/test_inner_flow_batch_add.py +151 -0
- hap_cli-0.9.0/hap_cli/tests/test_instance_envelope.py +127 -0
- hap_cli-0.9.0/hap_cli/tests/test_instance_history_cli.py +89 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_integration_misc.py +8 -4
- hap_cli-0.9.0/hap_cli/tests/test_jsonschema_mini_copy.py +84 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_multi_profile.py +1 -1
- hap_cli-0.9.0/hap_cli/tests/test_noninteractive_confirm.py +153 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_org_approval_v3_semantic_cli.py +1 -1
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_org_id_cli.py +1 -1
- hap_cli-0.9.0/hap_cli/tests/test_page_filters_group_read.py +243 -0
- hap_cli-0.9.0/hap_cli/tests/test_page_filters_group_update.py +290 -0
- hap_cli-0.9.0/hap_cli/tests/test_page_save_page_id.py +76 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_post_scope_cli.py +1 -1
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_record_batch_v3_semantic_cli.py +1 -1
- hap_cli-0.9.0/hap_cli/tests/test_record_business_rules.py +999 -0
- hap_cli-0.9.0/hap_cli/tests/test_record_defaults.py +723 -0
- hap_cli-0.9.0/hap_cli/tests/test_record_doc_id_hidden.py +199 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_record_field_alias.py +1 -1
- hap_cli-0.9.0/hap_cli/tests/test_record_form_checks.py +355 -0
- hap_cli-0.9.0/hap_cli/tests/test_record_run_action.py +345 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_record_v3_semantic_cli.py +1 -1
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_record_write_fixes.py +8 -5
- hap_cli-0.9.0/hap_cli/tests/test_relation_scope.py +440 -0
- hap_cli-0.9.0/hap_cli/tests/test_rmw_mdpublic_parity.py +183 -0
- hap_cli-0.9.0/hap_cli/tests/test_role_app_scope.py +101 -0
- hap_cli-0.9.0/hap_cli/tests/test_rule_filters_and_field_warning.py +199 -0
- hap_cli-0.9.0/hap_cli/tests/test_save_action_silent_drop.py +66 -0
- hap_cli-0.9.0/hap_cli/tests/test_save_rule_spec.py +274 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_semantic_types_registry.py +1 -1
- hap_cli-0.9.0/hap_cli/tests/test_subtable_mdpublic_parity.py +82 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_update.py +3 -3
- hap_cli-0.9.0/hap_cli/tests/test_upload_mdpublic_parity.py +105 -0
- hap_cli-0.9.0/hap_cli/tests/test_v3_bool_flags.py +195 -0
- hap_cli-0.9.0/hap_cli/tests/test_v3_response_format_json.py +276 -0
- hap_cli-0.9.0/hap_cli/tests/test_view_mdpublic_parity.py +197 -0
- hap_cli-0.9.0/hap_cli/tests/test_wf_config_keys.py +153 -0
- hap_cli-0.9.0/hap_cli/tests/test_wf_inner_scope.py +155 -0
- hap_cli-0.9.0/hap_cli/tests/test_wf_json_file_arg.py +86 -0
- hap_cli-0.9.0/hap_cli/tests/test_wf_node_delete_missing.py +98 -0
- hap_cli-0.9.0/hap_cli/tests/test_wf_save_action_dsl_fields.py +184 -0
- hap_cli-0.9.0/hap_cli/tests/test_wf_structure_listing.py +79 -0
- hap_cli-0.9.0/hap_cli/tests/test_wf_trigger_outcome.py +72 -0
- hap_cli-0.9.0/hap_cli/tests/test_wf_trigger_preserve.py +99 -0
- hap_cli-0.9.0/hap_cli/tests/test_wo4_result_handling.py +184 -0
- hap_cli-0.9.0/hap_cli/tests/test_workflow_code_node.py +324 -0
- hap_cli-0.9.0/hap_cli/tests/test_workflow_condition_field_types.py +360 -0
- hap_cli-0.9.0/hap_cli/tests/test_workflow_condition_slots.py +180 -0
- hap_cli-0.9.0/hap_cli/tests/test_workflow_delete_cascade.py +137 -0
- hap_cli-0.9.0/hap_cli/tests/test_workflow_lifecycle_wire.py +179 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_workflow_list_cli.py +1 -1
- hap_cli-0.9.0/hap_cli/tests/test_workflow_node_wire.py +349 -0
- hap_cli-0.9.0/hap_cli/tests/test_workflow_publish_inner.py +349 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_workflow_v3_semantic_cli.py +29 -12
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_worksheet_crud_cli.py +1 -1
- hap_cli-0.9.0/hap_cli/tests/test_worksheet_filter_read.py +203 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_worksheet_switch.py +19 -7
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_worksheet_v3_semantic_cli.py +24 -6
- hap_cli-0.9.0/hap_cli/utils/atomic_write.py +97 -0
- hap_cli-0.9.0/hap_cli/utils/confirm.py +60 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/utils/formatting.py +38 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/utils/options.py +41 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli.egg-info/PKG-INFO +31 -21
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli.egg-info/SOURCES.txt +116 -1
- hap_cli-0.9.0/hap_cli.egg-info/entry_points.txt +2 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/setup.py +1 -1
- hap_cli-0.8.30/app_live_tests/smoke.py +0 -575
- hap_cli-0.8.30/hap_cli/__init__.py +0 -3
- hap_cli-0.8.30/hap_cli/commands/guide_cmd.py +0 -36
- hap_cli-0.8.30/hap_cli/commands/node_cmd.py +0 -730
- hap_cli-0.8.30/hap_cli/commands/workflow_cmd.py +0 -419
- hap_cli-0.8.30/hap_cli/core/app_creator/_hapmeta/worksheet_templates.py +0 -734
- hap_cli-0.8.30/hap_cli/core/chart.py +0 -276
- hap_cli-0.8.30/hap_cli/core/control_type_codes.py +0 -210
- hap_cli-0.8.30/hap_cli/core/editor/fieldlower.py +0 -66
- hap_cli-0.8.30/hap_cli/core/flow_node.py +0 -1331
- hap_cli-0.8.30/hap_cli/core/guide.py +0 -176
- hap_cli-0.8.30/hap_cli/core/page.py +0 -367
- hap_cli-0.8.30/hap_cli/core/v3/dispatcher.py +0 -516
- hap_cli-0.8.30/hap_cli/core/workflow.py +0 -704
- hap_cli-0.8.30/hap_cli/core/workflow_node_dsl.py +0 -2607
- hap_cli-0.8.30/hap_cli/core/worksheet.py +0 -1930
- hap_cli-0.8.30/hap_cli/guide/en/approval.md +0 -118
- hap_cli-0.8.30/hap_cli/guide/en/chart.md +0 -150
- hap_cli-0.8.30/hap_cli/guide/en/record.md +0 -455
- hap_cli-0.8.30/hap_cli/guide/index.json +0 -60
- hap_cli-0.8.30/hap_cli/guide/zh-Hans/approval.md +0 -105
- hap_cli-0.8.30/hap_cli/guide/zh-Hans/chart.md +0 -133
- hap_cli-0.8.30/hap_cli/guide/zh-Hans/record.md +0 -430
- hap_cli-0.8.30/hap_cli/tests/test_guide.py +0 -173
- hap_cli-0.8.30/hap_cli/tests/test_instance_history_cli.py +0 -34
- hap_cli-0.8.30/hap_cli.egg-info/entry_points.txt +0 -2
- {hap_cli-0.8.30 → hap_cli-0.9.0}/MANIFEST.in +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/app_live_tests/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/app_live_tests/__main__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/app_live_tests/config.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/app_live_tests/harness.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/app_live_tests/state.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/app_creator_cmd.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/app_editor_cmd.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/icon_cmd.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/region_cmd.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/update_cmd.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/commands/upload_cmd.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/_hapmeta/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/cleanup.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/compiler.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/design/design.schema.json +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/errors.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/examples/minimal.design.json +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/executor.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/merge.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/recording/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/recording/console.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/recording/jsonl.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/recording/mirror.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/recording/report.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/schema.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/seed/INSTRUCTIONS.md +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/seed/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/seed/cli.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/seed/executor.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/seed/resources/attachments.json +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/seed/resources/sample.docx +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/seed/resources/sample.pdf +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/seed/resources/sample_images.json +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/seed/template.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/selftest.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/smoke.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/app_creator/validate.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/_hapmeta/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/_hapmeta/control_type_codes.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/apply.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/componentlower.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/editspec/component.schema.json +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/editspec/custom-action.schema.json +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/editspec/envelope.schema.json +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/editspec.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/errors.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/models.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/editor/planner.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/icon_index.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/response_crypto.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/role_perm_builder.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/token_crypto.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/v3/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/v3/render.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/core/v3/schema.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/locale/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/locale/messages.schema.json +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_app_creator.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_app_editor.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_auth_prerelease.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_bug_036750.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_content_language.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_control_lookup_guard.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_integration.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_integration_approval.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_integration_approval_actions.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_integration_calendar.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_integration_destructive.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_integration_post.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_integration_social.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_integration_v3.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_integration_workflow.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_integration_worksheet_extra.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_member_relation_array_wrap.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_no_workflow_unsupported.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_org_id_docs.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_parameter_conventions.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_parameter_mapping_registry.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_select_add_option.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_select_rejects_relation_value.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_update_mode.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_upload_allow_down.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_upload_host_resolution.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_v3_api_schema_loader.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_v3_dispatcher.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_v3_registry_coverage.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_v3_session.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_v3_yaml_translation.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_workflow_envelope_errors.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_workflow_read_write_keys.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/tests/test_worksheet_create_section.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/utils/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli/utils/parameter_mapping.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli.egg-info/dependency_links.txt +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli.egg-info/requires.txt +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/hap_cli.egg-info/top_level.txt +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/__main__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/_wftest.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/charts.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/cleanup.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/compiler.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/config.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/errors.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/executor.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/fields.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/hap.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/recording/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/recording/console.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/recording/jsonl.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/recording/mirror.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/recording/report.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/schema.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/seed/__init__.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/seed/cli.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/seed/executor.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/seed/template.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/selftest.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/smoke.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/step.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/steps.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/store.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/live_tests/workflow_dsl.py +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/setup.cfg +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/INDEX.json +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/add_member_to_role.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/batch_delete_records.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/create_optionset.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/create_role.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/delete_optionset.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/delete_record.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/delete_role.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/delete_worksheet.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/get_app_info.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/get_app_knowledge_list.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/get_app_worksheets_list.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/get_optionset_list.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/get_record_details.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/get_record_discussions.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/get_record_list.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/get_record_logs.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/get_record_pivot_data.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/get_record_relations.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/get_record_share_link.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/get_regions.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/get_role_details.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/get_role_list.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/knowledge_search.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/leave_all_roles.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/remove_member_from_role.yaml +0 -0
- {hap_cli-0.8.30 → hap_cli-0.9.0}/sources/v3-api-schema/update_optionset.yaml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hap-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: CLI harness for Mingdao HAP - Enterprise no-code platform
|
|
5
5
|
Author: hap-cli
|
|
6
6
|
License: Apache-2.0
|
|
@@ -131,7 +131,9 @@ hap worksheet record list WORKSHEET_ID --page-size 10
|
|
|
131
131
|
hap --json worksheet record list WORKSHEET_ID
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
-
Every command supports `--json` for machine-readable output.
|
|
134
|
+
Every command supports `--json` for machine-readable output. It can go
|
|
135
|
+
before or after the command: `hap --json post list` and `hap post list --json`
|
|
136
|
+
do the same thing.
|
|
135
137
|
|
|
136
138
|
---
|
|
137
139
|
|
|
@@ -164,9 +166,9 @@ discover every subcommand.
|
|
|
164
166
|
| `app select APP_ID` / `app unselect` | Manage the default app used when `--app-id` is omitted |
|
|
165
167
|
| `app create-section / edit-section / delete-section` | Section management |
|
|
166
168
|
| `app sort-sections / sort-worksheets` | Reorder sections / a section's worksheets |
|
|
167
|
-
| `app create-item` | Batch-create empty worksheets / custom pages |
|
|
168
169
|
| `app backup / export / exports / backup-logs` | Backup & export |
|
|
169
|
-
| `app usage / logs` | Statistics
|
|
170
|
+
| `app usage / logs / log-archives` | Statistics, operation logs and their archives |
|
|
171
|
+
| `app trash` | What was deleted from an application, and by whom |
|
|
170
172
|
| `app role …` | Role CRUD, permissions, members, leave-all, applications |
|
|
171
173
|
| `app optionset …` | Option set CRUD and cross-app moves |
|
|
172
174
|
| `app knowledge list / search` | Vector knowledge bases |
|
|
@@ -175,24 +177,30 @@ discover every subcommand.
|
|
|
175
177
|
|
|
176
178
|
| Command | Description |
|
|
177
179
|
|---|---|
|
|
178
|
-
| `worksheet list / info / fields / field-types` | Discover structure |
|
|
179
|
-
| `worksheet
|
|
180
|
+
| `worksheet list / info / fields / field-types` | Discover structure (`info --with-form --with-views` pulls the layout and views in the same call) |
|
|
181
|
+
| `worksheet list --workflows / --without-workflows` | See which worksheets have automation, and which have none |
|
|
182
|
+
| `worksheet references` | What else points at a worksheet — fields in other sheets, and workflow steps |
|
|
183
|
+
| `worksheet create / update / copy / delete` | Worksheet lifecycle (`update --visibility` hides a sheet from the app navigation) |
|
|
184
|
+
| `worksheet pair-relation` | Make a relation field point both ways (`--repair` fixes one paired by hand) |
|
|
185
|
+
| `worksheet add-fields / update-fields` | Append fields, or replace the whole field layout |
|
|
186
|
+
| `worksheet mount-subtable` | Embed an existing worksheet as a sub-table |
|
|
180
187
|
| `worksheet rules / save-rule` | Business rules |
|
|
181
|
-
| `worksheet switches / edit-switch` | Feature switches |
|
|
188
|
+
| `worksheet switches / switch-types / edit-switch / batch-edit-switch` | Feature switches |
|
|
182
189
|
| `worksheet form-settings / save-form-settings` | Form submission settings |
|
|
183
190
|
| `worksheet custom-actions / create-custom-action / delete-custom-action` | Custom action buttons |
|
|
184
|
-
| `worksheet create
|
|
185
|
-
| `worksheet view list / info / create / copy / delete / sort` | View management |
|
|
191
|
+
| `worksheet chart list / get / create / update / delete` | Statistics charts on a worksheet |
|
|
192
|
+
| `worksheet view list / info / create / copy / delete / sort` | View management (`list --deleted` is the recycle bin; a spec can group a table, restrict its columns, or name a plugin) |
|
|
186
193
|
|
|
187
194
|
### worksheet record — record CRUD
|
|
188
195
|
|
|
189
196
|
| Command | Description |
|
|
190
197
|
|---|---|
|
|
191
198
|
| `worksheet record list / get` | Query and read |
|
|
192
|
-
| `worksheet record create / update / delete` | Single-row CRUD |
|
|
193
|
-
| `worksheet record batch-create / batch-update` | Bulk operations (
|
|
199
|
+
| `worksheet record create / update / delete` | Single-row CRUD (`update --lock` / `--unlock` locks a record against edits) |
|
|
200
|
+
| `worksheet record batch-create / batch-update` | Bulk operations (relation/sub-table cells persist; `batch-create --single-request` writes them all in one call) |
|
|
194
201
|
| `worksheet record relations / share-link` | Linked records and share URLs |
|
|
195
|
-
| `worksheet record
|
|
202
|
+
| `worksheet record run-action` | Press a custom action button on one or more records (`--button` by name or ID, `--row-ids` comma-separated or repeated) |
|
|
203
|
+
| `worksheet record discussions / add-discussion / delete-discussion` | Discussion threads (mention people with `--at-all` / `--at`) |
|
|
196
204
|
| `worksheet record logs` | Per-record change log |
|
|
197
205
|
| `worksheet record pivot / bottom-stats` | Aggregations and summary rows |
|
|
198
206
|
|
|
@@ -200,13 +208,12 @@ discover every subcommand.
|
|
|
200
208
|
|
|
201
209
|
| Command | Description |
|
|
202
210
|
|---|---|
|
|
203
|
-
| `workflow list / get / structure / history / groups / stats` | Inspect |
|
|
204
|
-
| `workflow create / update / copy / move / delete` | Lifecycle |
|
|
211
|
+
| `workflow list / get / structure / history / groups / stats / pbp-parameters` | Inspect (`list --kind` filters by trigger) |
|
|
212
|
+
| `workflow create / update / copy / move / delete / restore / purge` | Lifecycle (delete is the recycle bin; restore and purge are the way out) |
|
|
205
213
|
| `workflow publish / rollback` | Versioning |
|
|
206
214
|
| `workflow trigger / trigger-pbp` | Manual trigger |
|
|
207
215
|
| `workflow config-get / config-set` | Global config |
|
|
208
|
-
| `workflow
|
|
209
|
-
| `workflow node …` | Node CRUD, batch-add / batch-update / batch-delete (and `*-approval` variants), test-code / test-webhook / test-ai, controls, types, code templates |
|
|
216
|
+
| `workflow node …` | Node CRUD, batch-add, save-action / save-search / save-get-more, test-code / test-webhook / test-ai, controls, types, code templates |
|
|
210
217
|
|
|
211
218
|
> Always run `hap workflow structure PROCESS_ID` before computing insertion
|
|
212
219
|
> points, branch IDs, or approval block IDs. Don't fabricate node / block /
|
|
@@ -216,9 +223,9 @@ discover every subcommand.
|
|
|
216
223
|
|
|
217
224
|
| Command | Description |
|
|
218
225
|
|---|---|
|
|
219
|
-
| `approval todo / todo-count / todo-filters / archived` | Pending and archived |
|
|
220
|
-
| `approval get /
|
|
221
|
-
| `approval approve / reject / submit / sign / forward / urge` | Act on a task |
|
|
226
|
+
| `approval todo / todo-count / done-count / todo-filters / archived` | Pending, finished and archived |
|
|
227
|
+
| `approval get / work-item / operations / op-history / history / history-detail` | Read instance state |
|
|
228
|
+
| `approval approve / reject / submit / sign / forward / transfer / undo-approval / urge` | Act on a task (signature, attachments and the next step's approvers included) |
|
|
222
229
|
| `approval revoke / terminate / restart / retry` | Lifecycle |
|
|
223
230
|
| `approval batch / retry-batch / end-batch` | Bulk variants |
|
|
224
231
|
| `approval list-types` | Enum reference |
|
|
@@ -239,6 +246,7 @@ discover every subcommand.
|
|
|
239
246
|
| `contact search / resolve` | Find members by keyword / name / email / phone |
|
|
240
247
|
| `contact friends / friend-requests` | Address book |
|
|
241
248
|
| `contact add-friend / accept-friend / reject-friend / ignore-friend / remove-friend` | Friend management |
|
|
249
|
+
| `contact org-roles / org-role-members` | Organization roles and who holds them |
|
|
242
250
|
|
|
243
251
|
### department — directory
|
|
244
252
|
|
|
@@ -264,6 +272,7 @@ discover every subcommand.
|
|
|
264
272
|
| `calendar list / get / create / update / delete` | Event lifecycle |
|
|
265
273
|
| `calendar categories` | Built-in categories |
|
|
266
274
|
| `calendar add-member / remove-member` | Membership |
|
|
275
|
+
| `calendar add-discussion` | Comment on an event (attachments supported; mention people with `--at-all` / `--at`) |
|
|
267
276
|
|
|
268
277
|
### chat — chat & messaging
|
|
269
278
|
|
|
@@ -280,6 +289,7 @@ discover every subcommand.
|
|
|
280
289
|
|
|
281
290
|
| Command | Description |
|
|
282
291
|
|---|---|
|
|
292
|
+
| `group list` | List open groups you have joined (`--org-id`, `--keywords`, and pagination options) |
|
|
283
293
|
| `group info GROUP_ID` | Group metadata |
|
|
284
294
|
| `group create` | Create a new group (`--name`, `--org-id`, optional `--member`) |
|
|
285
295
|
| `group add-member` | Add one or more members (`--group-id`, `--account-id`) |
|
|
@@ -302,7 +312,7 @@ discover every subcommand.
|
|
|
302
312
|
|
|
303
313
|
| Command | Description |
|
|
304
314
|
|---|---|
|
|
305
|
-
| `attachment share ADDRESS` | Create a link to a stored file that you can pass on (`--hours`, default 48) |
|
|
315
|
+
| `attachment share [ADDRESS]` | Create a link to a stored file that you can pass on (`--hours`, default 48; `--file-id` to share by attachment id, `--short` for a landing page instead of the storage address) |
|
|
306
316
|
|
|
307
317
|
> ADDRESS is the file's link — one that has already stopped working is fine, paste it as-is — or just the path part of it. The file itself does not expire, only the link does, so a dead link can always be revived.
|
|
308
318
|
|
|
@@ -310,7 +320,7 @@ discover every subcommand.
|
|
|
310
320
|
|
|
311
321
|
| Command | Description |
|
|
312
322
|
|---|---|
|
|
313
|
-
| `guide` | Built-in usage guide: what this version can do, and the value formats that are easy to get wrong
|
|
323
|
+
| `guide` | Built-in usage guide: what this version can do, and the value formats that are easy to get wrong. `hap guide` lists the topics, `hap guide <topic>` what one covers section by section, `hap guide <topic> <number or name>` one section |
|
|
314
324
|
|
|
315
325
|
### upload — file upload
|
|
316
326
|
|
|
@@ -102,7 +102,9 @@ hap worksheet record list WORKSHEET_ID --page-size 10
|
|
|
102
102
|
hap --json worksheet record list WORKSHEET_ID
|
|
103
103
|
```
|
|
104
104
|
|
|
105
|
-
Every command supports `--json` for machine-readable output.
|
|
105
|
+
Every command supports `--json` for machine-readable output. It can go
|
|
106
|
+
before or after the command: `hap --json post list` and `hap post list --json`
|
|
107
|
+
do the same thing.
|
|
106
108
|
|
|
107
109
|
---
|
|
108
110
|
|
|
@@ -135,9 +137,9 @@ discover every subcommand.
|
|
|
135
137
|
| `app select APP_ID` / `app unselect` | Manage the default app used when `--app-id` is omitted |
|
|
136
138
|
| `app create-section / edit-section / delete-section` | Section management |
|
|
137
139
|
| `app sort-sections / sort-worksheets` | Reorder sections / a section's worksheets |
|
|
138
|
-
| `app create-item` | Batch-create empty worksheets / custom pages |
|
|
139
140
|
| `app backup / export / exports / backup-logs` | Backup & export |
|
|
140
|
-
| `app usage / logs` | Statistics
|
|
141
|
+
| `app usage / logs / log-archives` | Statistics, operation logs and their archives |
|
|
142
|
+
| `app trash` | What was deleted from an application, and by whom |
|
|
141
143
|
| `app role …` | Role CRUD, permissions, members, leave-all, applications |
|
|
142
144
|
| `app optionset …` | Option set CRUD and cross-app moves |
|
|
143
145
|
| `app knowledge list / search` | Vector knowledge bases |
|
|
@@ -146,24 +148,30 @@ discover every subcommand.
|
|
|
146
148
|
|
|
147
149
|
| Command | Description |
|
|
148
150
|
|---|---|
|
|
149
|
-
| `worksheet list / info / fields / field-types` | Discover structure |
|
|
150
|
-
| `worksheet
|
|
151
|
+
| `worksheet list / info / fields / field-types` | Discover structure (`info --with-form --with-views` pulls the layout and views in the same call) |
|
|
152
|
+
| `worksheet list --workflows / --without-workflows` | See which worksheets have automation, and which have none |
|
|
153
|
+
| `worksheet references` | What else points at a worksheet — fields in other sheets, and workflow steps |
|
|
154
|
+
| `worksheet create / update / copy / delete` | Worksheet lifecycle (`update --visibility` hides a sheet from the app navigation) |
|
|
155
|
+
| `worksheet pair-relation` | Make a relation field point both ways (`--repair` fixes one paired by hand) |
|
|
156
|
+
| `worksheet add-fields / update-fields` | Append fields, or replace the whole field layout |
|
|
157
|
+
| `worksheet mount-subtable` | Embed an existing worksheet as a sub-table |
|
|
151
158
|
| `worksheet rules / save-rule` | Business rules |
|
|
152
|
-
| `worksheet switches / edit-switch` | Feature switches |
|
|
159
|
+
| `worksheet switches / switch-types / edit-switch / batch-edit-switch` | Feature switches |
|
|
153
160
|
| `worksheet form-settings / save-form-settings` | Form submission settings |
|
|
154
161
|
| `worksheet custom-actions / create-custom-action / delete-custom-action` | Custom action buttons |
|
|
155
|
-
| `worksheet create
|
|
156
|
-
| `worksheet view list / info / create / copy / delete / sort` | View management |
|
|
162
|
+
| `worksheet chart list / get / create / update / delete` | Statistics charts on a worksheet |
|
|
163
|
+
| `worksheet view list / info / create / copy / delete / sort` | View management (`list --deleted` is the recycle bin; a spec can group a table, restrict its columns, or name a plugin) |
|
|
157
164
|
|
|
158
165
|
### worksheet record — record CRUD
|
|
159
166
|
|
|
160
167
|
| Command | Description |
|
|
161
168
|
|---|---|
|
|
162
169
|
| `worksheet record list / get` | Query and read |
|
|
163
|
-
| `worksheet record create / update / delete` | Single-row CRUD |
|
|
164
|
-
| `worksheet record batch-create / batch-update` | Bulk operations (
|
|
170
|
+
| `worksheet record create / update / delete` | Single-row CRUD (`update --lock` / `--unlock` locks a record against edits) |
|
|
171
|
+
| `worksheet record batch-create / batch-update` | Bulk operations (relation/sub-table cells persist; `batch-create --single-request` writes them all in one call) |
|
|
165
172
|
| `worksheet record relations / share-link` | Linked records and share URLs |
|
|
166
|
-
| `worksheet record
|
|
173
|
+
| `worksheet record run-action` | Press a custom action button on one or more records (`--button` by name or ID, `--row-ids` comma-separated or repeated) |
|
|
174
|
+
| `worksheet record discussions / add-discussion / delete-discussion` | Discussion threads (mention people with `--at-all` / `--at`) |
|
|
167
175
|
| `worksheet record logs` | Per-record change log |
|
|
168
176
|
| `worksheet record pivot / bottom-stats` | Aggregations and summary rows |
|
|
169
177
|
|
|
@@ -171,13 +179,12 @@ discover every subcommand.
|
|
|
171
179
|
|
|
172
180
|
| Command | Description |
|
|
173
181
|
|---|---|
|
|
174
|
-
| `workflow list / get / structure / history / groups / stats` | Inspect |
|
|
175
|
-
| `workflow create / update / copy / move / delete` | Lifecycle |
|
|
182
|
+
| `workflow list / get / structure / history / groups / stats / pbp-parameters` | Inspect (`list --kind` filters by trigger) |
|
|
183
|
+
| `workflow create / update / copy / move / delete / restore / purge` | Lifecycle (delete is the recycle bin; restore and purge are the way out) |
|
|
176
184
|
| `workflow publish / rollback` | Versioning |
|
|
177
185
|
| `workflow trigger / trigger-pbp` | Manual trigger |
|
|
178
186
|
| `workflow config-get / config-set` | Global config |
|
|
179
|
-
| `workflow
|
|
180
|
-
| `workflow node …` | Node CRUD, batch-add / batch-update / batch-delete (and `*-approval` variants), test-code / test-webhook / test-ai, controls, types, code templates |
|
|
187
|
+
| `workflow node …` | Node CRUD, batch-add, save-action / save-search / save-get-more, test-code / test-webhook / test-ai, controls, types, code templates |
|
|
181
188
|
|
|
182
189
|
> Always run `hap workflow structure PROCESS_ID` before computing insertion
|
|
183
190
|
> points, branch IDs, or approval block IDs. Don't fabricate node / block /
|
|
@@ -187,9 +194,9 @@ discover every subcommand.
|
|
|
187
194
|
|
|
188
195
|
| Command | Description |
|
|
189
196
|
|---|---|
|
|
190
|
-
| `approval todo / todo-count / todo-filters / archived` | Pending and archived |
|
|
191
|
-
| `approval get /
|
|
192
|
-
| `approval approve / reject / submit / sign / forward / urge` | Act on a task |
|
|
197
|
+
| `approval todo / todo-count / done-count / todo-filters / archived` | Pending, finished and archived |
|
|
198
|
+
| `approval get / work-item / operations / op-history / history / history-detail` | Read instance state |
|
|
199
|
+
| `approval approve / reject / submit / sign / forward / transfer / undo-approval / urge` | Act on a task (signature, attachments and the next step's approvers included) |
|
|
193
200
|
| `approval revoke / terminate / restart / retry` | Lifecycle |
|
|
194
201
|
| `approval batch / retry-batch / end-batch` | Bulk variants |
|
|
195
202
|
| `approval list-types` | Enum reference |
|
|
@@ -210,6 +217,7 @@ discover every subcommand.
|
|
|
210
217
|
| `contact search / resolve` | Find members by keyword / name / email / phone |
|
|
211
218
|
| `contact friends / friend-requests` | Address book |
|
|
212
219
|
| `contact add-friend / accept-friend / reject-friend / ignore-friend / remove-friend` | Friend management |
|
|
220
|
+
| `contact org-roles / org-role-members` | Organization roles and who holds them |
|
|
213
221
|
|
|
214
222
|
### department — directory
|
|
215
223
|
|
|
@@ -235,6 +243,7 @@ discover every subcommand.
|
|
|
235
243
|
| `calendar list / get / create / update / delete` | Event lifecycle |
|
|
236
244
|
| `calendar categories` | Built-in categories |
|
|
237
245
|
| `calendar add-member / remove-member` | Membership |
|
|
246
|
+
| `calendar add-discussion` | Comment on an event (attachments supported; mention people with `--at-all` / `--at`) |
|
|
238
247
|
|
|
239
248
|
### chat — chat & messaging
|
|
240
249
|
|
|
@@ -251,6 +260,7 @@ discover every subcommand.
|
|
|
251
260
|
|
|
252
261
|
| Command | Description |
|
|
253
262
|
|---|---|
|
|
263
|
+
| `group list` | List open groups you have joined (`--org-id`, `--keywords`, and pagination options) |
|
|
254
264
|
| `group info GROUP_ID` | Group metadata |
|
|
255
265
|
| `group create` | Create a new group (`--name`, `--org-id`, optional `--member`) |
|
|
256
266
|
| `group add-member` | Add one or more members (`--group-id`, `--account-id`) |
|
|
@@ -273,7 +283,7 @@ discover every subcommand.
|
|
|
273
283
|
|
|
274
284
|
| Command | Description |
|
|
275
285
|
|---|---|
|
|
276
|
-
| `attachment share ADDRESS` | Create a link to a stored file that you can pass on (`--hours`, default 48) |
|
|
286
|
+
| `attachment share [ADDRESS]` | Create a link to a stored file that you can pass on (`--hours`, default 48; `--file-id` to share by attachment id, `--short` for a landing page instead of the storage address) |
|
|
277
287
|
|
|
278
288
|
> ADDRESS is the file's link — one that has already stopped working is fine, paste it as-is — or just the path part of it. The file itself does not expire, only the link does, so a dead link can always be revived.
|
|
279
289
|
|
|
@@ -281,7 +291,7 @@ discover every subcommand.
|
|
|
281
291
|
|
|
282
292
|
| Command | Description |
|
|
283
293
|
|---|---|
|
|
284
|
-
| `guide` | Built-in usage guide: what this version can do, and the value formats that are easy to get wrong
|
|
294
|
+
| `guide` | Built-in usage guide: what this version can do, and the value formats that are easy to get wrong. `hap guide` lists the topics, `hap guide <topic>` what one covers section by section, `hap guide <topic> <number or name>` one section |
|
|
285
295
|
|
|
286
296
|
### upload — file upload
|
|
287
297
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Long-lived live fixtures. Built once, kept, reused by later work."""
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"""Build the FB- scenario: the shape the feedback report was written about.
|
|
2
|
+
|
|
3
|
+
Twenty-odd near-identical document tables spread over sub-groups, copied
|
|
4
|
+
from one template, wired together with sub-tables, relations, look-ups,
|
|
5
|
+
roll-ups, formulas, dynamic defaults and one two-way pair. That shape is
|
|
6
|
+
what made the report's problems visible, so the fixes need it standing.
|
|
7
|
+
|
|
8
|
+
This is deliberately **not** torn down: it is the baseline later work
|
|
9
|
+
reads from. Everything it makes is named ``FB-*`` and lives in the
|
|
10
|
+
persistent live-test application.
|
|
11
|
+
|
|
12
|
+
Every server interaction goes through the ``hap`` CLI. That is the point
|
|
13
|
+
— the report's complaint was that none of this could be done with the
|
|
14
|
+
CLI, so a fixture that reached for ``session.api_call`` would be
|
|
15
|
+
assuming away the thing under test.
|
|
16
|
+
|
|
17
|
+
Run:
|
|
18
|
+
python3 -m app_live_tests.fixtures.feedback_scenario # build / repair
|
|
19
|
+
python3 -m app_live_tests.fixtures.feedback_scenario --show # print ids
|
|
20
|
+
|
|
21
|
+
It is idempotent: anything already there by name is reused, so a second
|
|
22
|
+
run makes no new objects.
|
|
23
|
+
|
|
24
|
+
FB-单据B-模板 is deliberately left in a damaged state — see below.
|
|
25
|
+
|
|
26
|
+
Two-way pairing, and why one sheet here is broken on purpose
|
|
27
|
+
-----------------------------------------------------------
|
|
28
|
+
There is no supported way to pair a relation two-way from the CLI. The
|
|
29
|
+
report's author worked one out (3.5): read the placeholder the server
|
|
30
|
+
puts on the forward field's ``sourceControlId``, then create a field on
|
|
31
|
+
the target sheet whose ``controlId`` is forced to that placeholder. It
|
|
32
|
+
does produce a pair that reads as two-way — and it leaves the target
|
|
33
|
+
sheet corrupting on every later save.
|
|
34
|
+
|
|
35
|
+
Measured 2026-09-10 on this fixture:
|
|
36
|
+
|
|
37
|
+
* ``FB-单据B-模板`` holds such a forged reverse end. Reading its 14
|
|
38
|
+
controls and posting the same 14 back answers ``操作成功`` and reads
|
|
39
|
+
back 15, the reverse-end control duplicated under one ``controlId``.
|
|
40
|
+
Repeated three times: 14 in, 15 out, every time. Sending a
|
|
41
|
+
de-duplicated layout does not help; the only clean layout is one that
|
|
42
|
+
drops the pairing altogether.
|
|
43
|
+
* ``FB-明细-隐藏`` holds a reverse end created by ``mount-subtable``,
|
|
44
|
+
which pairs through the supported path. Same no-op replace: 5 in, 5
|
|
45
|
+
out, clean.
|
|
46
|
+
* ``FB-单据A-模板`` is the forward side and carries all six bridge
|
|
47
|
+
fields. Same no-op replace: 22 in, 22 out, clean, every bridge intact.
|
|
48
|
+
|
|
49
|
+
So a full-layout replace is not broadly unsafe, and this is not a
|
|
50
|
+
server-side defect in ``SaveWorksheetControls``. What corrupts is a
|
|
51
|
+
reverse end that was never registered as one — the server re-materialises
|
|
52
|
+
the real far side beside the forged one on every save. Which means the
|
|
53
|
+
recipe in report 3.5 quietly damages every sheet it is applied to, and
|
|
54
|
+
sheets built that way accumulate a copy per edit.
|
|
55
|
+
|
|
56
|
+
The damage is left standing here on purpose: a fix for report 3.4 has to
|
|
57
|
+
classify this pair as two-way, and the ``--check`` validator asked for in
|
|
58
|
+
3.7 has to notice the duplicate ``controlId``.
|
|
59
|
+
"""
|
|
60
|
+
from __future__ import annotations
|
|
61
|
+
|
|
62
|
+
import json
|
|
63
|
+
import sys
|
|
64
|
+
from pathlib import Path
|
|
65
|
+
|
|
66
|
+
from app_live_tests import state
|
|
67
|
+
from app_live_tests.harness import hap
|
|
68
|
+
|
|
69
|
+
STATE_PATH = Path(__file__).resolve().parent / "state" / "feedback_scenario.json"
|
|
70
|
+
|
|
71
|
+
PREFIX = "FB-"
|
|
72
|
+
TEMPLATE_GROUP = "FB-模板组"
|
|
73
|
+
TARGET_GROUP = "FB-目标组"
|
|
74
|
+
HELPER_GROUP = "FB-辅助组"
|
|
75
|
+
|
|
76
|
+
# The twelve columns every document table in the report carries, plus the
|
|
77
|
+
# title. Kept here as data so later work can rebuild or compare against
|
|
78
|
+
# them without re-reading the report.
|
|
79
|
+
STANDARD_FIELDS = [
|
|
80
|
+
{"type": "TEXT", "name": "名称", "required": True},
|
|
81
|
+
{"type": "DROP_DOWN", "name": "单据状态",
|
|
82
|
+
"options": ["草稿", "已提交", "已完成"]},
|
|
83
|
+
{"type": "DROP_DOWN", "name": "审核状态",
|
|
84
|
+
"options": ["待审核", "通过", "驳回"]},
|
|
85
|
+
{"type": "DATE", "name": "业务日期"},
|
|
86
|
+
{"type": "USER_PICKER", "name": "经手人"},
|
|
87
|
+
{"type": "DEPARTMENT", "name": "业务部门"},
|
|
88
|
+
{"type": "USER_PICKER", "name": "部门负责人"},
|
|
89
|
+
{"type": "USER_PICKER", "name": "待审核人"},
|
|
90
|
+
{"type": "USER_PICKER", "name": "已审核人"},
|
|
91
|
+
{"type": "TEXT", "name": "审核意见"},
|
|
92
|
+
{"type": "AUTO_ID", "name": "流水号"},
|
|
93
|
+
{"type": "TEXT", "name": "备注"},
|
|
94
|
+
{"type": "ATTACHMENT", "name": "附件"},
|
|
95
|
+
]
|
|
96
|
+
|
|
97
|
+
DETAIL_FIELDS = [
|
|
98
|
+
{"type": "TEXT", "name": "明细名称", "required": True},
|
|
99
|
+
{"type": "NUMBER", "name": "数量"},
|
|
100
|
+
{"type": "MONEY", "name": "单价"},
|
|
101
|
+
{"type": "TEXT", "name": "明细备注"},
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
TEMPLATE_SHEETS = ["FB-单据A-模板", "FB-单据B-模板", "FB-单据C-模板"]
|
|
105
|
+
TARGET_SHEETS = ["FB-单据A-目标", "FB-单据B-目标", "FB-单据C-目标"]
|
|
106
|
+
DETAIL_SHEET = "FB-明细-隐藏"
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _load() -> dict:
|
|
110
|
+
if STATE_PATH.exists():
|
|
111
|
+
return json.loads(STATE_PATH.read_text(encoding="utf-8"))
|
|
112
|
+
return {}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _save(data: dict) -> None:
|
|
116
|
+
STATE_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
117
|
+
STATE_PATH.write_text(
|
|
118
|
+
json.dumps(data, ensure_ascii=False, indent=1) + "\n", encoding="utf-8")
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _app_tree(app_id: str) -> dict:
|
|
122
|
+
detail = hap(["app", "info", "-a", app_id], check=False)
|
|
123
|
+
return detail.get("data", detail) if isinstance(detail, dict) else {}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _child_sections(app_id: str) -> dict[str, str]:
|
|
127
|
+
"""Name → id for every second-level group under the app's root."""
|
|
128
|
+
out: dict[str, str] = {}
|
|
129
|
+
for sec in _app_tree(app_id).get("sections") or []:
|
|
130
|
+
for child in sec.get("childSections") or []:
|
|
131
|
+
if child.get("name"):
|
|
132
|
+
out[child["name"]] = child.get("id") or ""
|
|
133
|
+
return out
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _items(app_id: str) -> dict[str, str]:
|
|
137
|
+
"""Name → id for every worksheet anywhere in the app, groups included."""
|
|
138
|
+
out: dict[str, str] = {}
|
|
139
|
+
|
|
140
|
+
def walk(sections):
|
|
141
|
+
for sec in sections or []:
|
|
142
|
+
for item in sec.get("items") or []:
|
|
143
|
+
if item.get("type", 0) == 0 and item.get("name"):
|
|
144
|
+
out[item["name"]] = item.get("id") or ""
|
|
145
|
+
walk(sec.get("childSections"))
|
|
146
|
+
|
|
147
|
+
walk(_app_tree(app_id).get("sections"))
|
|
148
|
+
return out
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _fields(ws_id: str) -> list[dict]:
|
|
152
|
+
data = hap(["worksheet", "fields", ws_id, "--raw"], check=False)
|
|
153
|
+
return data if isinstance(data, list) else []
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def _by_name(ws_id: str, name: str) -> str:
|
|
157
|
+
for c in _fields(ws_id):
|
|
158
|
+
if c.get("controlName") == name:
|
|
159
|
+
return c.get("controlId") or ""
|
|
160
|
+
return ""
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def _ensure_section(app_id: str, root_id: str, name: str) -> str:
|
|
164
|
+
have = _child_sections(app_id)
|
|
165
|
+
if name in have:
|
|
166
|
+
return have[name]
|
|
167
|
+
made = hap(["app", "add-section", app_id, "-n", name,
|
|
168
|
+
"--parent-id", root_id], check=False)
|
|
169
|
+
return made if isinstance(made, str) else ""
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def build(show_only: bool = False) -> dict:
|
|
173
|
+
app_id, org_id = state.ensure_app()
|
|
174
|
+
root_id = state.first_section_id(app_id)
|
|
175
|
+
data = _load()
|
|
176
|
+
data.update({"app_id": app_id, "org_id": org_id, "root_section": root_id})
|
|
177
|
+
if show_only:
|
|
178
|
+
print(json.dumps(data, ensure_ascii=False, indent=1))
|
|
179
|
+
return data
|
|
180
|
+
|
|
181
|
+
# ── the three second-level groups ────────────────────────────────
|
|
182
|
+
sections = {}
|
|
183
|
+
for name in (TEMPLATE_GROUP, TARGET_GROUP, HELPER_GROUP):
|
|
184
|
+
sections[name] = _ensure_section(app_id, root_id, name)
|
|
185
|
+
print(f" group {name}: {sections[name]}")
|
|
186
|
+
data["sections"] = sections
|
|
187
|
+
|
|
188
|
+
items = _items(app_id)
|
|
189
|
+
|
|
190
|
+
# ── the template table, then five copies of it ───────────────────
|
|
191
|
+
# Copies keep the source's controlIds — that is the product's own
|
|
192
|
+
# behaviour and the reason the report's author first suspected
|
|
193
|
+
# cross-sheet mis-references (report 3.10). The fixture keeps it.
|
|
194
|
+
template = TEMPLATE_SHEETS[0]
|
|
195
|
+
if template in items:
|
|
196
|
+
tpl_id = items[template]
|
|
197
|
+
else:
|
|
198
|
+
made = hap(["worksheet", "create", app_id, template,
|
|
199
|
+
"--section-id", sections[TEMPLATE_GROUP]], check=False)
|
|
200
|
+
tpl_id = (made.get("workSheetId") or made.get("id")
|
|
201
|
+
if isinstance(made, dict) else "") or ""
|
|
202
|
+
hap(["worksheet", "update-fields", tpl_id, "--title-name", "名称",
|
|
203
|
+
"--fields", json.dumps(STANDARD_FIELDS, ensure_ascii=False)],
|
|
204
|
+
check=False)
|
|
205
|
+
print(f" template {template}: {tpl_id}")
|
|
206
|
+
|
|
207
|
+
sheets = {template: tpl_id}
|
|
208
|
+
plan = [(n, sections[TEMPLATE_GROUP]) for n in TEMPLATE_SHEETS[1:]]
|
|
209
|
+
plan += [(n, sections[TARGET_GROUP]) for n in TARGET_SHEETS]
|
|
210
|
+
for name, sec in plan:
|
|
211
|
+
if name in items:
|
|
212
|
+
sheets[name] = items[name]
|
|
213
|
+
else:
|
|
214
|
+
made = hap(["worksheet", "copy", tpl_id, name, "-a", app_id,
|
|
215
|
+
"--section-id", sec], check=False)
|
|
216
|
+
sheets[name] = made if isinstance(made, str) else ""
|
|
217
|
+
print(f" sheet {name}: {sheets[name]}")
|
|
218
|
+
|
|
219
|
+
# ── the hidden detail sheet, mounted as a sub-table ──────────────
|
|
220
|
+
if DETAIL_SHEET in items:
|
|
221
|
+
detail_id = items[DETAIL_SHEET]
|
|
222
|
+
else:
|
|
223
|
+
made = hap(["worksheet", "create", app_id, DETAIL_SHEET,
|
|
224
|
+
"--section-id", sections[HELPER_GROUP]], check=False)
|
|
225
|
+
detail_id = (made.get("workSheetId") or made.get("id")
|
|
226
|
+
if isinstance(made, dict) else "") or ""
|
|
227
|
+
hap(["worksheet", "update-fields", detail_id,
|
|
228
|
+
"--title-name", "明细名称",
|
|
229
|
+
"--fields", json.dumps(DETAIL_FIELDS, ensure_ascii=False)],
|
|
230
|
+
check=False)
|
|
231
|
+
hap(["worksheet", "mount-subtable", tpl_id, detail_id,
|
|
232
|
+
"--name", "明细子表", "-a", app_id], check=False)
|
|
233
|
+
hap(["worksheet", "update", detail_id, "-a", app_id,
|
|
234
|
+
"--visibility", "hidden"], check=False)
|
|
235
|
+
sheets[DETAIL_SHEET] = detail_id
|
|
236
|
+
print(f" detail {DETAIL_SHEET}: {detail_id} (hidden)")
|
|
237
|
+
|
|
238
|
+
data["sheets"] = sheets
|
|
239
|
+
data["fields"] = {
|
|
240
|
+
name: {c.get("controlName"): c.get("controlId")
|
|
241
|
+
for c in _fields(wid) if c.get("controlName")}
|
|
242
|
+
for name, wid in sheets.items()
|
|
243
|
+
}
|
|
244
|
+
_save(data)
|
|
245
|
+
print(f"\nwrote {STATE_PATH}")
|
|
246
|
+
return data
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def main(argv: list[str] | None = None) -> int:
|
|
250
|
+
argv = list(sys.argv[1:] if argv is None else argv)
|
|
251
|
+
build(show_only="--show" in argv)
|
|
252
|
+
return 0
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
if __name__ == "__main__":
|
|
256
|
+
raise SystemExit(main())
|