hap-cli 0.5.0__py3-none-any.whl
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/README.md +194 -0
- hap_cli/README_CN.md +601 -0
- hap_cli/__init__.py +3 -0
- hap_cli/commands/__init__.py +1 -0
- hap_cli/commands/ai_cmd.py +224 -0
- hap_cli/commands/app_cmd.py +308 -0
- hap_cli/commands/calendar_cmd.py +138 -0
- hap_cli/commands/chat_cmd.py +101 -0
- hap_cli/commands/config_cmd.py +169 -0
- hap_cli/commands/contact_cmd.py +125 -0
- hap_cli/commands/department_cmd.py +168 -0
- hap_cli/commands/group_cmd.py +128 -0
- hap_cli/commands/instance_cmd.py +310 -0
- hap_cli/commands/node_cmd.py +538 -0
- hap_cli/commands/optionset_cmd.py +99 -0
- hap_cli/commands/page_cmd.py +102 -0
- hap_cli/commands/plugin_cmd.py +133 -0
- hap_cli/commands/post_cmd.py +155 -0
- hap_cli/commands/record_cmd.py +228 -0
- hap_cli/commands/role_cmd.py +221 -0
- hap_cli/commands/workflow_cmd.py +284 -0
- hap_cli/commands/worksheet_cmd.py +342 -0
- hap_cli/context.py +43 -0
- hap_cli/core/__init__.py +1 -0
- hap_cli/core/ai.py +133 -0
- hap_cli/core/app.py +307 -0
- hap_cli/core/auth.py +219 -0
- hap_cli/core/calendar_mod.py +114 -0
- hap_cli/core/chat.py +73 -0
- hap_cli/core/contact.py +85 -0
- hap_cli/core/department.py +131 -0
- hap_cli/core/flow_node.py +1001 -0
- hap_cli/core/group.py +99 -0
- hap_cli/core/instance.py +572 -0
- hap_cli/core/optionset.py +112 -0
- hap_cli/core/page.py +138 -0
- hap_cli/core/plugin.py +87 -0
- hap_cli/core/post.py +118 -0
- hap_cli/core/record.py +268 -0
- hap_cli/core/role.py +227 -0
- hap_cli/core/session.py +348 -0
- hap_cli/core/workflow.py +556 -0
- hap_cli/core/worksheet.py +403 -0
- hap_cli/hap_cli.py +105 -0
- hap_cli/skills/SKILL.md +383 -0
- hap_cli/skills/__init__.py +0 -0
- hap_cli/tests/__init__.py +1 -0
- hap_cli/tests/test_core.py +1824 -0
- hap_cli/tests/test_full_e2e.py +136 -0
- hap_cli/tests/test_integration.py +805 -0
- hap_cli/utils/__init__.py +1 -0
- hap_cli/utils/formatting.py +111 -0
- hap_cli/utils/options.py +10 -0
- hap_cli-0.5.0.dist-info/METADATA +223 -0
- hap_cli-0.5.0.dist-info/RECORD +58 -0
- hap_cli-0.5.0.dist-info/WHEEL +5 -0
- hap_cli-0.5.0.dist-info/entry_points.txt +2 -0
- hap_cli-0.5.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"""CLI commands for role management."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
|
|
7
|
+
from hap_cli.context import pass_context
|
|
8
|
+
from hap_cli.core import role as role_mod
|
|
9
|
+
from hap_cli.utils.formatting import output_json, output_kv, output_table
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@click.group()
|
|
13
|
+
def role():
|
|
14
|
+
"""Role management."""
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@role.command("list")
|
|
19
|
+
@click.argument("app_id", default="")
|
|
20
|
+
@pass_context
|
|
21
|
+
def role_list(ctx, app_id):
|
|
22
|
+
"""List roles for an application."""
|
|
23
|
+
try:
|
|
24
|
+
session = ctx.get_session()
|
|
25
|
+
aid = app_id or session.default_app_id
|
|
26
|
+
if not aid:
|
|
27
|
+
raise click.UsageError("App ID required.")
|
|
28
|
+
roles = role_mod.get_roles(session, aid)
|
|
29
|
+
ctx.output(
|
|
30
|
+
roles,
|
|
31
|
+
lambda d: output_table(
|
|
32
|
+
d,
|
|
33
|
+
["roleId", "name", "permissionWay", "description"],
|
|
34
|
+
["Role ID", "Name", "Permission", "Description"],
|
|
35
|
+
),
|
|
36
|
+
)
|
|
37
|
+
except Exception as e:
|
|
38
|
+
ctx.handle_error(e)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@role.command("create")
|
|
42
|
+
@click.argument("app_id")
|
|
43
|
+
@click.option("--name", "-n", required=True, help="Role name")
|
|
44
|
+
@click.option("--desc", "-d", default="", help="Description")
|
|
45
|
+
@click.option(
|
|
46
|
+
"--permission", "-p", default=10, type=int,
|
|
47
|
+
help="Permission type: 0=custom, 10=readonly, 50=member, 100=admin",
|
|
48
|
+
)
|
|
49
|
+
@pass_context
|
|
50
|
+
def role_create(ctx, app_id, name, desc, permission):
|
|
51
|
+
"""Create a new role."""
|
|
52
|
+
try:
|
|
53
|
+
session = ctx.get_session()
|
|
54
|
+
data = role_mod.create_role(session, app_id, name, desc, permission)
|
|
55
|
+
ctx.output(data, lambda d: click.echo(f"Created role: {d}"))
|
|
56
|
+
except Exception as e:
|
|
57
|
+
ctx.handle_error(e)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@role.command("delete")
|
|
61
|
+
@click.argument("app_id")
|
|
62
|
+
@click.argument("role_id")
|
|
63
|
+
@click.option("--move-to", "-m", default="", help="Move members to this role ID")
|
|
64
|
+
@click.option("--yes", "-y", is_flag=True, help="Skip confirmation")
|
|
65
|
+
@pass_context
|
|
66
|
+
def role_delete(ctx, app_id, role_id, move_to, yes):
|
|
67
|
+
"""Delete a role."""
|
|
68
|
+
try:
|
|
69
|
+
if not yes:
|
|
70
|
+
click.confirm(f"Delete role {role_id}?", abort=True)
|
|
71
|
+
session = ctx.get_session()
|
|
72
|
+
data = role_mod.delete_role(session, app_id, role_id, move_to)
|
|
73
|
+
ctx.output(data, lambda d: click.echo(f"Deleted role."))
|
|
74
|
+
except Exception as e:
|
|
75
|
+
ctx.handle_error(e)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@role.command("add-member")
|
|
79
|
+
@click.argument("app_id")
|
|
80
|
+
@click.argument("role_id")
|
|
81
|
+
@click.option("--user", "-u", multiple=True, help="User ID to add")
|
|
82
|
+
@click.option("--dept", "-d", multiple=True, help="Department ID to add")
|
|
83
|
+
@pass_context
|
|
84
|
+
def role_add_member(ctx, app_id, role_id, user, dept):
|
|
85
|
+
"""Add members to a role."""
|
|
86
|
+
try:
|
|
87
|
+
session = ctx.get_session()
|
|
88
|
+
data = role_mod.add_role_members(
|
|
89
|
+
session, app_id, role_id,
|
|
90
|
+
user_ids=list(user) if user else None,
|
|
91
|
+
department_ids=list(dept) if dept else None,
|
|
92
|
+
)
|
|
93
|
+
ctx.output(data, lambda d: click.echo("Members added."))
|
|
94
|
+
except Exception as e:
|
|
95
|
+
ctx.handle_error(e)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@role.command("remove-member")
|
|
99
|
+
@click.argument("app_id")
|
|
100
|
+
@click.argument("role_id")
|
|
101
|
+
@click.option("--user", "-u", multiple=True, help="User ID to remove")
|
|
102
|
+
@click.option("--dept", "-d", multiple=True, help="Department ID to remove")
|
|
103
|
+
@pass_context
|
|
104
|
+
def role_remove_member(ctx, app_id, role_id, user, dept):
|
|
105
|
+
"""Remove members from a role."""
|
|
106
|
+
try:
|
|
107
|
+
session = ctx.get_session()
|
|
108
|
+
data = role_mod.remove_role_members(
|
|
109
|
+
session, app_id, role_id,
|
|
110
|
+
user_ids=list(user) if user else None,
|
|
111
|
+
department_ids=list(dept) if dept else None,
|
|
112
|
+
)
|
|
113
|
+
ctx.output(data, lambda d: click.echo("Members removed."))
|
|
114
|
+
except Exception as e:
|
|
115
|
+
ctx.handle_error(e)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@role.command("permissions")
|
|
119
|
+
@click.argument("app_id")
|
|
120
|
+
@click.argument("role_id")
|
|
121
|
+
@pass_context
|
|
122
|
+
def role_permissions(ctx, app_id, role_id):
|
|
123
|
+
"""Get role detail including permissions."""
|
|
124
|
+
try:
|
|
125
|
+
session = ctx.get_session()
|
|
126
|
+
data = role_mod.get_role_detail(session, app_id, role_id)
|
|
127
|
+
ctx.output(data, lambda d: output_json(d))
|
|
128
|
+
except Exception as e:
|
|
129
|
+
ctx.handle_error(e)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@role.command("set-permissions")
|
|
133
|
+
@click.argument("app_id")
|
|
134
|
+
@click.argument("role_id")
|
|
135
|
+
@click.option("--permissions", "-P", default="", help="Permissions as JSON string")
|
|
136
|
+
@click.option("--permission-way", type=int, default=0, help="Permission type: 0=custom, 10=readonly, 50=member, 100=admin")
|
|
137
|
+
@pass_context
|
|
138
|
+
def role_set_permissions(ctx, app_id, role_id, permissions, permission_way):
|
|
139
|
+
"""Edit role permissions."""
|
|
140
|
+
try:
|
|
141
|
+
session = ctx.get_session()
|
|
142
|
+
perms = json.loads(permissions) if permissions else None
|
|
143
|
+
data = role_mod.edit_role(
|
|
144
|
+
session, app_id, role_id,
|
|
145
|
+
permission_way=permission_way, permissions=perms,
|
|
146
|
+
)
|
|
147
|
+
ctx.output(data, lambda d: click.echo("Permissions updated."))
|
|
148
|
+
except Exception as e:
|
|
149
|
+
ctx.handle_error(e)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@role.command("rename")
|
|
153
|
+
@click.argument("app_id")
|
|
154
|
+
@click.argument("role_id")
|
|
155
|
+
@click.option("--name", "-n", required=True, help="New role name")
|
|
156
|
+
@pass_context
|
|
157
|
+
def role_rename(ctx, app_id, role_id, name):
|
|
158
|
+
"""Rename a role."""
|
|
159
|
+
try:
|
|
160
|
+
session = ctx.get_session()
|
|
161
|
+
data = role_mod.rename_role(session, app_id, role_id, name)
|
|
162
|
+
ctx.output(data, lambda d: click.echo(f"Role renamed to: {name}"))
|
|
163
|
+
except Exception as e:
|
|
164
|
+
ctx.handle_error(e)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@role.command("apply")
|
|
168
|
+
@click.argument("app_id")
|
|
169
|
+
@click.argument("role_id")
|
|
170
|
+
@pass_context
|
|
171
|
+
def role_apply(ctx, app_id, role_id):
|
|
172
|
+
"""Apply to join a role."""
|
|
173
|
+
try:
|
|
174
|
+
session = ctx.get_session()
|
|
175
|
+
data = role_mod.apply_role(session, app_id, role_id)
|
|
176
|
+
ctx.output(data, lambda d: click.echo("Role application submitted."))
|
|
177
|
+
except Exception as e:
|
|
178
|
+
ctx.handle_error(e)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@role.command("approve")
|
|
182
|
+
@click.argument("app_id")
|
|
183
|
+
@click.argument("role_id")
|
|
184
|
+
@click.argument("account_id")
|
|
185
|
+
@pass_context
|
|
186
|
+
def role_approve(ctx, app_id, role_id, account_id):
|
|
187
|
+
"""Approve a user's role application."""
|
|
188
|
+
try:
|
|
189
|
+
session = ctx.get_session()
|
|
190
|
+
data = role_mod.approve_role_apply(session, app_id, role_id, account_id)
|
|
191
|
+
ctx.output(data, lambda d: click.echo("Application approved."))
|
|
192
|
+
except Exception as e:
|
|
193
|
+
ctx.handle_error(e)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
@role.command("reject")
|
|
197
|
+
@click.argument("app_id")
|
|
198
|
+
@click.argument("role_id")
|
|
199
|
+
@click.argument("account_id")
|
|
200
|
+
@pass_context
|
|
201
|
+
def role_reject(ctx, app_id, role_id, account_id):
|
|
202
|
+
"""Reject a user's role application."""
|
|
203
|
+
try:
|
|
204
|
+
session = ctx.get_session()
|
|
205
|
+
data = role_mod.reject_role_apply(session, app_id, role_id, account_id)
|
|
206
|
+
ctx.output(data, lambda d: click.echo("Application rejected."))
|
|
207
|
+
except Exception as e:
|
|
208
|
+
ctx.handle_error(e)
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@role.command("pending")
|
|
212
|
+
@click.argument("app_id")
|
|
213
|
+
@pass_context
|
|
214
|
+
def role_pending(ctx, app_id):
|
|
215
|
+
"""Get users with pending role applications."""
|
|
216
|
+
try:
|
|
217
|
+
session = ctx.get_session()
|
|
218
|
+
data = role_mod.get_pending_role_users(session, app_id)
|
|
219
|
+
ctx.output(data, lambda d: output_json(d))
|
|
220
|
+
except Exception as e:
|
|
221
|
+
ctx.handle_error(e)
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"""CLI commands for workflow process lifecycle management."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
|
|
7
|
+
from hap_cli.context import pass_context
|
|
8
|
+
from hap_cli.core import workflow as wf_mod
|
|
9
|
+
from hap_cli.utils.formatting import output_json, output_table, output_kv
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@click.group()
|
|
13
|
+
def workflow():
|
|
14
|
+
"""Workflow process lifecycle management."""
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@workflow.command("list")
|
|
19
|
+
@click.argument("app_id", default="")
|
|
20
|
+
@click.option("--keyword", "-k", default="", help="Search keyword")
|
|
21
|
+
@click.option("--enabled/--disabled", default=None, help="Filter by status")
|
|
22
|
+
@click.option("--page-size", "-n", default=50, help="Items per page")
|
|
23
|
+
@click.option("--page", "-p", default=1, help="Page number")
|
|
24
|
+
@pass_context
|
|
25
|
+
def workflow_list(ctx, app_id, keyword, enabled, page_size, page):
|
|
26
|
+
"""List workflows in an application."""
|
|
27
|
+
try:
|
|
28
|
+
session = ctx.get_session()
|
|
29
|
+
aid = app_id or session.default_app_id
|
|
30
|
+
if not aid:
|
|
31
|
+
raise click.UsageError("App ID required.")
|
|
32
|
+
result = wf_mod.get_process_list(
|
|
33
|
+
session, aid, keyword=keyword,
|
|
34
|
+
page_index=page, page_size=page_size,
|
|
35
|
+
)
|
|
36
|
+
ctx.output(
|
|
37
|
+
result,
|
|
38
|
+
lambda d: output_table(
|
|
39
|
+
d.get("data", []),
|
|
40
|
+
["id", "name", "enabled", "child"],
|
|
41
|
+
["Process ID", "Name", "Enabled", "Sub-processes"],
|
|
42
|
+
),
|
|
43
|
+
)
|
|
44
|
+
except Exception as e:
|
|
45
|
+
ctx.handle_error(e)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@workflow.command("get")
|
|
49
|
+
@click.argument("process_id")
|
|
50
|
+
@pass_context
|
|
51
|
+
def workflow_get(ctx, process_id):
|
|
52
|
+
"""Get workflow process details."""
|
|
53
|
+
try:
|
|
54
|
+
session = ctx.get_session()
|
|
55
|
+
data = wf_mod.get_process_by_id(session, process_id)
|
|
56
|
+
ctx.output(data, lambda d: output_kv(d))
|
|
57
|
+
except Exception as e:
|
|
58
|
+
ctx.handle_error(e)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@workflow.command("create")
|
|
62
|
+
@click.option("--company-id", "-c", required=True, help="Organization/project ID")
|
|
63
|
+
@click.option("--name", "-n", required=True, help="Process name")
|
|
64
|
+
@click.option("--app-id", "-a", default="", help="Related app ID")
|
|
65
|
+
@click.option("--type", "start_type", default=1, type=int,
|
|
66
|
+
help="Trigger type: 1=worksheet, 5=scheduled, 6=date")
|
|
67
|
+
@click.option("--desc", "-d", default="", help="Description")
|
|
68
|
+
@pass_context
|
|
69
|
+
def workflow_create(ctx, company_id, name, app_id, start_type, desc):
|
|
70
|
+
"""Create a new workflow process."""
|
|
71
|
+
try:
|
|
72
|
+
session = ctx.get_session()
|
|
73
|
+
data = wf_mod.create_process(
|
|
74
|
+
session, company_id, name,
|
|
75
|
+
relation_id=app_id,
|
|
76
|
+
start_event_app_type=start_type,
|
|
77
|
+
explain=desc,
|
|
78
|
+
)
|
|
79
|
+
ctx.output(data, lambda d: click.echo(f"Created workflow: {d}"))
|
|
80
|
+
except Exception as e:
|
|
81
|
+
ctx.handle_error(e)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@workflow.command("update")
|
|
85
|
+
@click.argument("process_id")
|
|
86
|
+
@click.option("--name", "-n", default="", help="New name")
|
|
87
|
+
@click.option("--desc", "-d", default="", help="New description")
|
|
88
|
+
@click.option("--icon-color", default="", help="Icon color hex")
|
|
89
|
+
@pass_context
|
|
90
|
+
def workflow_update(ctx, process_id, name, desc, icon_color):
|
|
91
|
+
"""Update workflow process info."""
|
|
92
|
+
try:
|
|
93
|
+
session = ctx.get_session()
|
|
94
|
+
data = wf_mod.update_process(
|
|
95
|
+
session, process_id, name=name, explain=desc, icon_color=icon_color,
|
|
96
|
+
)
|
|
97
|
+
ctx.output(data, lambda d: click.echo("Workflow updated."))
|
|
98
|
+
except Exception as e:
|
|
99
|
+
ctx.handle_error(e)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@workflow.command("delete")
|
|
103
|
+
@click.argument("process_id")
|
|
104
|
+
@click.option("--yes", "-y", is_flag=True, help="Skip confirmation")
|
|
105
|
+
@pass_context
|
|
106
|
+
def workflow_delete(ctx, process_id, yes):
|
|
107
|
+
"""Delete a workflow process."""
|
|
108
|
+
try:
|
|
109
|
+
if not yes:
|
|
110
|
+
click.confirm(f"Delete workflow {process_id}?", abort=True)
|
|
111
|
+
session = ctx.get_session()
|
|
112
|
+
data = wf_mod.delete_process(session, process_id)
|
|
113
|
+
ctx.output(data, lambda d: click.echo("Workflow deleted."))
|
|
114
|
+
except Exception as e:
|
|
115
|
+
ctx.handle_error(e)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@workflow.command("copy")
|
|
119
|
+
@click.argument("process_id")
|
|
120
|
+
@click.option("--name", "-n", required=True, help="Name for the copy")
|
|
121
|
+
@click.option("--sub-process", is_flag=True, help="Include sub-processes")
|
|
122
|
+
@pass_context
|
|
123
|
+
def workflow_copy(ctx, process_id, name, sub_process):
|
|
124
|
+
"""Copy/clone a workflow process."""
|
|
125
|
+
try:
|
|
126
|
+
session = ctx.get_session()
|
|
127
|
+
data = wf_mod.copy_process(session, process_id, name, sub_process)
|
|
128
|
+
ctx.output(data, lambda d: click.echo(f"Copied: {d}"))
|
|
129
|
+
except Exception as e:
|
|
130
|
+
ctx.handle_error(e)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@workflow.command("move")
|
|
134
|
+
@click.argument("process_id")
|
|
135
|
+
@click.argument("target_app_id")
|
|
136
|
+
@pass_context
|
|
137
|
+
def workflow_move(ctx, process_id, target_app_id):
|
|
138
|
+
"""Move workflow to another application."""
|
|
139
|
+
try:
|
|
140
|
+
session = ctx.get_session()
|
|
141
|
+
data = wf_mod.move_process(session, process_id, target_app_id)
|
|
142
|
+
ctx.output(data, lambda d: click.echo("Workflow moved."))
|
|
143
|
+
except Exception as e:
|
|
144
|
+
ctx.handle_error(e)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@workflow.command("publish")
|
|
148
|
+
@click.argument("process_id")
|
|
149
|
+
@click.option("--disable", is_flag=True, help="Disable instead of publish")
|
|
150
|
+
@pass_context
|
|
151
|
+
def workflow_publish(ctx, process_id, disable):
|
|
152
|
+
"""Publish (enable) or disable a workflow."""
|
|
153
|
+
try:
|
|
154
|
+
session = ctx.get_session()
|
|
155
|
+
data = wf_mod.publish(session, process_id, is_publish=not disable)
|
|
156
|
+
action = "Disabled" if disable else "Published"
|
|
157
|
+
ctx.output(data, lambda d: click.echo(f"{action} workflow."))
|
|
158
|
+
except Exception as e:
|
|
159
|
+
ctx.handle_error(e)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
@workflow.command("rollback")
|
|
163
|
+
@click.argument("process_id")
|
|
164
|
+
@click.option("--yes", "-y", is_flag=True, help="Skip confirmation")
|
|
165
|
+
@pass_context
|
|
166
|
+
def workflow_rollback(ctx, process_id, yes):
|
|
167
|
+
"""Rollback to previous version."""
|
|
168
|
+
try:
|
|
169
|
+
if not yes:
|
|
170
|
+
click.confirm(f"Rollback workflow {process_id}?", abort=True)
|
|
171
|
+
session = ctx.get_session()
|
|
172
|
+
data = wf_mod.rollback_version(session, process_id)
|
|
173
|
+
ctx.output(data, lambda d: click.echo("Rolled back to previous version."))
|
|
174
|
+
except Exception as e:
|
|
175
|
+
ctx.handle_error(e)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@workflow.command("history")
|
|
179
|
+
@click.argument("process_id")
|
|
180
|
+
@click.option("--page-size", "-n", default=20, help="Items per page")
|
|
181
|
+
@click.option("--page", "-p", default=1, help="Page number")
|
|
182
|
+
@pass_context
|
|
183
|
+
def workflow_history(ctx, process_id, page_size, page):
|
|
184
|
+
"""Get workflow version history."""
|
|
185
|
+
try:
|
|
186
|
+
session = ctx.get_session()
|
|
187
|
+
data = wf_mod.get_version_history(session, process_id, page, page_size)
|
|
188
|
+
ctx.output(data, lambda d: output_json(d))
|
|
189
|
+
except Exception as e:
|
|
190
|
+
ctx.handle_error(e)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@workflow.command("config-get")
|
|
194
|
+
@click.argument("process_id")
|
|
195
|
+
@pass_context
|
|
196
|
+
def workflow_config_get(ctx, process_id):
|
|
197
|
+
"""Get workflow global configuration."""
|
|
198
|
+
try:
|
|
199
|
+
session = ctx.get_session()
|
|
200
|
+
data = wf_mod.get_process_config(session, process_id)
|
|
201
|
+
ctx.output(data, lambda d: output_json(d))
|
|
202
|
+
except Exception as e:
|
|
203
|
+
ctx.handle_error(e)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
@workflow.command("config-set")
|
|
207
|
+
@click.argument("process_id")
|
|
208
|
+
@click.option("--config", "-c", required=True, help="JSON config string")
|
|
209
|
+
@pass_context
|
|
210
|
+
def workflow_config_set(ctx, process_id, config):
|
|
211
|
+
"""Save workflow global configuration (JSON string)."""
|
|
212
|
+
try:
|
|
213
|
+
session = ctx.get_session()
|
|
214
|
+
config_dict = json.loads(config)
|
|
215
|
+
data = wf_mod.save_process_config(session, process_id, config_dict)
|
|
216
|
+
ctx.output(data, lambda d: click.echo("Config saved."))
|
|
217
|
+
except json.JSONDecodeError as e:
|
|
218
|
+
ctx.handle_error(click.UsageError(f"Invalid JSON: {e}"))
|
|
219
|
+
except Exception as e:
|
|
220
|
+
ctx.handle_error(e)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
@workflow.command("trigger")
|
|
224
|
+
@click.argument("process_id")
|
|
225
|
+
@click.option("--source-id", "-s", default="", help="Source record ID")
|
|
226
|
+
@pass_context
|
|
227
|
+
def workflow_trigger(ctx, process_id, source_id):
|
|
228
|
+
"""Trigger/start a workflow by process ID."""
|
|
229
|
+
try:
|
|
230
|
+
session = ctx.get_session()
|
|
231
|
+
data = wf_mod.start_process_by_id(session, process_id, source_id)
|
|
232
|
+
ctx.output(data, lambda d: click.echo(f"Triggered: {d}"))
|
|
233
|
+
except Exception as e:
|
|
234
|
+
ctx.handle_error(e)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
@workflow.command("trigger-pbp")
|
|
238
|
+
@click.argument("process_id")
|
|
239
|
+
@click.option("--app-id", "-a", required=True, help="Application ID")
|
|
240
|
+
@click.option("--trigger-id", default="", help="Trigger ID")
|
|
241
|
+
@click.option("--title", default="", help="Instance title")
|
|
242
|
+
@pass_context
|
|
243
|
+
def workflow_trigger_pbp(ctx, process_id, app_id, trigger_id, title):
|
|
244
|
+
"""Trigger a PBP (Packaged Business Process) workflow."""
|
|
245
|
+
try:
|
|
246
|
+
session = ctx.get_session()
|
|
247
|
+
data = wf_mod.start_process_by_pbp(
|
|
248
|
+
session, process_id, app_id, trigger_id, title,
|
|
249
|
+
)
|
|
250
|
+
ctx.output(data, lambda d: click.echo(f"PBP triggered: {d}"))
|
|
251
|
+
except Exception as e:
|
|
252
|
+
ctx.handle_error(e)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
@workflow.command("groups")
|
|
256
|
+
@click.argument("app_id", default="")
|
|
257
|
+
@pass_context
|
|
258
|
+
def workflow_groups(ctx, app_id):
|
|
259
|
+
"""List workflow groups."""
|
|
260
|
+
try:
|
|
261
|
+
session = ctx.get_session()
|
|
262
|
+
aid = app_id or session.default_app_id
|
|
263
|
+
if not aid:
|
|
264
|
+
raise click.UsageError("App ID required.")
|
|
265
|
+
data = wf_mod.get_group_list(session, aid)
|
|
266
|
+
ctx.output(
|
|
267
|
+
data,
|
|
268
|
+
lambda d: output_table(d, ["id", "name"], ["Group ID", "Name"]),
|
|
269
|
+
)
|
|
270
|
+
except Exception as e:
|
|
271
|
+
ctx.handle_error(e)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
@workflow.command("stats")
|
|
275
|
+
@click.option("--company-id", "-c", required=True, help="Organization ID")
|
|
276
|
+
@pass_context
|
|
277
|
+
def workflow_stats(ctx, company_id):
|
|
278
|
+
"""Get workflow usage statistics."""
|
|
279
|
+
try:
|
|
280
|
+
session = ctx.get_session()
|
|
281
|
+
data = wf_mod.get_process_use_count(session, company_id)
|
|
282
|
+
ctx.output(data, lambda d: output_kv(d))
|
|
283
|
+
except Exception as e:
|
|
284
|
+
ctx.handle_error(e)
|